xfs_inode_item.c 22.3 KB
Newer Older
D
Dave Chinner 已提交
1
// SPDX-License-Identifier: GPL-2.0
L
Linus Torvalds 已提交
2
/*
3 4
 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
 * All Rights Reserved.
L
Linus Torvalds 已提交
5 6
 */
#include "xfs.h"
7
#include "xfs_fs.h"
8
#include "xfs_shared.h"
9
#include "xfs_format.h"
10 11
#include "xfs_log_format.h"
#include "xfs_trans_resv.h"
L
Linus Torvalds 已提交
12 13
#include "xfs_mount.h"
#include "xfs_inode.h"
14
#include "xfs_trans.h"
15
#include "xfs_inode_item.h"
C
Christoph Hellwig 已提交
16
#include "xfs_trace.h"
17
#include "xfs_trans_priv.h"
18
#include "xfs_buf_item.h"
C
Christoph Hellwig 已提交
19
#include "xfs_log.h"
20
#include "xfs_error.h"
L
Linus Torvalds 已提交
21

J
Jeff Layton 已提交
22
#include <linux/iversion.h>
L
Linus Torvalds 已提交
23 24 25

kmem_zone_t	*xfs_ili_zone;		/* inode log item zone */

26 27 28 29 30
static inline struct xfs_inode_log_item *INODE_ITEM(struct xfs_log_item *lip)
{
	return container_of(lip, struct xfs_inode_log_item, ili_item);
}

31
STATIC void
32 33
xfs_inode_item_data_fork_size(
	struct xfs_inode_log_item *iip,
34 35
	int			*nvecs,
	int			*nbytes)
L
Linus Torvalds 已提交
36
{
37
	struct xfs_inode	*ip = iip->ili_inode;
38

39
	switch (ip->i_df.if_format) {
L
Linus Torvalds 已提交
40
	case XFS_DINODE_FMT_EXTENTS:
41
		if ((iip->ili_fields & XFS_ILOG_DEXT) &&
42
		    ip->i_df.if_nextents > 0 &&
43 44 45 46 47
		    ip->i_df.if_bytes > 0) {
			/* worst case, doesn't subtract delalloc extents */
			*nbytes += XFS_IFORK_DSIZE(ip);
			*nvecs += 1;
		}
L
Linus Torvalds 已提交
48 49
		break;
	case XFS_DINODE_FMT_BTREE:
50
		if ((iip->ili_fields & XFS_ILOG_DBROOT) &&
51 52 53 54
		    ip->i_df.if_broot_bytes > 0) {
			*nbytes += ip->i_df.if_broot_bytes;
			*nvecs += 1;
		}
L
Linus Torvalds 已提交
55 56
		break;
	case XFS_DINODE_FMT_LOCAL:
57
		if ((iip->ili_fields & XFS_ILOG_DDATA) &&
58 59 60 61
		    ip->i_df.if_bytes > 0) {
			*nbytes += roundup(ip->i_df.if_bytes, 4);
			*nvecs += 1;
		}
L
Linus Torvalds 已提交
62 63 64 65 66 67 68 69
		break;

	case XFS_DINODE_FMT_DEV:
		break;
	default:
		ASSERT(0);
		break;
	}
70
}
L
Linus Torvalds 已提交
71

72 73 74 75 76 77 78
STATIC void
xfs_inode_item_attr_fork_size(
	struct xfs_inode_log_item *iip,
	int			*nvecs,
	int			*nbytes)
{
	struct xfs_inode	*ip = iip->ili_inode;
L
Linus Torvalds 已提交
79

80
	switch (ip->i_afp->if_format) {
L
Linus Torvalds 已提交
81
	case XFS_DINODE_FMT_EXTENTS:
82
		if ((iip->ili_fields & XFS_ILOG_AEXT) &&
83
		    ip->i_afp->if_nextents > 0 &&
84 85 86 87 88
		    ip->i_afp->if_bytes > 0) {
			/* worst case, doesn't subtract unused space */
			*nbytes += XFS_IFORK_ASIZE(ip);
			*nvecs += 1;
		}
L
Linus Torvalds 已提交
89 90
		break;
	case XFS_DINODE_FMT_BTREE:
91
		if ((iip->ili_fields & XFS_ILOG_ABROOT) &&
92 93 94 95
		    ip->i_afp->if_broot_bytes > 0) {
			*nbytes += ip->i_afp->if_broot_bytes;
			*nvecs += 1;
		}
L
Linus Torvalds 已提交
96 97
		break;
	case XFS_DINODE_FMT_LOCAL:
98
		if ((iip->ili_fields & XFS_ILOG_ADATA) &&
99 100 101 102
		    ip->i_afp->if_bytes > 0) {
			*nbytes += roundup(ip->i_afp->if_bytes, 4);
			*nvecs += 1;
		}
L
Linus Torvalds 已提交
103 104 105 106 107 108 109
		break;
	default:
		ASSERT(0);
		break;
	}
}

