xfs: Hold inode locks in xfs_trans_alloc_dir
Modify xfs_trans_alloc_dir to hold locks after return. Caller will be responsible for manual unlock. We will need this later to hold locks across parent pointer operations Signed-off-by: Allison Henderson <allison.henderson@oracle.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Catherine Hoang <catherine.hoang@oracle.com> Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
267979b4ce
commit
bd5562111d
2 changed files with 19 additions and 4 deletions
|
@ -1368,10 +1368,15 @@ xfs_link(
|
||||||
if (xfs_has_wsync(mp) || xfs_has_dirsync(mp))
|
if (xfs_has_wsync(mp) || xfs_has_dirsync(mp))
|
||||||
xfs_trans_set_sync(tp);
|
xfs_trans_set_sync(tp);
|
||||||
|
|
||||||
return xfs_trans_commit(tp);
|
error = xfs_trans_commit(tp);
|
||||||
|
xfs_iunlock(tdp, XFS_ILOCK_EXCL);
|
||||||
|
xfs_iunlock(sip, XFS_ILOCK_EXCL);
|
||||||
|
return error;
|
||||||
|
|
||||||
error_return:
|
error_return:
|
||||||
xfs_trans_cancel(tp);
|
xfs_trans_cancel(tp);
|
||||||
|
xfs_iunlock(tdp, XFS_ILOCK_EXCL);
|
||||||
|
xfs_iunlock(sip, XFS_ILOCK_EXCL);
|
||||||
std_return:
|
std_return:
|
||||||
if (error == -ENOSPC && nospace_error)
|
if (error == -ENOSPC && nospace_error)
|
||||||
error = nospace_error;
|
error = nospace_error;
|
||||||
|
@ -2781,15 +2786,20 @@ xfs_remove(
|
||||||
|
|
||||||
error = xfs_trans_commit(tp);
|
error = xfs_trans_commit(tp);
|
||||||
if (error)
|
if (error)
|
||||||
goto std_return;
|
goto out_unlock;
|
||||||
|
|
||||||
if (is_dir && xfs_inode_is_filestream(ip))
|
if (is_dir && xfs_inode_is_filestream(ip))
|
||||||
xfs_filestream_deassociate(ip);
|
xfs_filestream_deassociate(ip);
|
||||||
|
|
||||||
|
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||||
|
xfs_iunlock(dp, XFS_ILOCK_EXCL);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_trans_cancel:
|
out_trans_cancel:
|
||||||
xfs_trans_cancel(tp);
|
xfs_trans_cancel(tp);
|
||||||
|
out_unlock:
|
||||||
|
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||||
|
xfs_iunlock(dp, XFS_ILOCK_EXCL);
|
||||||
std_return:
|
std_return:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1430,6 +1430,8 @@ out_cancel:
|
||||||
* The caller must ensure that the on-disk dquots attached to this inode have
|
* The caller must ensure that the on-disk dquots attached to this inode have
|
||||||
* already been allocated and initialized. The ILOCKs will be dropped when the
|
* already been allocated and initialized. The ILOCKs will be dropped when the
|
||||||
* transaction is committed or cancelled.
|
* transaction is committed or cancelled.
|
||||||
|
*
|
||||||
|
* Caller is responsible for unlocking the inodes manually upon return
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xfs_trans_alloc_dir(
|
xfs_trans_alloc_dir(
|
||||||
|
@ -1460,8 +1462,8 @@ retry:
|
||||||
|
|
||||||
xfs_lock_two_inodes(dp, XFS_ILOCK_EXCL, ip, XFS_ILOCK_EXCL);
|
xfs_lock_two_inodes(dp, XFS_ILOCK_EXCL, ip, XFS_ILOCK_EXCL);
|
||||||
|
|
||||||
xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
|
xfs_trans_ijoin(tp, dp, 0);
|
||||||
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
|
xfs_trans_ijoin(tp, ip, 0);
|
||||||
|
|
||||||
error = xfs_qm_dqattach_locked(dp, false);
|
error = xfs_qm_dqattach_locked(dp, false);
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -1484,6 +1486,9 @@ retry:
|
||||||
if (error == -EDQUOT || error == -ENOSPC) {
|
if (error == -EDQUOT || error == -ENOSPC) {
|
||||||
if (!retried) {
|
if (!retried) {
|
||||||
xfs_trans_cancel(tp);
|
xfs_trans_cancel(tp);
|
||||||
|
xfs_iunlock(dp, XFS_ILOCK_EXCL);
|
||||||
|
if (dp != ip)
|
||||||
|
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||||
xfs_blockgc_free_quota(dp, 0);
|
xfs_blockgc_free_quota(dp, 0);
|
||||||
retried = true;
|
retried = true;
|
||||||
goto retry;
|
goto retry;
|
||||||
|
|
Loading…
Add table
Reference in a new issue