aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_vnodeops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
-rw-r--r--fs/xfs/xfs_vnodeops.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index e2c9bbc27823..de17aed578f0 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -1947,7 +1947,7 @@ xfs_create(
1947 goto error_return; 1947 goto error_return;
1948 } 1948 }
1949 1949
1950 xfs_ilock(dp, XFS_ILOCK_EXCL); 1950 xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
1951 1951
1952 XFS_BMAP_INIT(&free_list, &first_block); 1952 XFS_BMAP_INIT(&free_list, &first_block);
1953 1953
@@ -2141,7 +2141,7 @@ xfs_lock_dir_and_entry(
2141 attempts = 0; 2141 attempts = 0;
2142 2142
2143again: 2143again:
2144 xfs_ilock(dp, XFS_ILOCK_EXCL); 2144 xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
2145 2145
2146 e_inum = ip->i_ino; 2146 e_inum = ip->i_ino;
2147 2147
@@ -2210,6 +2210,21 @@ int xfs_lock_delays;
2210#endif 2210#endif
2211 2211
2212/* 2212/*
2213 * Bump the subclass so xfs_lock_inodes() acquires each lock with
2214 * a different value
2215 */
2216static inline int
2217xfs_lock_inumorder(int lock_mode, int subclass)
2218{
2219 if (lock_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL))
2220 lock_mode |= (subclass + XFS_IOLOCK_INUMORDER) << XFS_IOLOCK_SHIFT;
2221 if (lock_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL))
2222 lock_mode |= (subclass + XFS_ILOCK_INUMORDER) << XFS_ILOCK_SHIFT;
2223
2224 return lock_mode;
2225}
2226
2227/*
2213 * The following routine will lock n inodes in exclusive mode. 2228 * The following routine will lock n inodes in exclusive mode.
2214 * We assume the caller calls us with the inodes in i_ino order. 2229 * We assume the caller calls us with the inodes in i_ino order.
2215 * 2230 *
@@ -2276,7 +2291,7 @@ again:
2276 * that is in the AIL. 2291 * that is in the AIL.
2277 */ 2292 */
2278 ASSERT(i != 0); 2293 ASSERT(i != 0);
2279 if (!xfs_ilock_nowait(ips[i], lock_mode)) { 2294 if (!xfs_ilock_nowait(ips[i], xfs_lock_inumorder(lock_mode, i))) {
2280 attempts++; 2295 attempts++;
2281 2296
2282 /* 2297 /*
@@ -2311,7 +2326,7 @@ again:
2311 goto again; 2326 goto again;
2312 } 2327 }
2313 } else { 2328 } else {
2314 xfs_ilock(ips[i], lock_mode); 2329 xfs_ilock(ips[i], xfs_lock_inumorder(lock_mode, i));
2315 } 2330 }
2316 } 2331 }
2317 2332
@@ -2845,7 +2860,7 @@ xfs_mkdir(
2845 goto error_return; 2860 goto error_return;
2846 } 2861 }
2847 2862
2848 xfs_ilock(dp, XFS_ILOCK_EXCL); 2863 xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
2849 2864
2850 /* 2865 /*
2851 * Check for directory link count overflow. 2866 * Check for directory link count overflow.
@@ -3399,7 +3414,7 @@ xfs_symlink(
3399 goto error_return; 3414 goto error_return;
3400 } 3415 }
3401 3416
3402 xfs_ilock(dp, XFS_ILOCK_EXCL); 3417 xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
3403 3418
3404 /* 3419 /*
3405 * Check whether the directory allows new symlinks or not. 3420 * Check whether the directory allows new symlinks or not.