110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
/*
 * This returns the number of iovecs needed to log the given inode item.
 *
 * We need one iovec for the inode log format structure, one for the
 * inode core, and possibly one for the inode data/extents/b-tree root
 * and one for the inode attribute data/extents/b-tree root.
 */
STATIC void
xfs_inode_item_size(
	struct xfs_log_item	*lip,
	int			*nvecs,
	int			*nbytes)
{
	struct xfs_inode_log_item *iip = INODE_ITEM(lip);
	struct xfs_inode	*ip = iip->ili_inode;

	*nvecs += 2;
	*nbytes += sizeof(struct xfs_inode_log_format) +
128
		   xfs_log_dinode_size(ip->i_mount);
129 130 131 132 133 134

	xfs_inode_item_data_fork_size(iip, nvecs, nbytes);
	if (XFS_IFORK_Q(ip))
		xfs_inode_item_attr_fork_size(iip, nvecs, nbytes);
}

C
Christoph Hellwig 已提交
135
STATIC void
136 137
xfs_inode_item_format_data_fork(
	struct xfs_inode_log_item *iip,
138 139 140
	struct xfs_inode_log_format *ilf,
	struct xfs_log_vec	*lv,
	struct xfs_log_iovec	**vecp)
L
Linus Torvalds 已提交
141
{
142
	struct xfs_inode	*ip = iip->ili_inode;
L
Linus Torvalds 已提交
143 144
	size_t			data_bytes;

145
	switch (ip->i_df.if_format) {
L
Linus Torvalds 已提交
146
	case XFS_DINODE_FMT_EXTENTS:
147
		iip->ili_fields &=
148
			~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | XFS_ILOG_DEV);
149

150
		if ((iip->ili_fields & XFS_ILOG_DEXT) &&
151
		    ip->i_df.if_nextents > 0 &&
152
		    ip->i_df.if_bytes > 0) {
153 154
			struct xfs_bmbt_rec *p;

155
			ASSERT(xfs_iext_count(&ip->i_df) > 0);
156 157 158 159 160 161 162 163

			p = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_IEXT);
			data_bytes = xfs_iextents_copy(ip, p, XFS_DATA_FORK);
			xlog_finish_iovec(lv, *vecp, data_bytes);

			ASSERT(data_bytes <= ip->i_df.if_bytes);

			ilf->ilf_dsize = data_bytes;
164
			ilf->ilf_size++;
165
		} else {
166
			iip->ili_fields &= ~XFS_ILOG_DEXT;
L
Linus Torvalds 已提交
167 168 169
		}
		break;
	case XFS_DINODE_FMT_BTREE:
170
		iip->ili_fields &=
171
			~(XFS_ILOG_DDATA | XFS_ILOG_DEXT | XFS_ILOG_DEV);
172

173
		if ((iip->ili_fields & XFS_ILOG_DBROOT) &&
174
		    ip->i_df.if_broot_bytes > 0) {
L
Linus Torvalds 已提交
175
			ASSERT(ip->i_df.if_broot != NULL);
176
			xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IBROOT,
C
Christoph Hellwig 已提交
177 178
					ip->i_df.if_broot,
					ip->i_df.if_broot_bytes);
179 180
			ilf->ilf_dsize = ip->i_df.if_broot_bytes;
			ilf->ilf_size++;
181
		} else {
182
			ASSERT(!(iip->ili_fields &
183
				 XFS_ILOG_DBROOT));
184
			iip->ili_fields &= ~XFS_ILOG_DBROOT;
L
Linus Torvalds 已提交
185 186 187
		}
		break;
	case XFS_DINODE_FMT_LOCAL:
188
		iip->ili_fields &=
189
			~(XFS_ILOG_DEXT | XFS_ILOG_DBROOT | XFS_ILOG_DEV);
190
		if ((iip->ili_fields & XFS_ILOG_DDATA) &&
191
		    ip->i_df.if_bytes > 0) {
L
Linus Torvalds 已提交
192 193 194 195 196 197
			/*
			 * Round i_bytes up to a word boundary.
			 * The underlying memory is guaranteed to
			 * to be there by xfs_idata_realloc().
			 */
			data_bytes = roundup(ip->i_df.if_bytes, 4);
C
Christoph Hellwig 已提交
198 199
			ASSERT(ip->i_df.if_u1.if_data != NULL);
			ASSERT(ip->i_d.di_size > 0);
200
			xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_ILOCAL,
C
Christoph Hellwig 已提交
201
					ip->i_df.if_u1.if_data, data_bytes);
202 203
			ilf->ilf_dsize = (unsigned)data_bytes;
			ilf->ilf_size++;
