Final changes before pull request to Linus
[ext4-patch-queue.git] / move-unlocked-dio-protection-from-ext4_alloc_file_blocks
blob9f795dc0058303c07e975b4fbb8670e479c036f5
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>
16 ---
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);
32         /*
33          * credits to insert 1 extent into extent tree
34          */
35 @@ -4748,8 +4744,6 @@ retry:
36                 goto retry;
37         }
39 -       ext4_inode_resume_unlocked_dio(inode);
41         return ret > 0 ? ret2 : ret;
42  }
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);
58                 if (ret)
59 -                       goto out_mutex;
60 +                       goto out_dio;
62         }
64 @@ -4840,10 +4838,6 @@ static long ext4_zero_range(struct file *file, loff_t offset,
65                 flags |= (EXT4_GET_BLOCKS_CONVERT_UNWRITTEN |
66                           EXT4_EX_NOCACHE);
68 -               /* Wait all existing dio workers, newcomers will block on i_mutex */
69 -               ext4_inode_block_unlocked_dio(inode);
70 -               inode_dio_wait(inode);
72                 /*
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)
76                         goto out;
77         }
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,
84                                      flags, mode);
85 +       ext4_inode_resume_unlocked_dio(inode);
86         if (ret)
87                 goto out;
89 -- 
90 2.1.4
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