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 | |
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')
-rw-r--r-- | fs/ext4/ext4.h | 2 | ||||
-rw-r--r-- | fs/ext4/ioctl.c | 4 | ||||
-rw-r--r-- | fs/ext4/move_extent.c | 40 |
3 files changed, 4 insertions, 42 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index af815ea9d7cc..d01d62315f7e 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -2734,8 +2734,6 @@ extern void ext4_double_down_write_data_sem(struct inode *first, | |||
2734 | struct inode *second); | 2734 | struct inode *second); |
2735 | extern void ext4_double_up_write_data_sem(struct inode *orig_inode, | 2735 | extern void ext4_double_up_write_data_sem(struct inode *orig_inode, |
2736 | struct inode *donor_inode); | 2736 | struct inode *donor_inode); |
2737 | void ext4_inode_double_lock(struct inode *inode1, struct inode *inode2); | ||
2738 | void ext4_inode_double_unlock(struct inode *inode1, struct inode *inode2); | ||
2739 | extern int ext4_move_extents(struct file *o_filp, struct file *d_filp, | 2737 | extern int ext4_move_extents(struct file *o_filp, struct file *d_filp, |
2740 | __u64 start_orig, __u64 start_donor, | 2738 | __u64 start_orig, __u64 start_donor, |
2741 | __u64 len, __u64 *moved_len); | 2739 | __u64 len, __u64 *moved_len); |
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index a569d335f804..60589b60e9b0 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c | |||
@@ -130,7 +130,7 @@ static long swap_inode_boot_loader(struct super_block *sb, | |||
130 | 130 | ||
131 | /* Protect orig inodes against a truncate and make sure, | 131 | /* Protect orig inodes against a truncate and make sure, |
132 | * that only 1 swap_inode_boot_loader is running. */ | 132 | * that only 1 swap_inode_boot_loader is running. */ |
133 | ext4_inode_double_lock(inode, inode_bl); | 133 | lock_two_nondirectories(inode, inode_bl); |
134 | 134 | ||
135 | truncate_inode_pages(&inode->i_data, 0); | 135 | truncate_inode_pages(&inode->i_data, 0); |
136 | truncate_inode_pages(&inode_bl->i_data, 0); | 136 | truncate_inode_pages(&inode_bl->i_data, 0); |
@@ -205,7 +205,7 @@ static long swap_inode_boot_loader(struct super_block *sb, | |||
205 | ext4_inode_resume_unlocked_dio(inode); | 205 | ext4_inode_resume_unlocked_dio(inode); |
206 | ext4_inode_resume_unlocked_dio(inode_bl); | 206 | ext4_inode_resume_unlocked_dio(inode_bl); |
207 | 207 | ||
208 | ext4_inode_double_unlock(inode, inode_bl); | 208 | unlock_two_nondirectories(inode, inode_bl); |
209 | 209 | ||
210 | iput(inode_bl); | 210 | iput(inode_bl); |
211 | 211 | ||
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 | } |