204
		} else {
205
			iip->ili_fields &= ~XFS_ILOG_DDATA;
L
Linus Torvalds 已提交
206 207 208
		}
		break;
	case XFS_DINODE_FMT_DEV:
209
		iip->ili_fields &=
210
			~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | XFS_ILOG_DEXT);
211
		if (iip->ili_fields & XFS_ILOG_DEV)
C
Christoph Hellwig 已提交
212
			ilf->ilf_u.ilfu_rdev = sysv_encode_dev(VFS_I(ip)->i_rdev);
L
Linus Torvalds 已提交
213 214 215 216 217
		break;
	default:
		ASSERT(0);
		break;
	}
218 219
}

C
Christoph Hellwig 已提交
220
STATIC void
221 222
xfs_inode_item_format_attr_fork(
	struct xfs_inode_log_item *iip,
223 224 225
	struct xfs_inode_log_format *ilf,
	struct xfs_log_vec	*lv,
	struct xfs_log_iovec	**vecp)
226 227 228
{
	struct xfs_inode	*ip = iip->ili_inode;
	size_t			data_bytes;
L
Linus Torvalds 已提交
229

230
	switch (ip->i_afp->if_format) {
L
Linus Torvalds 已提交
231
	case XFS_DINODE_FMT_EXTENTS:
232
		iip->ili_fields &=
233 234
			~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT);

235
		if ((iip->ili_fields & XFS_ILOG_AEXT) &&
236
		    ip->i_afp->if_nextents > 0 &&
237
		    ip->i_afp->if_bytes > 0) {
238 239
			struct xfs_bmbt_rec *p;

240
			ASSERT(xfs_iext_count(ip->i_afp) ==
241
				ip->i_afp->if_nextents);
242 243 244 245 246 247

			p = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_EXT);
			data_bytes = xfs_iextents_copy(ip, p, XFS_ATTR_FORK);
			xlog_finish_iovec(lv, *vecp, data_bytes);

			ilf->ilf_asize = data_bytes;
248
			ilf->ilf_size++;
249
		} else {
250
			iip->ili_fields &= ~XFS_ILOG_AEXT;
L
Linus Torvalds 已提交
251 252 253
		}
		break;
	case XFS_DINODE_FMT_BTREE:
254
		iip->ili_fields &=
255 256
			~(XFS_ILOG_ADATA | XFS_ILOG_AEXT);

257
		if ((iip->ili_fields & XFS_ILOG_ABROOT) &&
258
		    ip->i_afp->if_broot_bytes > 0) {
L
Linus Torvalds 已提交
259
			ASSERT(ip->i_afp->if_broot != NULL);
260

261
			xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_BROOT,
C
Christoph Hellwig 已提交
262 263
					ip->i_afp->if_broot,
					ip->i_afp->if_broot_bytes);
264 265
			ilf->ilf_asize = ip->i_afp->if_broot_bytes;
			ilf->ilf_size++;
266
		} else {
267
			iip->ili_fields &= ~XFS_ILOG_ABROOT;
L
Linus Torvalds 已提交
268 269 270
		}
		break;
	case XFS_DINODE_FMT_LOCAL:
271
		iip->ili_fields &=
272 273
			~(XFS_ILOG_AEXT | XFS_ILOG_ABROOT);

274
		if ((iip->ili_fields & XFS_ILOG_ADATA) &&
275
		    ip->i_afp->if_bytes > 0) {
L
Linus Torvalds 已提交
276 277 278 279 280 281
			/*
			 * Round i_bytes up to a word boundary.
			 * The underlying memory is guaranteed to
			 * to be there by xfs_idata_realloc().
			 */
			data_bytes = roundup(ip->i_afp->if_bytes, 4);
C
Christoph Hellwig 已提交
282
			ASSERT(ip->i_afp->if_u1.if_data != NULL);
283
			xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_LOCAL,
C
Christoph Hellwig 已提交
284 285
					ip->i_afp->if_u1.if_data,
					data_bytes);
286 287
			ilf->ilf_asize = (unsigned)data_bytes;
			ilf->ilf_size++;
288
		} else {
289
			iip->ili_fields &= ~XFS_ILOG_ADATA;
L
Linus Torvalds 已提交
290 291 292 293 294 295
		}
		break;
	default:
		ASSERT(0);
		break;
	}
296 297
}

298
static void
299 300
xfs_inode_to_log_dinode(
	struct xfs_inode	*ip,
301 302
	struct xfs_log_dinode	*to,
	xfs_lsn_t		lsn)
