aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r--fs/xfs/xfs_inode.c34
1 files changed, 21 insertions, 13 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 657f6123b445..65792660b043 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -663,30 +663,29 @@ xfs_lookup(
663{ 663{
664 xfs_ino_t inum; 664 xfs_ino_t inum;
665 int error; 665 int error;
666 uint lock_mode;
667 666
668 trace_xfs_lookup(dp, name); 667 trace_xfs_lookup(dp, name);
669 668
670 if (XFS_FORCED_SHUTDOWN(dp->i_mount)) 669 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
671 return -EIO; 670 return -EIO;
672 671
673 lock_mode = xfs_ilock_data_map_shared(dp); 672 xfs_ilock(dp, XFS_IOLOCK_SHARED);
674 error = xfs_dir_lookup(NULL, dp, name, &inum, ci_name); 673 error = xfs_dir_lookup(NULL, dp, name, &inum, ci_name);
675 xfs_iunlock(dp, lock_mode);
676
677 if (error) 674 if (error)
678 goto out; 675 goto out_unlock;
679 676
680 error = xfs_iget(dp->i_mount, NULL, inum, 0, 0, ipp); 677 error = xfs_iget(dp->i_mount, NULL, inum, 0, 0, ipp);
681 if (error) 678 if (error)
682 goto out_free_name; 679 goto out_free_name;
683 680
681 xfs_iunlock(dp, XFS_IOLOCK_SHARED);
684 return 0; 682 return 0;
685 683
686out_free_name: 684out_free_name:
687 if (ci_name) 685 if (ci_name)
688 kmem_free(ci_name->name); 686 kmem_free(ci_name->name);
689out: 687out_unlock:
688 xfs_iunlock(dp, XFS_IOLOCK_SHARED);
690 *ipp = NULL; 689 *ipp = NULL;
691 return error; 690 return error;
692} 691}
@@ -1183,7 +1182,8 @@ xfs_create(
1183 goto out_trans_cancel; 1182 goto out_trans_cancel;
1184 1183
1185 1184
1186 xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); 1185 xfs_ilock(dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL |
1186 XFS_IOLOCK_PARENT | XFS_ILOCK_PARENT);
1187 unlock_dp_on_error = true; 1187 unlock_dp_on_error = true;
1188 1188
1189 xfs_bmap_init(&free_list, &first_block); 1189 xfs_bmap_init(&free_list, &first_block);
@@ -1222,7 +1222,7 @@ xfs_create(
1222 * the transaction cancel unlocking dp so don't do it explicitly in the 1222 * the transaction cancel unlocking dp so don't do it explicitly in the
1223 * error path. 1223 * error path.
1224 */ 1224 */
1225 xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); 1225 xfs_trans_ijoin(tp, dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
1226 unlock_dp_on_error = false; 1226 unlock_dp_on_error = false;
1227 1227
1228 error = xfs_dir_createname(tp, dp, name, ip->i_ino, 1228 error = xfs_dir_createname(tp, dp, name, ip->i_ino,
@@ -1295,7 +1295,7 @@ xfs_create(
1295 xfs_qm_dqrele(pdqp); 1295 xfs_qm_dqrele(pdqp);
1296 1296
1297 if (unlock_dp_on_error) 1297 if (unlock_dp_on_error)
1298 xfs_iunlock(dp, XFS_ILOCK_EXCL); 1298 xfs_iunlock(dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
1299 return error; 1299 return error;
1300} 1300}
1301 1301
@@ -1443,10 +1443,11 @@ xfs_link(
1443 if (error) 1443 if (error)
1444 goto error_return; 1444 goto error_return;
1445 1445
1446 xfs_ilock(tdp, XFS_IOLOCK_EXCL | XFS_IOLOCK_PARENT);
1446 xfs_lock_two_inodes(sip, tdp, XFS_ILOCK_EXCL); 1447 xfs_lock_two_inodes(sip, tdp, XFS_ILOCK_EXCL);
1447 1448
1448 xfs_trans_ijoin(tp, sip, XFS_ILOCK_EXCL); 1449 xfs_trans_ijoin(tp, sip, XFS_ILOCK_EXCL);
1449 xfs_trans_ijoin(tp, tdp, XFS_ILOCK_EXCL); 1450 xfs_trans_ijoin(tp, tdp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
1450 1451
1451 /* 1452 /*
1452 * If we are using project inheritance, we only allow hard link 1453 * If we are using project inheritance, we only allow hard link
@@ -2549,9 +2550,10 @@ xfs_remove(
2549 goto out_trans_cancel; 2550 goto out_trans_cancel;
2550 } 2551 }
2551 2552
2553 xfs_ilock(dp, XFS_IOLOCK_EXCL | XFS_IOLOCK_PARENT);
2552 xfs_lock_two_inodes(dp, ip, XFS_ILOCK_EXCL); 2554 xfs_lock_two_inodes(dp, ip, XFS_ILOCK_EXCL);
2553 2555
2554 xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); 2556 xfs_trans_ijoin(tp, dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
2555 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 2557 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
2556 2558
2557 /* 2559 /*
@@ -2932,6 +2934,12 @@ xfs_rename(
2932 * whether the target directory is the same as the source 2934 * whether the target directory is the same as the source
2933 * directory, we can lock from 2 to 4 inodes. 2935 * directory, we can lock from 2 to 4 inodes.
2934 */ 2936 */
2937 if (!new_parent)
2938 xfs_ilock(src_dp, XFS_IOLOCK_EXCL | XFS_IOLOCK_PARENT);
2939 else
2940 xfs_lock_two_inodes(src_dp, target_dp,
2941 XFS_IOLOCK_EXCL | XFS_IOLOCK_PARENT);
2942
2935 xfs_lock_inodes(inodes, num_inodes, XFS_ILOCK_EXCL); 2943 xfs_lock_inodes(inodes, num_inodes, XFS_ILOCK_EXCL);
2936 2944
2937 /* 2945 /*
@@ -2939,9 +2947,9 @@ xfs_rename(
2939 * we can rely on either trans_commit or trans_cancel to unlock 2947 * we can rely on either trans_commit or trans_cancel to unlock
2940 * them. 2948 * them.
2941 */ 2949 */
2942 xfs_trans_ijoin(tp, src_dp, XFS_ILOCK_EXCL); 2950 xfs_trans_ijoin(tp, src_dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
2943 if (new_parent) 2951 if (new_parent)
2944 xfs_trans_ijoin(tp, target_dp, XFS_ILOCK_EXCL); 2952 xfs_trans_ijoin(tp, target_dp, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
2945 xfs_trans_ijoin(tp, src_ip, XFS_ILOCK_EXCL); 2953 xfs_trans_ijoin(tp, src_ip, XFS_ILOCK_EXCL);
2946 if (target_ip) 2954 if (target_ip)
2947 xfs_trans_ijoin(tp, target_ip, XFS_ILOCK_EXCL); 2955 xfs_trans_ijoin(tp, target_ip, XFS_ILOCK_EXCL);