1 ext4: move unlocked dio protection from ext4_alloc_file_blocks()
3 From: Jan Kara <jack@suse.com>
5 Currently ext4_alloc_file_blocks() was handling protection against
6 unlocked DIO. However we now need to sometimes call it under i_mmap_sem
7 and sometimes not and DIO protection ranks above it (although strictly
8 speaking this cannot currently create any deadlocks). Also
9 ext4_zero_range() was actually getting & releasing unlocked DIO
10 protection twice in some cases. Luckily it didn't introduce any real bug
11 but it was a land mine waiting to be stepped on. So move DIO protection
12 out from ext4_alloc_file_blocks() into the two callsites.
14 Signed-off-by: Jan Kara <jack@suse.com>
15 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
17 fs/ext4/extents.c | 21 ++++++++++-----------
18 1 file changed, 10 insertions(+), 11 deletions(-)
20 diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
21 index 6e0c5d37a232..66ab89b58c1f 100644
22 --- a/fs/ext4/extents.c
23 +++ b/fs/ext4/extents.c
24 @@ -4681,10 +4681,6 @@ static int ext4_alloc_file_blocks(struct file *file, ext4_lblk_t offset,
25 if (len <= EXT_UNWRITTEN_MAX_LEN)
26 flags |= EXT4_GET_BLOCKS_NO_NORMALIZE;
28 - /* Wait all existing dio workers, newcomers will block on i_mutex */
29 - ext4_inode_block_unlocked_dio(inode);
30 - inode_dio_wait(inode);
33 * credits to insert 1 extent into extent tree
35 @@ -4748,8 +4744,6 @@ retry:
39 - ext4_inode_resume_unlocked_dio(inode);
41 return ret > 0 ? ret2 : ret;
44 @@ -4823,6 +4817,10 @@ static long ext4_zero_range(struct file *file, loff_t offset,
45 if (mode & FALLOC_FL_KEEP_SIZE)
46 flags |= EXT4_GET_BLOCKS_KEEP_SIZE;
48 + /* Wait all existing dio workers, newcomers will block on i_mutex */
49 + ext4_inode_block_unlocked_dio(inode);
50 + inode_dio_wait(inode);
52 /* Preallocate the range including the unaligned edges */
53 if (partial_begin || partial_end) {
54 ret = ext4_alloc_file_blocks(file,
55 @@ -4831,7 +4829,7 @@ static long ext4_zero_range(struct file *file, loff_t offset,
56 round_down(offset, 1 << blkbits)) >> blkbits,
57 new_size, flags, mode);
64 @@ -4840,10 +4838,6 @@ static long ext4_zero_range(struct file *file, loff_t offset,
65 flags |= (EXT4_GET_BLOCKS_CONVERT_UNWRITTEN |
68 - /* Wait all existing dio workers, newcomers will block on i_mutex */
69 - ext4_inode_block_unlocked_dio(inode);
70 - inode_dio_wait(inode);
73 * Prevent page faults from reinstantiating pages we have
74 * released from page cache.
75 @@ -4988,8 +4982,13 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
79 + /* Wait all existing dio workers, newcomers will block on i_mutex */
80 + ext4_inode_block_unlocked_dio(inode);
81 + inode_dio_wait(inode);
83 ret = ext4_alloc_file_blocks(file, lblk, max_blocks, new_size,
85 + ext4_inode_resume_unlocked_dio(inode);
93 To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
94 the body of a message to majordomo@vger.kernel.org
95 More majordomo info at http://vger.kernel.org/majordomo-info.html