diff options
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 34 |
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 | ||
686 | out_free_name: | 684 | out_free_name: |
687 | if (ci_name) | 685 | if (ci_name) |
688 | kmem_free(ci_name->name); | 686 | kmem_free(ci_name->name); |
689 | out: | 687 | out_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); |