add patch enforce-regular-file-in-ext4_zero_range
[ext4-patch-queue.git] / factor-out-common-code-in-ext4_file_write
blob5df306a4526907e38d57216fc571c0629a82f172
1 ext4: factor out common code in ext4_file_write()
3 This shouldn't change any logic flow; just delete duplicated code.
5 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
6 Reviewed-by: Jan Kara <jack@suse.cz>
7 ---
8  fs/ext4/file.c | 58 ++++++++++++++++++++++------------------------------------
9  1 file changed, 22 insertions(+), 36 deletions(-)
11 diff --git a/fs/ext4/file.c b/fs/ext4/file.c
12 index 3ec0c09..4925c5a 100644
13 --- a/fs/ext4/file.c
14 +++ b/fs/ext4/file.c
15 @@ -97,8 +97,9 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
16  {
17         struct file *file = iocb->ki_filp;
18         struct inode *inode = file_inode(iocb->ki_filp);
19 +       struct mutex *aio_mutex = NULL;
20         struct blk_plug plug;
21 -       int unaligned_aio = 0;
22 +       int o_direct = file->f_flags & O_DIRECT;
23         int overwrite = 0;
24         size_t length = iov_length(iov, nr_segs);
25         ssize_t ret;
26 @@ -123,15 +124,13 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
27                 }
28         }
30 -       if (unlikely(iocb->ki_filp->f_flags & O_DIRECT)) {
31 -               if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) &&
32 -                   !is_sync_kiocb(iocb))
33 -                       unaligned_aio = ext4_unaligned_aio(inode, iov,
34 -                                                          nr_segs, pos);
36 +       if (o_direct) {
37                 /* Unaligned direct AIO must be serialized; see comment above */
38 -               if (unaligned_aio) {
39 -                       mutex_lock(ext4_aio_mutex(inode));
40 +               if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) &&
41 +                   !is_sync_kiocb(iocb) &&
42 +                   ext4_unaligned_aio(inode, iov, nr_segs, pos)) {
43 +                       aio_mutex = ext4_aio_mutex(inode);
44 +                       mutex_lock(aio_mutex);
45                         ext4_unwritten_wait(inode);
46                 }
48 @@ -141,7 +140,7 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
49                 iocb->private = &overwrite;
51                 /* check whether we do a DIO overwrite or not */
52 -               if (ext4_should_dioread_nolock(inode) && !unaligned_aio &&
53 +               if (ext4_should_dioread_nolock(inode) && !aio_mutex &&
54                     !file->f_mapping->nrpages && pos + length <= i_size_read(inode)) {
55                         struct ext4_map_blocks map;
56                         unsigned int blkbits = inode->i_blkbits;
57 @@ -168,37 +167,24 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
58                         if (err == len && (map.m_flags & EXT4_MAP_MAPPED))
59                                 overwrite = 1;
60                 }
62 -               ret = __generic_file_aio_write(iocb, iov, nr_segs,
63 -                                              &iocb->ki_pos);
64 -               mutex_unlock(&inode->i_mutex);
66 -               if (ret > 0) {
67 -                       ssize_t err;
69 -                       err = generic_write_sync(file, iocb->ki_pos - ret, ret);
70 -                       if (err < 0)
71 -                               ret = err;
72 -               }
73 -               blk_finish_plug(&plug);
75 -               if (unaligned_aio)
76 -                       mutex_unlock(ext4_aio_mutex(inode));
77 -       } else {
78 +       } else
79                 mutex_lock(&inode->i_mutex);
80 -               ret = __generic_file_aio_write(iocb, iov, nr_segs,
81 -                                              &iocb->ki_pos);
82 -               mutex_unlock(&inode->i_mutex);
84 -               if (ret > 0) {
85 -                       ssize_t err;
86 +       ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
87 +       mutex_unlock(&inode->i_mutex);
89 -                       err = generic_write_sync(file, iocb->ki_pos - ret, ret);
90 -                       if (err < 0)
91 -                               ret = err;
92 -               }
93 +       if (ret > 0) {
94 +               ssize_t err;
96 +               err = generic_write_sync(file, iocb->ki_pos - ret, ret);
97 +               if (err < 0)
98 +                       ret = err;
99         }
100 +       if (o_direct)
101 +               blk_finish_plug(&plug);
103 +       if (aio_mutex)
104 +               mutex_unlock(aio_mutex);
105         return ret;