|
@@ -663,30 +663,29 @@ xfs_lookup(
|
|
|
{
|
|
|
xfs_ino_t inum;
|
|
|
int error;
|
|
|
- uint lock_mode;
|
|
|
|
|
|
trace_xfs_lookup(dp, name);
|
|
|
|
|
|
if (XFS_FORCED_SHUTDOWN(dp->i_mount))
|
|
|
return -EIO;
|
|
|
|
|
|
- lock_mode = xfs_ilock_data_map_shared(dp);
|
|
|
+ xfs_ilock(dp, XFS_IOLOCK_SHARED);
|
|
|
error = xfs_dir_lookup(NULL, dp, name, &inum, ci_name);
|
|
|
- xfs_iunlock(dp, lock_mode);
|
|
|
-
|
|
|
if (error)
|
|
|
- goto out;
|
|
|
+ goto out_unlock;
|
|
|
|
|
|
error = xfs_iget(dp->i_mount, NULL, inum, 0, 0, ipp);
|
|
|
if (error)
|
|
|
goto out_free_name;
|
|
|
|
|
|
+ xfs_iunlock(dp, XFS_IOLOCK_SHARED);
|
|
|
return 0;
|
|
|
|
|
|
out_free_name:
|
|
|
if (ci_name)
|
|
|
kmem_free(ci_name->name);
|
|
|
-out:
|
|
|
+out_unlock:
|
|
|
+ xfs_iunlock(dp, XFS_IOLOCK_SHARED);
|
|
|
*ipp = NULL;
|
|
|
return error;
|
|
|
}
|
|
@@ -1183,7 +1182,8 @@ xfs_create(
|
|
|
goto out_trans_cancel;
|
|
|
|
|
|
|
|
|
- xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
|
|
|
+ xfs_ilock(dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL |
|
|
|
+ XFS_IOLOCK_PARENT | XFS_ILOCK_PARENT);
|
|
|
unlock_dp_on_error = true;
|
|
|
|
|
|
xfs_bmap_init(&free_list, &first_block);
|
|
@@ -1222,7 +1222,7 @@ xfs_create(
|
|
|
* the transaction cancel unlocking dp so don't do it explicitly in the
|
|
|
* error path.
|
|
|
*/
|
|
|
- xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
|
|
|
+ xfs_trans_ijoin(tp, dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
|
|
|
unlock_dp_on_error = false;
|
|
|
|
|
|
error = xfs_dir_createname(tp, dp, name, ip->i_ino,
|
|
@@ -1295,7 +1295,7 @@ xfs_create(
|
|
|
xfs_qm_dqrele(pdqp);
|
|
|
|
|
|
if (unlock_dp_on_error)
|
|
|
- xfs_iunlock(dp, XFS_ILOCK_EXCL);
|
|
|
+ xfs_iunlock(dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
|
|
|
return error;
|
|
|
}
|
|
|
|
|
@@ -1443,10 +1443,11 @@ xfs_link(
|
|
|
if (error)
|
|
|
goto error_return;
|
|
|
|
|
|
+ xfs_ilock(tdp, XFS_IOLOCK_EXCL | XFS_IOLOCK_PARENT);
|
|
|
xfs_lock_two_inodes(sip, tdp, XFS_ILOCK_EXCL);
|
|
|
|
|
|
xfs_trans_ijoin(tp, sip, XFS_ILOCK_EXCL);
|
|
|
- xfs_trans_ijoin(tp, tdp, XFS_ILOCK_EXCL);
|
|
|
+ xfs_trans_ijoin(tp, tdp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
|
|
|
|
|
|
/*
|
|
|
* If we are using project inheritance, we only allow hard link
|
|
@@ -2549,9 +2550,10 @@ xfs_remove(
|
|
|
goto out_trans_cancel;
|
|
|
}
|
|
|
|
|
|
+ xfs_ilock(dp, XFS_IOLOCK_EXCL | XFS_IOLOCK_PARENT);
|
|
|
xfs_lock_two_inodes(dp, ip, XFS_ILOCK_EXCL);
|
|
|
|
|
|
- xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
|
|
|
+ xfs_trans_ijoin(tp, dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
|
|
|
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
|
|
|
|
|
|
/*
|
|
@@ -2932,6 +2934,12 @@ xfs_rename(
|
|
|
* whether the target directory is the same as the source
|
|
|
* directory, we can lock from 2 to 4 inodes.
|
|
|
*/
|
|
|
+ if (!new_parent)
|
|
|
+ xfs_ilock(src_dp, XFS_IOLOCK_EXCL | XFS_IOLOCK_PARENT);
|
|
|
+ else
|
|
|
+ xfs_lock_two_inodes(src_dp, target_dp,
|
|
|
+ XFS_IOLOCK_EXCL | XFS_IOLOCK_PARENT);
|
|
|
+
|
|
|
xfs_lock_inodes(inodes, num_inodes, XFS_ILOCK_EXCL);
|
|
|
|
|
|
/*
|
|
@@ -2939,9 +2947,9 @@ xfs_rename(
|
|
|
* we can rely on either trans_commit or trans_cancel to unlock
|
|
|
* them.
|
|
|
*/
|
|
|
- xfs_trans_ijoin(tp, src_dp, XFS_ILOCK_EXCL);
|
|
|
+ xfs_trans_ijoin(tp, src_dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
|
|
|
if (new_parent)
|
|
|
- xfs_trans_ijoin(tp, target_dp, XFS_ILOCK_EXCL);
|
|
|
+ xfs_trans_ijoin(tp, target_dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
|
|
|
xfs_trans_ijoin(tp, src_ip, XFS_ILOCK_EXCL);
|
|
|
if (target_ip)
|
|
|
xfs_trans_ijoin(tp, target_ip, XFS_ILOCK_EXCL);
|