diff options
Diffstat (limited to 'fs/xfs')
| -rw-r--r-- | fs/xfs/quota/xfs_qm.c | 7 | ||||
| -rw-r--r-- | fs/xfs/xfs_inode.c | 5 | ||||
| -rw-r--r-- | fs/xfs/xfs_trans.h | 2 | ||||
| -rw-r--r-- | fs/xfs/xfs_trans_inode.c | 22 | ||||
| -rw-r--r-- | fs/xfs/xfs_vnodeops.c | 61 | 
5 files changed, 19 insertions, 78 deletions
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 206a2815ced..f517963aec0 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c @@ -1230,13 +1230,6 @@ xfs_qm_qino_alloc(  	}  	/* -	 * Keep an extra reference to this quota inode. This inode is -	 * locked exclusively and joined to the transaction already. -	 */ -	ASSERT(xfs_isilocked(*ip, XFS_ILOCK_EXCL)); -	IHOLD(*ip); - -	/*  	 * Make the changes in the superblock, and log those too.  	 * sbfields arg may contain fields other than *QUOTINO;  	 * VERSIONNUM for example. diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index be7cf625421..c39278b6c87 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1016,8 +1016,8 @@ xfs_ialloc(  	 * This is because we're setting fields here we need  	 * to prevent others from looking at until we're done.  	 */ -	error = xfs_trans_iget(tp->t_mountp, tp, ino, -				XFS_IGET_CREATE, XFS_ILOCK_EXCL, &ip); +	error = xfs_iget(tp->t_mountp, tp, ino, XFS_IGET_CREATE, +			 XFS_ILOCK_EXCL, &ip);  	if (error)  		return error;  	ASSERT(ip != NULL); @@ -1166,6 +1166,7 @@ xfs_ialloc(  	/*  	 * Log the new values stuffed into the inode.  	 */ +	xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL);  	xfs_trans_log_inode(tp, ip, flags);  	/* now that we have an i_mode we can setup inode ops and unlock */ diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index c2042b736b8..06a9759b635 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -469,8 +469,6 @@ void		xfs_trans_inode_buf(xfs_trans_t *, struct xfs_buf *);  void		xfs_trans_stale_inode_buf(xfs_trans_t *, struct xfs_buf *);  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_ichgtime(struct xfs_trans *, struct xfs_inode *, int);  void		xfs_trans_ijoin_ref(struct xfs_trans *, struct xfs_inode *, uint);  void		xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *); diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c index ccb34532768..16084d8ea23 100644 --- a/fs/xfs/xfs_trans_inode.c +++ b/fs/xfs/xfs_trans_inode.c @@ -44,28 +44,6 @@ xfs_trans_inode_broot_debug(  #endif  /* - * Get an inode and join it to the transaction. - */ -int -xfs_trans_iget( -	xfs_mount_t	*mp, -	xfs_trans_t	*tp, -	xfs_ino_t	ino, -	uint		flags, -	uint		lock_flags, -	xfs_inode_t	**ipp) -{ -	int			error; - -	error = xfs_iget(mp, tp, ino, flags, lock_flags, ipp); -	if (!error && tp) { -		xfs_trans_ijoin(tp, *ipp); -		(*ipp)->i_itemp->ili_lock_flags = lock_flags; -	} -	return error; -} - -/*   * Add a locked inode to the transaction.   *   * The inode must be locked, and it cannot be associated with any transaction. diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index d8e6f8cd6f0..258d4f98eb9 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -1310,7 +1310,7 @@ xfs_create(  	error = xfs_qm_vop_dqalloc(dp, current_fsuid(), current_fsgid(), prid,  			XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);  	if (error) -		goto std_return; +		return error;  	if (is_dir) {  		rdev = 0; @@ -1390,12 +1390,6 @@ xfs_create(  	}  	/* -	 * At this point, we've gotten a newly allocated inode. -	 * It is locked (and joined to the transaction). -	 */ -	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); - -	/*  	 * Now we join the directory inode to the transaction.  We do not do it  	 * earlier because xfs_dir_ialloc might commit the previous transaction  	 * (and release all the locks).  An error from here on will result in @@ -1440,22 +1434,13 @@ xfs_create(  	 */  	xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp); -	/* -	 * xfs_trans_commit normally decrements the vnode ref count -	 * when it unlocks the inode. Since we want to return the -	 * vnode to the caller, we bump the vnode ref count now. -	 */ -	IHOLD(ip); -  	error = xfs_bmap_finish(&tp, &free_list, &committed);  	if (error) -		goto out_abort_rele; +		goto out_bmap_cancel;  	error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); -	if (error) { -		IRELE(ip); -		goto out_dqrele; -	} +	if (error) +		goto out_release_inode;  	xfs_qm_dqrele(udqp);  	xfs_qm_dqrele(gdqp); @@ -1469,27 +1454,21 @@ xfs_create(  	cancel_flags |= XFS_TRANS_ABORT;   out_trans_cancel:  	xfs_trans_cancel(tp, cancel_flags); - out_dqrele: + out_release_inode: +	/* +	 * Wait until after the current transaction is aborted to +	 * release the inode.  This prevents recursive transactions +	 * and deadlocks from xfs_inactive. +	 */ +	if (ip) +		IRELE(ip); +  	xfs_qm_dqrele(udqp);  	xfs_qm_dqrele(gdqp);  	if (unlock_dp_on_error)  		xfs_iunlock(dp, XFS_ILOCK_EXCL); - std_return:  	return error; - - out_abort_rele: -	/* -	 * Wait until after the current transaction is aborted to -	 * release the inode.  This prevents recursive transactions -	 * and deadlocks from xfs_inactive. -	 */ -	xfs_bmap_cancel(&free_list); -	cancel_flags |= XFS_TRANS_ABORT; -	xfs_trans_cancel(tp, cancel_flags); -	IRELE(ip); -	unlock_dp_on_error = B_FALSE; -	goto out_dqrele;  }  #ifdef DEBUG @@ -2114,9 +2093,8 @@ xfs_symlink(  				  XFS_BMAPI_WRITE | XFS_BMAPI_METADATA,  				  &first_block, resblks, mval, &nmaps,  				  &free_list); -		if (error) { -			goto error1; -		} +		if (error) +			goto error2;  		if (resblks)  			resblks -= fs_blocks; @@ -2148,7 +2126,7 @@ xfs_symlink(  	error = xfs_dir_createname(tp, dp, link_name, ip->i_ino,  					&first_block, &free_list, resblks);  	if (error) -		goto error1; +		goto error2;  	xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);  	xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); @@ -2161,13 +2139,6 @@ xfs_symlink(  		xfs_trans_set_sync(tp);  	} -	/* -	 * xfs_trans_commit normally decrements the vnode ref count -	 * when it unlocks the inode. Since we want to return the -	 * vnode to the caller, we bump the vnode ref count now. -	 */ -	IHOLD(ip); -  	error = xfs_bmap_finish(&tp, &free_list, &committed);  	if (error) {  		goto error2;  |