diff options
author | J. Bruce Fields <bfields@redhat.com> | 2012-04-18 15:16:33 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-11-09 00:16:39 -0500 |
commit | 375e289ea85166c5241c570940e7e7e966c63a9f (patch) | |
tree | 406c6701e7a45a809114bfb925f474bdd20d252a /fs/ext4/move_extent.c | |
parent | f27c9298fd717e1f7e63e314a7a85a3a7e77139d (diff) |
vfs: pull ext4's double-i_mutex-locking into common code
We want to do this elsewhere as well.
Also catch any attempts to use it for directories (where this ordering
would conflict with ancestor-first directory ordering in lock_rename).
Cc: Andreas Dilger <adilger.kernel@dilger.ca>
Cc: Dave Chinner <david@fromorbit.com>
Acked-by: Jeff Layton <jlayton@redhat.com>
Acked-by: "Theodore Ts'o" <tytso@mit.edu>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/ext4/move_extent.c')
-rw-r--r-- | fs/ext4/move_extent.c | 40 |
1 files changed, 2 insertions, 38 deletions
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c index 7fa4d855dbd5..773b503bd18c 100644 --- a/fs/ext4/move_extent.c +++ b/fs/ext4/move_extent.c | |||
@@ -1203,42 +1203,6 @@ mext_check_arguments(struct inode *orig_inode, | |||
1203 | } | 1203 | } |
1204 | 1204 | ||
1205 | /** | 1205 | /** |
1206 | * ext4_inode_double_lock - Lock i_mutex on both @inode1 and @inode2 | ||
1207 | * | ||
1208 | * @inode1: the inode structure | ||
1209 | * @inode2: the inode structure | ||
1210 | * | ||
1211 | * Lock two inodes' i_mutex | ||
1212 | */ | ||
1213 | void | ||
1214 | ext4_inode_double_lock(struct inode *inode1, struct inode *inode2) | ||
1215 | { | ||
1216 | BUG_ON(inode1 == inode2); | ||
1217 | if (inode1 < inode2) { | ||
1218 | mutex_lock_nested(&inode1->i_mutex, I_MUTEX_PARENT); | ||
1219 | mutex_lock_nested(&inode2->i_mutex, I_MUTEX_CHILD); | ||
1220 | } else { | ||
1221 | mutex_lock_nested(&inode2->i_mutex, I_MUTEX_PARENT); | ||
1222 | mutex_lock_nested(&inode1->i_mutex, I_MUTEX_CHILD); | ||
1223 | } | ||
1224 | } | ||
1225 | |||
1226 | /** | ||
1227 | * ext4_inode_double_unlock - Release i_mutex on both @inode1 and @inode2 | ||
1228 | * | ||
1229 | * @inode1: the inode that is released first | ||
1230 | * @inode2: the inode that is released second | ||
1231 | * | ||
1232 | */ | ||
1233 | |||
1234 | void | ||
1235 | ext4_inode_double_unlock(struct inode *inode1, struct inode *inode2) | ||
1236 | { | ||
1237 | mutex_unlock(&inode1->i_mutex); | ||
1238 | mutex_unlock(&inode2->i_mutex); | ||
1239 | } | ||
1240 | |||
1241 | /** | ||
1242 | * ext4_move_extents - Exchange the specified range of a file | 1206 | * ext4_move_extents - Exchange the specified range of a file |
1243 | * | 1207 | * |
1244 | * @o_filp: file structure of the original file | 1208 | * @o_filp: file structure of the original file |
@@ -1327,7 +1291,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, | |||
1327 | return -EINVAL; | 1291 | return -EINVAL; |
1328 | } | 1292 | } |
1329 | /* Protect orig and donor inodes against a truncate */ | 1293 | /* Protect orig and donor inodes against a truncate */ |
1330 | ext4_inode_double_lock(orig_inode, donor_inode); | 1294 | lock_two_nondirectories(orig_inode, donor_inode); |
1331 | 1295 | ||
1332 | /* Wait for all existing dio workers */ | 1296 | /* Wait for all existing dio workers */ |
1333 | ext4_inode_block_unlocked_dio(orig_inode); | 1297 | ext4_inode_block_unlocked_dio(orig_inode); |
@@ -1535,7 +1499,7 @@ out: | |||
1535 | ext4_double_up_write_data_sem(orig_inode, donor_inode); | 1499 | ext4_double_up_write_data_sem(orig_inode, donor_inode); |
1536 | ext4_inode_resume_unlocked_dio(orig_inode); | 1500 | ext4_inode_resume_unlocked_dio(orig_inode); |
1537 | ext4_inode_resume_unlocked_dio(donor_inode); | 1501 | ext4_inode_resume_unlocked_dio(donor_inode); |
1538 | ext4_inode_double_unlock(orig_inode, donor_inode); | 1502 | unlock_two_nondirectories(orig_inode, donor_inode); |
1539 | 1503 | ||
1540 | return ret; | 1504 | return ret; |
1541 | } | 1505 | } |