303
{
304 305 306
	struct xfs_icdinode	*from = &ip->i_d;
	struct inode		*inode = VFS_I(ip);

307
	to->di_magic = XFS_DINODE_MAGIC;
308
	to->di_format = xfs_ifork_format(&ip->i_df);
309 310
	to->di_uid = i_uid_read(inode);
	to->di_gid = i_gid_read(inode);
311 312
	to->di_projid_lo = from->di_projid & 0xffff;
	to->di_projid_hi = from->di_projid >> 16;
313

314
	memset(to->di_pad, 0, sizeof(to->di_pad));
315
	memset(to->di_pad3, 0, sizeof(to->di_pad3));
316 317 318 319 320 321
	to->di_atime.t_sec = inode->i_atime.tv_sec;
	to->di_atime.t_nsec = inode->i_atime.tv_nsec;
	to->di_mtime.t_sec = inode->i_mtime.tv_sec;
	to->di_mtime.t_nsec = inode->i_mtime.tv_nsec;
	to->di_ctime.t_sec = inode->i_ctime.tv_sec;
	to->di_ctime.t_nsec = inode->i_ctime.tv_nsec;
322
	to->di_nlink = inode->i_nlink;
323
	to->di_gen = inode->i_generation;
D
Dave Chinner 已提交
324
	to->di_mode = inode->i_mode;
325 326 327 328

	to->di_size = from->di_size;
	to->di_nblocks = from->di_nblocks;
	to->di_extsize = from->di_extsize;
329 330
	to->di_nextents = xfs_ifork_nextents(&ip->i_df);
	to->di_anextents = xfs_ifork_nextents(ip->i_afp);
331
	to->di_forkoff = from->di_forkoff;
332
	to->di_aformat = xfs_ifork_format(ip->i_afp);
333 334 335 336
	to->di_dmevmask = from->di_dmevmask;
	to->di_dmstate = from->di_dmstate;
	to->di_flags = from->di_flags;

337 338 339
	/* log a dummy value to ensure log structure is fully initialised */
	to->di_next_unlinked = NULLAGINO;

340 341
	if (xfs_sb_version_has_v3inode(&ip->i_mount->m_sb)) {
		to->di_version = 3;
J
Jeff Layton 已提交
342
		to->di_changecount = inode_peek_iversion(inode);
343 344
		to->di_crtime.t_sec = from->di_crtime.tv_sec;
		to->di_crtime.t_nsec = from->di_crtime.tv_nsec;
345
		to->di_flags2 = from->di_flags2;
346
		to->di_cowextsize = from->di_cowextsize;
347 348 349 350
		to->di_ino = ip->i_ino;
		to->di_lsn = lsn;
		memset(to->di_pad2, 0, sizeof(to->di_pad2));
		uuid_copy(&to->di_uuid, &ip->i_mount->m_sb.sb_meta_uuid);
351 352
		to->di_flushiter = 0;
	} else {
353
		to->di_version = 2;
354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371
		to->di_flushiter = from->di_flushiter;
	}
}

/*
 * Format the inode core. Current timestamp data is only in the VFS inode
 * fields, so we need to grab them from there. Hence rather than just copying
 * the XFS inode core structure, format the fields directly into the iovec.
 */
static void
xfs_inode_item_format_core(
	struct xfs_inode	*ip,
	struct xfs_log_vec	*lv,
	struct xfs_log_iovec	**vecp)
{
	struct xfs_log_dinode	*dic;

	dic = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_ICORE);
372
	xfs_inode_to_log_dinode(ip, dic, ip->i_itemp->ili_item.li_lsn);
373
	xlog_finish_iovec(lv, *vecp, xfs_log_dinode_size(ip->i_mount));
374 375
}

376 377 378 379 380 381
/*
 * This is called to fill in the vector of log iovecs for the given inode
 * log item.  It fills the first item with an inode log format structure,
 * the second with the on-disk inode structure, and a possible third and/or
 * fourth with the inode data/extents/b-tree root and inode attributes
 * data/extents/b-tree root.
382 383 384 385 386
 *
 * Note: Always use the 64 bit inode log format structure so we don't
 * leave an uninitialised hole in the format item on 64 bit systems. Log
 * recovery on 32 bit systems handles this just fine, so there's no reason
 * for not using an initialising the properly padded structure all the time.
387 388 389 390
 */
STATIC void
xfs_inode_item_format(
	struct xfs_log_item	*lip,
391
	struct xfs_log_vec	*lv)
392 393 394
{
	struct xfs_inode_log_item *iip = INODE_ITEM(lip);
	struct xfs_inode	*ip = iip->ili_inode;
395
	struct xfs_log_iovec	*vecp = NULL;
396
	struct xfs_inode_log_format *ilf;
397

398 399 400 401 402 403 404 405
	ilf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_IFORMAT);
	ilf->ilf_type = XFS_LI_INODE;
	ilf->ilf_ino = ip->i_ino;
	ilf->ilf_blkno = ip->i_imap.im_blkno;
	ilf->ilf_len = ip->i_imap.im_len;
	ilf->ilf_boffset = ip->i_imap.im_boffset;
	ilf->ilf_fields = XFS_ILOG_CORE;
	ilf->ilf_size = 2; /* format + core */
