diff options
| author | Christoph Hellwig <hch@infradead.org> | 2010-06-24 11:36:58 +1000 | 
|---|---|---|
| committer | Alex Elder <aelder@sgi.com> | 2010-07-26 13:16:36 -0500 | 
| commit | 898621d5a72c6799a9a13fce20443b4b6699899c (patch) | |
| tree | 6cd994bd8d24f4f4f6ac5b5b57e0b99ee02d4ba6 /fs/xfs | |
| parent | 4d16e9246fc3b3cf7bc95609eff66929a39daa06 (diff) | |
| download | olio-linux-3.10-898621d5a72c6799a9a13fce20443b4b6699899c.tar.xz olio-linux-3.10-898621d5a72c6799a9a13fce20443b4b6699899c.zip  | |
xfs: simplify inode to transaction joining
Currently we need to either call IHOLD or xfs_trans_ihold on an inode when
joining it to a transaction via xfs_trans_ijoin.
This patches instead makes xfs_trans_ijoin usable on it's own by doing
an implicity xfs_trans_ihold, which also allows us to drop the third
argument.  For the case where we want to hold a reference on the inode
a xfs_trans_ijoin_ref wrapper is added which does the IHOLD and marks
the inode for needing an xfs_iput.  In addition to the cleaner interface
to the caller this also simplifies the implementation.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Diffstat (limited to 'fs/xfs')
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_file.c | 3 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_ioctl.c | 3 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 3 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.c | 3 | ||||
| -rw-r--r-- | fs/xfs/quota/xfs_dquot.c | 9 | ||||
| -rw-r--r-- | fs/xfs/xfs_attr.c | 75 | ||||
| -rw-r--r-- | fs/xfs/xfs_bmap.c | 5 | ||||
| -rw-r--r-- | fs/xfs/xfs_dfrag.c | 7 | ||||
| -rw-r--r-- | fs/xfs/xfs_fsops.c | 3 | ||||
| -rw-r--r-- | fs/xfs/xfs_inode.c | 14 | ||||
| -rw-r--r-- | fs/xfs/xfs_inode_item.c | 42 | ||||
| -rw-r--r-- | fs/xfs/xfs_inode_item.h | 8 | ||||
| -rw-r--r-- | fs/xfs/xfs_iomap.c | 9 | ||||
| -rw-r--r-- | fs/xfs/xfs_rename.c | 26 | ||||
| -rw-r--r-- | fs/xfs/xfs_trans.c | 3 | ||||
| -rw-r--r-- | fs/xfs/xfs_trans.h | 4 | ||||
| -rw-r--r-- | fs/xfs/xfs_trans_inode.c | 60 | ||||
| -rw-r--r-- | fs/xfs/xfs_utils.c | 4 | ||||
| -rw-r--r-- | fs/xfs/xfs_vnodeops.c | 69 | 
19 files changed, 103 insertions, 247 deletions
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 8d26d93648b..9a9b446a58a 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c @@ -158,8 +158,7 @@ xfs_file_fsync(  		 * transaction.	 So we play it safe and fire off the  		 * transaction anyway.  		 */ -		xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); -		xfs_trans_ihold(tp, ip); +		xfs_trans_ijoin(tp, ip);  		xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);  		xfs_trans_set_sync(tp);  		error = _xfs_trans_commit(tp, 0, &log_flushed); diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index 8aa54f0eec1..a12dddad126 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c @@ -1034,8 +1034,7 @@ xfs_ioctl_setattr(  		}  	} -	xfs_trans_ijoin(tp, ip, lock_flags); -	xfs_trans_ihold(tp, ip); +	xfs_trans_ijoin(tp, ip);  	/*  	 * Change file ownership.  Must be the owner or privileged. diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 4b90e4b531b..b8ad17e730b 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -1023,8 +1023,7 @@ xfs_log_inode(  	 * an inode in another recent transaction.  So we play it safe and  	 * fire off the transaction anyway.  	 */ -	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); -	xfs_trans_ihold(tp, ip); +	xfs_trans_ijoin(tp, ip);  	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);  	xfs_trans_set_sync(tp);  	error = xfs_trans_commit(tp, 0); diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index 850b4198bf6..0283b88bc16 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c @@ -362,8 +362,7 @@ xfs_commit_dummy_trans(  	xfs_ilock(ip, XFS_ILOCK_EXCL); -	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); -	xfs_trans_ihold(tp, ip); +	xfs_trans_ijoin(tp, ip);  	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);  	error = xfs_trans_commit(tp, 0);  	xfs_iunlock(ip, XFS_ILOCK_EXCL); diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index 6526e87cade..56f366e327f 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c @@ -378,14 +378,7 @@ xfs_qm_dqalloc(  		return (ESRCH);  	} -	/* -	 * xfs_trans_commit normally decrements the vnode ref count -	 * when it unlocks the inode. Since we want to keep the quota -	 * inode around, we bump the vnode ref count now. -	 */ -	IHOLD(quotip); - -	xfs_trans_ijoin(tp, quotip, XFS_ILOCK_EXCL); +	xfs_trans_ijoin_ref(tp, quotip, XFS_ILOCK_EXCL);  	nmaps = 1;  	if ((error = xfs_bmapi(tp, quotip,  			      offset_fsb, XFS_DQUOT_CLUSTER_SIZE_FSB, diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index 8bde79785a7..f3ca7186155 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c @@ -319,8 +319,7 @@ xfs_attr_set_int(  		return (error);  	} -	xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL); -	xfs_trans_ihold(args.trans, dp); +	xfs_trans_ijoin(args.trans, dp);  	/*  	 * If the attribute list is non-existent or a shortform list, @@ -390,10 +389,8 @@ xfs_attr_set_int(  		 * bmap_finish() may have committed the last trans and started  		 * a new one.  We need the inode to be in all transactions.  		 */ -		if (committed) { -			xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL); -			xfs_trans_ihold(args.trans, dp); -		} +		if (committed) +			xfs_trans_ijoin(args.trans, dp);  		/*  		 * Commit the leaf transformation.  We'll need another (linked) @@ -538,8 +535,7 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags)  	 * No need to make quota reservations here. We expect to release some  	 * blocks not allocate in the common case.  	 */ -	xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL); -	xfs_trans_ihold(args.trans, dp); +	xfs_trans_ijoin(args.trans, dp);  	/*  	 * Decide on what work routines to call based on the inode size. @@ -815,8 +811,7 @@ xfs_attr_inactive(xfs_inode_t *dp)  	 * No need to make quota reservations here. We expect to release some  	 * blocks, not allocate, in the common case.  	 */ -	xfs_trans_ijoin(trans, dp, XFS_ILOCK_EXCL); -	xfs_trans_ihold(trans, dp); +	xfs_trans_ijoin(trans, dp);  	/*  	 * Decide on what work routines to call based on the inode size. @@ -975,10 +970,8 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)  		 * bmap_finish() may have committed the last trans and started  		 * a new one.  We need the inode to be in all transactions.  		 */ -		if (committed) { -			xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); -			xfs_trans_ihold(args->trans, dp); -		} +		if (committed) +			xfs_trans_ijoin(args->trans, dp);  		/*  		 * Commit the current trans (including the inode) and start @@ -1079,10 +1072,8 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)  			 * and started a new one.  We need the inode to be  			 * in all transactions.  			 */ -			if (committed) { -				xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); -				xfs_trans_ihold(args->trans, dp); -			} +			if (committed) +				xfs_trans_ijoin(args->trans, dp);  		} else  			xfs_da_buf_done(bp); @@ -1155,10 +1146,8 @@ xfs_attr_leaf_removename(xfs_da_args_t *args)  		 * bmap_finish() may have committed the last trans and started  		 * a new one.  We need the inode to be in all transactions.  		 */ -		if (committed) { -			xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); -			xfs_trans_ihold(args->trans, dp); -		} +		if (committed) +			xfs_trans_ijoin(args->trans, dp);  	} else  		xfs_da_buf_done(bp);  	return(0); @@ -1311,10 +1300,8 @@ restart:  			 * and started a new one.  We need the inode to be  			 * in all transactions.  			 */ -			if (committed) { -				xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); -				xfs_trans_ihold(args->trans, dp); -			} +			if (committed) +				xfs_trans_ijoin(args->trans, dp);  			/*  			 * Commit the node conversion and start the next @@ -1350,10 +1337,8 @@ restart:  		 * bmap_finish() may have committed the last trans and started  		 * a new one.  We need the inode to be in all transactions.  		 */ -		if (committed) { -			xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); -			xfs_trans_ihold(args->trans, dp); -		} +		if (committed) +			xfs_trans_ijoin(args->trans, dp);  	} else {  		/*  		 * Addition succeeded, update Btree hashvals. @@ -1464,10 +1449,8 @@ restart:  			 * and started a new one.  We need the inode to be  			 * in all transactions.  			 */ -			if (committed) { -				xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); -				xfs_trans_ihold(args->trans, dp); -			} +			if (committed) +				xfs_trans_ijoin(args->trans, dp);  		}  		/* @@ -1598,10 +1581,8 @@ xfs_attr_node_removename(xfs_da_args_t *args)  		 * bmap_finish() may have committed the last trans and started  		 * a new one.  We need the inode to be in all transactions.  		 */ -		if (committed) { -			xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); -			xfs_trans_ihold(args->trans, dp); -		} +		if (committed) +			xfs_trans_ijoin(args->trans, dp);  		/*  		 * Commit the Btree join operation and start a new trans. @@ -1652,10 +1633,8 @@ xfs_attr_node_removename(xfs_da_args_t *args)  			 * and started a new one.  We need the inode to be  			 * in all transactions.  			 */ -			if (committed) { -				xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); -				xfs_trans_ihold(args->trans, dp); -			} +			if (committed) +				xfs_trans_ijoin(args->trans, dp);  		} else  			xfs_da_brelse(args->trans, bp);  	} @@ -2093,10 +2072,8 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)  		 * bmap_finish() may have committed the last trans and started  		 * a new one.  We need the inode to be in all transactions.  		 */ -		if (committed) { -			xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL); -			xfs_trans_ihold(args->trans, dp); -		} +		if (committed) +			xfs_trans_ijoin(args->trans, dp);  		ASSERT(nmap == 1);  		ASSERT((map.br_startblock != DELAYSTARTBLOCK) && @@ -2249,10 +2226,8 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)  		 * bmap_finish() may have committed the last trans and started  		 * a new one.  We need the inode to be in all transactions.  		 */ -		if (committed) { -			xfs_trans_ijoin(args->trans, args->dp, XFS_ILOCK_EXCL); -			xfs_trans_ihold(args->trans, args->dp); -		} +		if (committed) +			xfs_trans_ijoin(args->trans, args->dp);  		/*  		 * Close out trans and start the next one in the chain. diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index ff8675b4197..e0389656ad2 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -3751,9 +3751,10 @@ xfs_bmap_add_attrfork(  		ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;  	}  	ASSERT(ip->i_d.di_anextents == 0); -	IHOLD(ip); -	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); + +	xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL);  	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); +  	switch (ip->i_d.di_format) {  	case XFS_DINODE_FMT_DEV:  		ip->i_d.di_forkoff = roundup(sizeof(xfs_dev_t), 8) >> 3; diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index 7b11dc0494c..3b9582c60a2 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c @@ -416,11 +416,8 @@ xfs_swap_extents(  	} -	IHOLD(ip); -	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); - -	IHOLD(tip); -	xfs_trans_ijoin(tp, tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); +	xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); +	xfs_trans_ijoin_ref(tp, tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);  	xfs_trans_log_inode(tp, ip,  ilf_fields);  	xfs_trans_log_inode(tp, tip, tilf_fields); diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index ade96922fc8..dbca5f5c37b 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -622,8 +622,7 @@ xfs_fs_log_dummy(  	ip = mp->m_rootip;  	xfs_ilock(ip, XFS_ILOCK_EXCL); -	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); -	xfs_trans_ihold(tp, ip); +	xfs_trans_ijoin(tp, ip);  	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);  	xfs_trans_set_sync(tp);  	error = xfs_trans_commit(tp, 0); diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index c7c48da97ad..d22b580162c 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1456,7 +1456,7 @@ xfs_itruncate_finish(  	ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES);  	ASSERT(ip->i_transp == *tp);  	ASSERT(ip->i_itemp != NULL); -	ASSERT(ip->i_itemp->ili_flags & XFS_ILI_HOLD); +	ASSERT(ip->i_itemp->ili_lock_flags == 0);  	ntp = *tp; @@ -1608,12 +1608,8 @@ xfs_itruncate_finish(  		 */  		error = xfs_bmap_finish(tp, &free_list, &committed);  		ntp = *tp; -		if (committed) { -			/* link the inode into the next xact in the chain */ -			xfs_trans_ijoin(ntp, ip, -					XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); -			xfs_trans_ihold(ntp, ip); -		} +		if (committed) +			xfs_trans_ijoin(ntp, ip);  		if (error) {  			/* @@ -1642,9 +1638,7 @@ xfs_itruncate_finish(  		error = xfs_trans_commit(*tp, 0);  		*tp = ntp; -		/* link the inode into the next transaction in the chain */ -		xfs_trans_ijoin(ntp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); -		xfs_trans_ihold(ntp, ip); +		xfs_trans_ijoin(ntp, ip);  		if (error)  			return error; diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index c7e70d70834..ad050c618e6 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -628,19 +628,10 @@ xfs_inode_item_unlock(  {  	struct xfs_inode_log_item *iip = INODE_ITEM(lip);  	struct xfs_inode	*ip = iip->ili_inode; -	uint			hold; -	uint			iolocked; -	uint			lock_flags; +	unsigned short		lock_flags; -	ASSERT(iip != NULL);  	ASSERT(iip->ili_inode->i_itemp != NULL);  	ASSERT(xfs_isilocked(iip->ili_inode, XFS_ILOCK_EXCL)); -	ASSERT((!(iip->ili_inode->i_itemp->ili_flags & -		  XFS_ILI_IOLOCKED_EXCL)) || -	       xfs_isilocked(iip->ili_inode, XFS_IOLOCK_EXCL)); -	ASSERT((!(iip->ili_inode->i_itemp->ili_flags & -		  XFS_ILI_IOLOCKED_SHARED)) || -	       xfs_isilocked(iip->ili_inode, XFS_IOLOCK_SHARED));  	/*  	 * Clear the transaction pointer in the inode. @@ -668,35 +659,10 @@ xfs_inode_item_unlock(  		iip->ili_aextents_buf = NULL;  	} -	/* -	 * Figure out if we should unlock the inode or not. -	 */ -	hold = iip->ili_flags & XFS_ILI_HOLD; - -	/* -	 * Before clearing out the flags, remember whether we -	 * are holding the inode's IO lock. -	 */ -	iolocked = iip->ili_flags & XFS_ILI_IOLOCKED_ANY; - -	/* -	 * Clear out the fields of the inode log item particular -	 * to the current transaction. -	 */ -	iip->ili_flags = 0; - -	/* -	 * Unlock the inode if XFS_ILI_HOLD was not set. -	 */ -	if (!hold) { -		lock_flags = XFS_ILOCK_EXCL; -		if (iolocked & XFS_ILI_IOLOCKED_EXCL) { -			lock_flags |= XFS_IOLOCK_EXCL; -		} else if (iolocked & XFS_ILI_IOLOCKED_SHARED) { -			lock_flags |= XFS_IOLOCK_SHARED; -		} +	lock_flags = iip->ili_lock_flags; +	iip->ili_lock_flags = 0; +	if (lock_flags)  		xfs_iput(iip->ili_inode, lock_flags); -	}  }  /* diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h index b6a97ff1c3a..d3dee61e6d9 100644 --- a/fs/xfs/xfs_inode_item.h +++ b/fs/xfs/xfs_inode_item.h @@ -103,12 +103,6 @@ typedef struct xfs_inode_log_format_64 {  				 XFS_ILOG_ADATA | XFS_ILOG_AEXT | \  				 XFS_ILOG_ABROOT) -#define	XFS_ILI_HOLD		0x1 -#define	XFS_ILI_IOLOCKED_EXCL	0x2 -#define	XFS_ILI_IOLOCKED_SHARED	0x4 - -#define	XFS_ILI_IOLOCKED_ANY   (XFS_ILI_IOLOCKED_EXCL | XFS_ILI_IOLOCKED_SHARED) -  static inline int xfs_ilog_fbroot(int w)  {  	return (w == XFS_DATA_FORK ? XFS_ILOG_DBROOT : XFS_ILOG_ABROOT); @@ -137,7 +131,7 @@ typedef struct xfs_inode_log_item {  	struct xfs_inode	*ili_inode;	   /* inode ptr */  	xfs_lsn_t		ili_flush_lsn;	   /* lsn at last flush */  	xfs_lsn_t		ili_last_lsn;	   /* lsn at last transaction */ -	unsigned short		ili_flags;	   /* misc flags */ +	unsigned short		ili_lock_flags;	   /* lock flags */  	unsigned short		ili_logged;	   /* flushed logged data */  	unsigned int		ili_last_fields;   /* fields when flushed */  	struct xfs_bmbt_rec	*ili_extents_buf;  /* array of logged diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 772f3e791eb..aeac00294a1 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -329,8 +329,7 @@ xfs_iomap_write_direct(  	if (error)  		goto error1; -	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); -	xfs_trans_ihold(tp, ip); +	xfs_trans_ijoin(tp, ip);  	bmapi_flag = XFS_BMAPI_WRITE;  	if ((flags & BMAPI_DIRECT) && (offset < ip->i_size || extsz)) @@ -597,8 +596,7 @@ xfs_iomap_write_allocate(  				return XFS_ERROR(error);  			}  			xfs_ilock(ip, XFS_ILOCK_EXCL); -			xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); -			xfs_trans_ihold(tp, ip); +			xfs_trans_ijoin(tp, ip);  			xfs_bmap_init(&free_list, &first_block); @@ -761,8 +759,7 @@ xfs_iomap_write_unwritten(  		}  		xfs_ilock(ip, XFS_ILOCK_EXCL); -		xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); -		xfs_trans_ihold(tp, ip); +		xfs_trans_ijoin(tp, ip);  		/*  		 * Modify the unwritten extent state of the buffer. diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c index 8edb1074847..778c87a8ebf 100644 --- a/fs/xfs/xfs_rename.c +++ b/fs/xfs/xfs_rename.c @@ -169,26 +169,14 @@ xfs_rename(  	/*  	 * Join all the inodes to the transaction. From this point on,  	 * we can rely on either trans_commit or trans_cancel to unlock -	 * them.  Note that we need to add a vnode reference to the -	 * directories since trans_commit & trans_cancel will decrement -	 * them when they unlock the inodes.  Also, we need to be careful -	 * not to add an inode to the transaction more than once. +	 * them.  	 */ -	IHOLD(src_dp); -	xfs_trans_ijoin(tp, src_dp, XFS_ILOCK_EXCL); - -	if (new_parent) { -		IHOLD(target_dp); -		xfs_trans_ijoin(tp, target_dp, XFS_ILOCK_EXCL); -	} - -	IHOLD(src_ip); -	xfs_trans_ijoin(tp, src_ip, XFS_ILOCK_EXCL); - -	if (target_ip) { -		IHOLD(target_ip); -		xfs_trans_ijoin(tp, target_ip, XFS_ILOCK_EXCL); -	} +	xfs_trans_ijoin_ref(tp, src_dp, XFS_ILOCK_EXCL); +	if (new_parent) +		xfs_trans_ijoin_ref(tp, target_dp, XFS_ILOCK_EXCL); +	xfs_trans_ijoin_ref(tp, src_ip, XFS_ILOCK_EXCL); +	if (target_ip) +		xfs_trans_ijoin_ref(tp, target_ip, XFS_ILOCK_EXCL);  	/*  	 * If we are using project inheritance, we only allow renames diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 213792e1ad0..f2065ccb6c2 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -1892,7 +1892,6 @@ xfs_trans_roll(  	if (error)  		return error; -	xfs_trans_ijoin(trans, dp, XFS_ILOCK_EXCL); -	xfs_trans_ihold(trans, dp); +	xfs_trans_ijoin(trans, dp);  	return 0;  } diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 37c0ce1ccd4..aa6f422f036 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -475,8 +475,8 @@ void		xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint);  void		xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *);  int		xfs_trans_iget(struct xfs_mount *, xfs_trans_t *,  			       xfs_ino_t , uint, uint, struct xfs_inode **); -void		xfs_trans_ijoin(xfs_trans_t *, struct xfs_inode *, uint); -void		xfs_trans_ihold(xfs_trans_t *, struct xfs_inode *); +void		xfs_trans_ijoin_ref(struct xfs_trans *, struct xfs_inode *, uint); +void		xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *);  void		xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint);  void		xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint);  struct xfs_efi_log_item	*xfs_trans_get_efi(xfs_trans_t *, uint); diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c index 865eeb63ce1..cdc53a1050c 100644 --- a/fs/xfs/xfs_trans_inode.c +++ b/fs/xfs/xfs_trans_inode.c @@ -33,6 +33,7 @@  #include "xfs_btree.h"  #include "xfs_trans_priv.h"  #include "xfs_inode_item.h" +#include "xfs_trace.h"  #ifdef XFS_TRANS_DEBUG  STATIC void @@ -42,7 +43,6 @@ xfs_trans_inode_broot_debug(  #define	xfs_trans_inode_broot_debug(ip)  #endif -  /*   * Get an inode and join it to the transaction.   */ @@ -58,32 +58,31 @@ xfs_trans_iget(  	int			error;  	error = xfs_iget(mp, tp, ino, flags, lock_flags, ipp); -	if (!error && tp) -		xfs_trans_ijoin(tp, *ipp, lock_flags); +	if (!error && tp) { +		xfs_trans_ijoin(tp, *ipp); +		(*ipp)->i_itemp->ili_lock_flags = lock_flags; +	}  	return error;  }  /* - * Add the locked inode to the transaction. - * The inode must be locked, and it cannot be associated with any - * transaction.  The caller must specify the locks already held - * on the inode. + * Add a locked inode to the transaction. + * + * The inode must be locked, and it cannot be associated with any transaction.   */  void  xfs_trans_ijoin( -	xfs_trans_t	*tp, -	xfs_inode_t	*ip, -	uint		lock_flags) +	struct xfs_trans	*tp, +	struct xfs_inode	*ip)  {  	xfs_inode_log_item_t	*iip;  	ASSERT(ip->i_transp == NULL);  	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); -	ASSERT(lock_flags & XFS_ILOCK_EXCL);  	if (ip->i_itemp == NULL)  		xfs_inode_item_init(ip, ip->i_mount);  	iip = ip->i_itemp; -	ASSERT(iip->ili_flags == 0); +	ASSERT(iip->ili_lock_flags == 0);  	/*  	 * Get a log_item_desc to point at the new item. @@ -93,42 +92,31 @@ xfs_trans_ijoin(  	xfs_trans_inode_broot_debug(ip);  	/* -	 * If the IO lock is already held, mark that in the inode log item. -	 */ -	if (lock_flags & XFS_IOLOCK_EXCL) { -		iip->ili_flags |= XFS_ILI_IOLOCKED_EXCL; -	} else if (lock_flags & XFS_IOLOCK_SHARED) { -		iip->ili_flags |= XFS_ILI_IOLOCKED_SHARED; -	} - -	/*  	 * Initialize i_transp so we can find it with xfs_inode_incore()  	 * in xfs_trans_iget() above.  	 */  	ip->i_transp = tp;  } - -  /* - * Mark the inode as not needing to be unlocked when the inode item's - * IOP_UNLOCK() routine is called.  The inode must already be locked - * and associated with the given transaction. + * Add a locked inode to the transaction. + * + * + * Grabs a reference to the inode which will be dropped when the transaction + * is commited.  The inode will also be unlocked at that point.  The inode + * must be locked, and it cannot be associated with any transaction.   */ -/*ARGSUSED*/  void -xfs_trans_ihold( -	xfs_trans_t	*tp, -	xfs_inode_t	*ip) +xfs_trans_ijoin_ref( +	struct xfs_trans	*tp, +	struct xfs_inode	*ip, +	uint			lock_flags)  { -	ASSERT(ip->i_transp == tp); -	ASSERT(ip->i_itemp != NULL); -	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); - -	ip->i_itemp->ili_flags |= XFS_ILI_HOLD; +	xfs_trans_ijoin(tp, ip); +	IHOLD(ip); +	ip->i_itemp->ili_lock_flags = lock_flags;  } -  /*   * This is called to mark the fields indicated in fieldmask as needing   * to be logged when the transaction is committed.  The inode must diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c index 8965887d26b..102ce4898ab 100644 --- a/fs/xfs/xfs_utils.c +++ b/fs/xfs/xfs_utils.c @@ -374,8 +374,8 @@ xfs_truncate_file(  	 * of references will stay constant.  	 */  	xfs_ilock(ip, XFS_ILOCK_EXCL); -	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); -	xfs_trans_ihold(tp, ip); +	xfs_trans_ijoin(tp, ip); +  	/*  	 * Signal a sync xaction.  The only case where that isn't  	 * the case is if we're truncating an already unlinked file diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 161444e768b..130343a5d22 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -268,8 +268,7 @@ xfs_setattr(  		commit_flags = XFS_TRANS_RELEASE_LOG_RES;  		xfs_ilock(ip, XFS_ILOCK_EXCL); -		xfs_trans_ijoin(tp, ip, lock_flags); -		xfs_trans_ihold(tp, ip); +		xfs_trans_ijoin(tp, ip);  		/*  		 * Only change the c/mtime if we are changing the size @@ -319,8 +318,7 @@ xfs_setattr(  			xfs_iflags_set(ip, XFS_ITRUNCATED);  		}  	} else if (tp) { -		xfs_trans_ijoin(tp, ip, lock_flags); -		xfs_trans_ihold(tp, ip); +		xfs_trans_ijoin(tp, ip);  	}  	/* @@ -653,10 +651,7 @@ xfs_free_eofblocks(  		}  		xfs_ilock(ip, XFS_ILOCK_EXCL); -		xfs_trans_ijoin(tp, ip, -				XFS_IOLOCK_EXCL | -				XFS_ILOCK_EXCL); -		xfs_trans_ihold(tp, ip); +		xfs_trans_ijoin(tp, ip);  		error = xfs_itruncate_finish(&tp, ip,  					     ip->i_size, @@ -728,8 +723,7 @@ xfs_inactive_symlink_rmt(  	xfs_ilock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);  	size = (int)ip->i_d.di_size;  	ip->i_d.di_size = 0; -	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); -	xfs_trans_ihold(tp, ip); +	xfs_trans_ijoin(tp, ip);  	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);  	/*  	 * Find the block(s) so we can inval and unmap them. @@ -773,8 +767,7 @@ xfs_inactive_symlink_rmt(  	 * Mark it dirty so it will be logged and moved forward in the log as  	 * part of every commit.  	 */ -	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); -	xfs_trans_ihold(tp, ip); +	xfs_trans_ijoin(tp, ip);  	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);  	/*  	 * Get a new, empty transaction to return to our caller. @@ -907,8 +900,7 @@ xfs_inactive_attrs(  		goto error_cancel;  	xfs_ilock(ip, XFS_ILOCK_EXCL); -	xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); -	xfs_trans_ihold(tp, ip); +	xfs_trans_ijoin(tp, ip);  	xfs_idestroy_fork(ip, XFS_ATTR_FORK);  	ASSERT(ip->i_d.di_anextents == 0); @@ -1095,8 +1087,7 @@ xfs_inactive(  		}  		xfs_ilock(ip, XFS_ILOCK_EXCL); -		xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); -		xfs_trans_ihold(tp, ip); +		xfs_trans_ijoin(tp, ip);  		/*  		 * normally, we have to run xfs_itruncate_finish sync. @@ -1129,8 +1120,7 @@ xfs_inactive(  			return VN_INACTIVE_CACHE;  		} -		xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); -		xfs_trans_ihold(tp, ip); +		xfs_trans_ijoin(tp, ip);  	} else {  		error = xfs_trans_reserve(tp, 0,  					  XFS_IFREE_LOG_RES(mp), @@ -1143,8 +1133,7 @@ xfs_inactive(  		}  		xfs_ilock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); -		xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); -		xfs_trans_ihold(tp, ip); +		xfs_trans_ijoin(tp, ip);  	}  	/* @@ -1392,8 +1381,7 @@ xfs_create(  	 * the transaction cancel unlocking dp so don't do it explicitly in the  	 * error path.  	 */ -	IHOLD(dp); -	xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); +	xfs_trans_ijoin_ref(tp, dp, XFS_ILOCK_EXCL);  	unlock_dp_on_error = B_FALSE;  	error = xfs_dir_createname(tp, dp, name, ip->i_ino, @@ -1730,15 +1718,8 @@ xfs_remove(  	xfs_lock_two_inodes(dp, ip, XFS_ILOCK_EXCL); -	/* -	 * At this point, we've gotten both the directory and the entry -	 * inodes locked. -	 */ -	IHOLD(ip); -	xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); - -	IHOLD(dp); -	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); +	xfs_trans_ijoin_ref(tp, dp, XFS_ILOCK_EXCL); +	xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL);  	/*  	 * If we're removing a directory perform some additional validation. @@ -1884,15 +1865,8 @@ xfs_link(  	xfs_lock_two_inodes(sip, tdp, XFS_ILOCK_EXCL); -	/* -	 * Increment vnode ref counts since xfs_trans_commit & -	 * xfs_trans_cancel will both unlock the inodes and -	 * decrement the associated ref counts. -	 */ -	IHOLD(sip); -	IHOLD(tdp); -	xfs_trans_ijoin(tp, sip, XFS_ILOCK_EXCL); -	xfs_trans_ijoin(tp, tdp, XFS_ILOCK_EXCL); +	xfs_trans_ijoin_ref(tp, sip, XFS_ILOCK_EXCL); +	xfs_trans_ijoin_ref(tp, tdp, XFS_ILOCK_EXCL);  	/*  	 * If the source has too many links, we can't make any more to it. @@ -2087,8 +2061,7 @@ xfs_symlink(  	 * transaction cancel unlocking dp so don't do it explicitly in the  	 * error path.  	 */ -	IHOLD(dp); -	xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); +	xfs_trans_ijoin_ref(tp, dp, XFS_ILOCK_EXCL);  	unlock_dp_on_error = B_FALSE;  	/* @@ -2227,13 +2200,12 @@ xfs_set_dmattrs(  		return error;  	}  	xfs_ilock(ip, XFS_ILOCK_EXCL); -	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); +	xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL);  	ip->i_d.di_dmevmask = evmask;  	ip->i_d.di_dmstate  = state;  	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); -	IHOLD(ip);  	error = xfs_trans_commit(tp, 0);  	return error; @@ -2366,8 +2338,7 @@ xfs_alloc_file_space(  		if (error)  			goto error1; -		xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); -		xfs_trans_ihold(tp, ip); +		xfs_trans_ijoin(tp, ip);  		/*  		 * Issue the xfs_bmapi() call to allocate the blocks @@ -2668,8 +2639,7 @@ xfs_free_file_space(  		if (error)  			goto error1; -		xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); -		xfs_trans_ihold(tp, ip); +		xfs_trans_ijoin(tp, ip);  		/*  		 * issue the bunmapi() call to free the blocks @@ -2839,8 +2809,7 @@ xfs_change_file_space(  	xfs_ilock(ip, XFS_ILOCK_EXCL); -	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); -	xfs_trans_ihold(tp, ip); +	xfs_trans_ijoin(tp, ip);  	if ((attr_flags & XFS_ATTR_DMI) == 0) {  		ip->i_d.di_mode &= ~S_ISUID;  |