406 407 408 409 410 411 412 413

	/*
	 * make sure we don't leak uninitialised data into the log in the case
	 * when we don't log every field in the inode.
	 */
	ilf->ilf_dsize = 0;
	ilf->ilf_asize = 0;
	ilf->ilf_pad = 0;
414
	memset(&ilf->ilf_u, 0, sizeof(ilf->ilf_u));
415 416

	xlog_finish_iovec(lv, vecp, sizeof(*ilf));
417

418
	xfs_inode_item_format_core(ip, lv, &vecp);
419
	xfs_inode_item_format_data_fork(iip, ilf, lv, &vecp);
420
	if (XFS_IFORK_Q(ip)) {
421
		xfs_inode_item_format_attr_fork(iip, ilf, lv, &vecp);
422 423 424 425 426
	} else {
		iip->ili_fields &=
			~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT);
	}

427 428
	/* update the format with the exact fields we actually logged */
	ilf->ilf_fields |= (iip->ili_fields & ~XFS_ILOG_TIMESTAMP);
L
Linus Torvalds 已提交
429 430 431 432
}

/*
 * This is called to pin the inode associated with the inode log
433
 * item in memory so it cannot be written out.
L
Linus Torvalds 已提交
434 435 436
 */
STATIC void
xfs_inode_item_pin(
437
	struct xfs_log_item	*lip)
L
Linus Torvalds 已提交
438
{
439
	struct xfs_inode	*ip = INODE_ITEM(lip)->ili_inode;
440

441
	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
442
	ASSERT(lip->li_buf);
443 444 445

	trace_xfs_inode_pin(ip, _RET_IP_);
	atomic_inc(&ip->i_pincount);
L
Linus Torvalds 已提交
446 447 448 449 450 451
}


/*
 * This is called to unpin the inode associated with the inode log
 * item which was previously pinned with a call to xfs_inode_item_pin().
452 453
 *
 * Also wake up anyone in xfs_iunpin_wait() if the count goes to 0.
454 455 456 457 458 459
 *
 * Note that unpin can race with inode cluster buffer freeing marking the buffer
 * stale. In that case, flush completions are run from the buffer unpin call,
 * which may happen before the inode is unpinned. If we lose the race, there
 * will be no buffer attached to the log item, but the inode will be marked
 * XFS_ISTALE.
L
Linus Torvalds 已提交
460 461 462
 */
STATIC void
xfs_inode_item_unpin(
463
	struct xfs_log_item	*lip,
464
	int			remove)
L
Linus Torvalds 已提交
465
{
466
	struct xfs_inode	*ip = INODE_ITEM(lip)->ili_inode;
467

468
	trace_xfs_inode_unpin(ip, _RET_IP_);
469
	ASSERT(lip->li_buf || xfs_iflags_test(ip, XFS_ISTALE));
470 471
	ASSERT(atomic_read(&ip->i_pincount) > 0);
	if (atomic_dec_and_test(&ip->i_pincount))
472
		wake_up_bit(&ip->i_flags, __XFS_IPINNED_BIT);
L
Linus Torvalds 已提交
473 474 475
}

STATIC uint
476 477 478
xfs_inode_item_push(
	struct xfs_log_item	*lip,
	struct list_head	*buffer_list)
479 480
		__releases(&lip->li_ailp->ail_lock)
		__acquires(&lip->li_ailp->ail_lock)
L
Linus Torvalds 已提交
481
{
482 483
	struct xfs_inode_log_item *iip = INODE_ITEM(lip);
	struct xfs_inode	*ip = iip->ili_inode;
484
	struct xfs_buf		*bp = lip->li_buf;
485 486
	uint			rval = XFS_ITEM_SUCCESS;
	int			error;
L
Linus Torvalds 已提交
487

488 489 490 491
	ASSERT(iip->ili_item.li_buf);

	if (xfs_ipincount(ip) > 0 || xfs_buf_ispinned(bp) ||
	    (ip->i_flags & XFS_ISTALE))
L
Linus Torvalds 已提交
492 493
		return XFS_ITEM_PINNED;

494 495 496
	/* If the inode is already flush locked, we're already flushing. */
	if (xfs_isiflocked(ip))
		return XFS_ITEM_FLUSHING;
L
Linus Torvalds 已提交
497

498 499
	if (!xfs_buf_trylock(bp))
		return XFS_ITEM_LOCKED;
500

501
	spin_unlock(&lip->li_ailp->ail_lock);
502

503
	/*
504 505 506 507
	 * We need to hold a reference for flushing the cluster buffer as it may
	 * fail the buffer without IO submission. In which case, we better get a
	 * reference for that completion because otherwise we don't get a
	 * reference for IO until we queue the buffer for delwri submission.
508
	 */
509
	xfs_buf_hold(bp);
510
	error = xfs_iflush_cluster(bp);
511 512 513 514
	if (!error) {
		if (!xfs_buf_delwri_queue(bp, buffer_list))
			rval = XFS_ITEM_FLUSHING;
		xfs_buf_relse(bp);
515
	} else {
516 517 518 519 520 521
		/*
		 * Release the buffer if we were unable to flush anything. On
		 * any other error, the buffer has already been released.
		 */
		if (error == -EAGAIN)
			xfs_buf_relse(bp);
522
		rval = XFS_ITEM_LOCKED;
523
	}
524

525
	spin_lock(&lip->li_ailp->ail_lock);
526
	return rval;
L
Linus Torvalds 已提交
527 528 529 530 531 532
}

/*
 * Unlock the inode associated with the inode log item.
 */
STATIC void
C
Christoph Hellwig 已提交
533
xfs_inode_item_release(
534
	struct xfs_log_item	*lip)
L
Linus Torvalds 已提交
535
{
536 537
	struct xfs_inode_log_item *iip = INODE_ITEM(lip);
	struct xfs_inode	*ip = iip->ili_inode;
538
	unsigned short		lock_flags;
L
Linus Torvalds 已提交
539

C
Christoph Hellwig 已提交
540 541
	ASSERT(ip->i_itemp != NULL);
	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
L
Linus Torvalds 已提交
542

543 544
	lock_flags = iip->ili_lock_flags;
	iip->ili_lock_flags = 0;
545
	if (lock_flags)
C
Christoph Hellwig 已提交
546
		xfs_iunlock(ip, lock_flags);
L
Linus Torvalds 已提交
547 548 549
}

/*
550 551 552 553 554 555 556 557 558 559 560
 * This is called to find out where the oldest active copy of the inode log
 * item in the on disk log resides now that the last log write of it completed
 * at the given lsn.  Since we always re-log all dirty data in an inode, the
 * latest copy in the on disk log is the only one that matters.  Therefore,
 * simply return the given lsn.
 *
 * If the inode has been marked stale because the cluster is being freed, we
 * don't want to (re-)insert this inode into the AIL. There is a race condition
 * where the cluster buffer may be unpinned before the inode is inserted into
 * the AIL during transaction committed processing. If the buffer is unpinned
 * before the inode item has been committed and inserted, then it is possible
561
 * for the buffer to be written and IO completes before the inode is inserted
562 563 564 565 566
 * into the AIL. In that case, we'd be inserting a clean, stale inode into the
 * AIL which will never get removed. It will, however, get reclaimed which
 * triggers an assert in xfs_inode_free() complaining about freein an inode
 * still in the AIL.
 *
567 568 569
 * To avoid this, just unpin the inode directly and return a LSN of -1 so the
 * transaction committed code knows that it does not need to do any further
 * processing on the item.
L
Linus Torvalds 已提交
570 571 572
 */
STATIC xfs_lsn_t
xfs_inode_item_committed(
573
	struct xfs_log_item	*lip,
L
Linus Torvalds 已提交
574 575
	xfs_lsn_t		lsn)
{
576 577 578
	struct xfs_inode_log_item *iip = INODE_ITEM(lip);
	struct xfs_inode	*ip = iip->ili_inode;

579 580 581 582
	if (xfs_iflags_test(ip, XFS_ISTALE)) {
		xfs_inode_item_unpin(lip, 0);
		return -1;
	}
583
	return lsn;
L
Linus Torvalds 已提交
584 585 586 587
}

STATIC void
xfs_inode_item_committing(
588
	struct xfs_log_item	*lip,
C
Christoph Hellwig 已提交
589
	xfs_lsn_t		commit_lsn)
L
Linus Torvalds 已提交
590
{
C
Christoph Hellwig 已提交
591 592
	INODE_ITEM(lip)->ili_last_lsn = commit_lsn;
	return xfs_inode_item_release(lip);
L
Linus Torvalds 已提交
593 594
}

C
Christoph Hellwig 已提交
595
static const struct xfs_item_ops xfs_inode_item_ops = {
596 597 598 599
	.iop_size	= xfs_inode_item_size,
	.iop_format	= xfs_inode_item_format,
	.iop_pin	= xfs_inode_item_pin,
	.iop_unpin	= xfs_inode_item_unpin,
C
Christoph Hellwig 已提交
600
	.iop_release	= xfs_inode_item_release,
601 602
	.iop_committed	= xfs_inode_item_committed,
	.iop_push	= xfs_inode_item_push,
C
Christoph Hellwig 已提交
603
	.iop_committing	= xfs_inode_item_committing,
L
Linus Torvalds 已提交
604 605 606 607 608 609 610 611
};


/*
 * Initialize the inode log item for a newly allocated (in-core) inode.
 */
void
xfs_inode_item_init(
612 613
	struct xfs_inode	*ip,
	struct xfs_mount	*mp)
L
Linus Torvalds 已提交
614
{
615
	struct xfs_inode_log_item *iip;
L
Linus Torvalds 已提交
616 617

	ASSERT(ip->i_itemp == NULL);
618 619
	iip = ip->i_itemp = kmem_cache_zalloc(xfs_ili_zone,
					      GFP_KERNEL | __GFP_NOFAIL);
L
Linus Torvalds 已提交
620 621

	iip->ili_inode = ip;
D
Dave Chinner 已提交
622
	spin_lock_init(&iip->ili_lock);
623 624
	xfs_log_item_init(mp, &iip->ili_item, XFS_LI_INODE,
						&xfs_inode_item_ops);
L
Linus Torvalds 已提交
625 626 627 628 629 630 631
}

/*
 * Free the inode log item and any memory hanging off of it.
 */
void
xfs_inode_item_destroy(
632
	struct xfs_inode	*ip)
L
Linus Torvalds 已提交
633
{
634 635 636 637 638 639 640
	struct xfs_inode_log_item *iip = ip->i_itemp;

	ASSERT(iip->ili_item.li_buf == NULL);

	ip->i_itemp = NULL;
	kmem_free(iip->ili_item.li_lv_shadow);
	kmem_cache_free(xfs_ili_zone, iip);
L
Linus Torvalds 已提交
641 642 643 644
}


/*
D
Dave Chinner 已提交
645 646 647
 * We only want to pull the item from the AIL if it is actually there
 * and its location in the log has not changed since we started the
 * flush.  Thus, we only bother if the inode's lsn has not changed.
L
Linus Torvalds 已提交
648
 */
D
Dave Chinner 已提交
649 650 651 652
static void
xfs_iflush_ail_updates(
	struct xfs_ail		*ailp,
	struct list_head	*list)
L
Linus Torvalds 已提交
653
{
D
Dave Chinner 已提交
654 655
	struct xfs_log_item	*lip;
	xfs_lsn_t		tail_lsn = 0;
656

D
Dave Chinner 已提交
657 658 659 660
	/* this is an opencoded batch version of xfs_trans_ail_delete */
	spin_lock(&ailp->ail_lock);
	list_for_each_entry(lip, list, li_bio_list) {
		xfs_lsn_t	lsn;
661

D
Dave Chinner 已提交
662 663
		clear_bit(XFS_LI_FAILED, &lip->li_flags);
		if (INODE_ITEM(lip)->ili_flush_lsn != lip->li_lsn)
664 665
			continue;

D
Dave Chinner 已提交
666 667 668
		lsn = xfs_ail_delete_one(ailp, lip);
		if (!tail_lsn && lsn)
			tail_lsn = lsn;
669
	}
D
Dave Chinner 已提交
670 671
	xfs_ail_update_finish(ailp, tail_lsn);
}
L
Linus Torvalds 已提交
672

D
Dave Chinner 已提交
673 674 675 676 677 678 679 680 681 682 683 684
/*
 * Walk the list of inodes that have completed their IOs. If they are clean
 * remove them from the list and dissociate them from the buffer. Buffers that
 * are still dirty remain linked to the buffer and on the list. Caller must
 * handle them appropriately.
 */
static void
xfs_iflush_finish(
	struct xfs_buf		*bp,
	struct list_head	*list)
{
	struct xfs_log_item	*lip, *n;
L
Linus Torvalds 已提交
685

D
Dave Chinner 已提交
686 687
	list_for_each_entry_safe(lip, n, list, li_bio_list) {
		struct xfs_inode_log_item *iip = INODE_ITEM(lip);
688 689
		bool	drop_buffer = false;

D
Dave Chinner 已提交
690
		spin_lock(&iip->ili_lock);
691 692 693

		/*
		 * Remove the reference to the cluster buffer if the inode is
D
Dave Chinner 已提交
694 695
		 * clean in memory and drop the buffer reference once we've
		 * dropped the locks we hold.
696 697 698 699
		 */
		ASSERT(iip->ili_item.li_buf == bp);
		if (!iip->ili_fields) {
			iip->ili_item.li_buf = NULL;
D
Dave Chinner 已提交
700
			list_del_init(&lip->li_bio_list);
701 702
			drop_buffer = true;
		}
703
		iip->ili_last_fields = 0;
704
		iip->ili_flush_lsn = 0;
D
Dave Chinner 已提交
705
		spin_unlock(&iip->ili_lock);
706
		xfs_ifunlock(iip->ili_inode);
707 708
		if (drop_buffer)
			xfs_buf_rele(bp);
709
	}
L
Linus Torvalds 已提交
710 711
}

D
Dave Chinner 已提交
712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756
/*
 * Inode buffer IO completion routine.  It is responsible for removing inodes
 * attached to the buffer from the AIL if they have not been re-logged, as well
 * as completing the flush and unlocking the inode.
 */
void
xfs_iflush_done(
	struct xfs_buf		*bp)
{
	struct xfs_log_item	*lip, *n;
	LIST_HEAD(flushed_inodes);
	LIST_HEAD(ail_updates);

	/*
	 * Pull the attached inodes from the buffer one at a time and take the
	 * appropriate action on them.
	 */
	list_for_each_entry_safe(lip, n, &bp->b_li_list, li_bio_list) {
		struct xfs_inode_log_item *iip = INODE_ITEM(lip);

		if (xfs_iflags_test(iip->ili_inode, XFS_ISTALE)) {
			xfs_iflush_abort(iip->ili_inode);
			continue;
		}
		if (!iip->ili_last_fields)
			continue;

		/* Do an unlocked check for needing the AIL lock. */
		if (iip->ili_flush_lsn == lip->li_lsn ||
		    test_bit(XFS_LI_FAILED, &lip->li_flags))
			list_move_tail(&lip->li_bio_list, &ail_updates);
		else
			list_move_tail(&lip->li_bio_list, &flushed_inodes);
	}

	if (!list_empty(&ail_updates)) {
		xfs_iflush_ail_updates(bp->b_mount->m_ail, &ail_updates);
		list_splice_tail(&ail_updates, &flushed_inodes);
	}

	xfs_iflush_finish(bp, &flushed_inodes);
	if (!list_empty(&flushed_inodes))
		list_splice_tail(&flushed_inodes, &bp->b_li_list);
}

L
Linus Torvalds 已提交
757
/*
758 759 760 761
 * This is the inode flushing abort routine.  It is called from xfs_iflush when
 * the filesystem is shutting down to clean up the inode state.  It is
 * responsible for removing the inode item from the AIL if it has not been
 * re-logged, and unlocking the inode's flush lock.
L
Linus Torvalds 已提交
762 763 764
 */
void
xfs_iflush_abort(
765
	struct xfs_inode	*ip)
L
Linus Torvalds 已提交
766
{
767 768
	struct xfs_inode_log_item *iip = ip->i_itemp;
	struct xfs_buf		*bp = NULL;
L
Linus Torvalds 已提交
769 770

	if (iip) {
771 772 773 774 775 776
		/*
		 * Clear the failed bit before removing the item from the AIL so
		 * xfs_trans_ail_delete() doesn't try to clear and release the
		 * buffer attached to the log item before we are done with it.
		 */
		clear_bit(XFS_LI_FAILED, &iip->ili_item.li_flags);
777
		xfs_trans_ail_delete(&iip->ili_item, 0);
778

L
Linus Torvalds 已提交
779 780 781 782
		/*
		 * Clear the inode logging fields so no more flushes are
		 * attempted.
		 */
D
Dave Chinner 已提交
783
		spin_lock(&iip->ili_lock);
784
		iip->ili_last_fields = 0;
785
		iip->ili_fields = 0;
786
		iip->ili_fsync_fields = 0;
787 788 789
		iip->ili_flush_lsn = 0;
		bp = iip->ili_item.li_buf;
		iip->ili_item.li_buf = NULL;
790
		list_del_init(&iip->ili_item.li_bio_list);
D
Dave Chinner 已提交
791
		spin_unlock(&iip->ili_lock);
L
Linus Torvalds 已提交
792 793
	}
	xfs_ifunlock(ip);
794 795
	if (bp)
		xfs_buf_rele(bp);
L
Linus Torvalds 已提交
796 797
}

798
/*
799 800
 * convert an xfs_inode_log_format struct from the old 32 bit version
 * (which can have different field alignments) to the native 64 bit version
801 802 803
 */
int
xfs_inode_item_format_convert(
804 805
	struct xfs_log_iovec		*buf,
	struct xfs_inode_log_format	*in_f)
806
{
807 808
	struct xfs_inode_log_format_32	*in_f32 = buf->i_addr;

809 810
	if (buf->i_len != sizeof(*in_f32)) {
		XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL);
811
		return -EFSCORRUPTED;
812
	}
813 814 815 816 817 818 819

	in_f->ilf_type = in_f32->ilf_type;
	in_f->ilf_size = in_f32->ilf_size;
	in_f->ilf_fields = in_f32->ilf_fields;
	in_f->ilf_asize = in_f32->ilf_asize;
	in_f->ilf_dsize = in_f32->ilf_dsize;
	in_f->ilf_ino = in_f32->ilf_ino;
820
	memcpy(&in_f->ilf_u, &in_f32->ilf_u, sizeof(in_f->ilf_u));
821 822 823 824
	in_f->ilf_blkno = in_f32->ilf_blkno;
	in_f->ilf_len = in_f32->ilf_len;
	in_f->ilf_boffset = in_f32->ilf_boffset;
	return 0;
825
}