add patch drop-unneeded-BUFFER_TRACE-in-ext4_delete_inline_entry
[ext4-patch-queue.git] / use-i_mutex-to-serialize-unaligned-AIO-DIO
blobb30ec28aca425f6c4a34bee7006e2cab51e2e260
1 ext4: use i_mutex to serialize unaligned AIO DIO
3 From: Jan Kara <jack@suse.cz>
5 Currently we've used hashed aio_mutex to serialize unaligned AIO DIO.
6 However the code cleanups that happened after 2011 when the lock was
7 introduced made aio_mutex acquired at almost the same places where we
8 already have exclusion using i_mutex. So just use i_mutex for the
9 exclusion of unaligned AIO DIO.
11 The change moves waiting for pending unwritten extent conversion under
12 i_mutex. That makes special handling of O_APPEND writes unnecessary and
13 also avoids possible livelocking of unaligned AIO DIO with aligned one
14 (nothing was preventing contiguous stream of aligned AIO DIOs to let
15 unaligned AIO DIO wait forever).
17 Signed-off-by: Jan Kara <jack@suse.cz>
18 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
19 ---
20  fs/ext4/ext4.h  |  3 ---
21  fs/ext4/file.c  | 32 +++++++++++++-------------------
22  fs/ext4/super.c |  5 +----
23  3 files changed, 14 insertions(+), 26 deletions(-)
25 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
26 index 1046621ef64d..b02b2e58805a 100644
27 --- a/fs/ext4/ext4.h
28 +++ b/fs/ext4/ext4.h
29 @@ -3284,10 +3284,7 @@ static inline void ext4_inode_resume_unlocked_dio(struct inode *inode)
30  #define EXT4_WQ_HASH_SZ                37
31  #define ext4_ioend_wq(v)   (&ext4__ioend_wq[((unsigned long)(v)) %\
32                                             EXT4_WQ_HASH_SZ])
33 -#define ext4_aio_mutex(v)  (&ext4__aio_mutex[((unsigned long)(v)) %\
34 -                                            EXT4_WQ_HASH_SZ])
35  extern wait_queue_head_t ext4__ioend_wq[EXT4_WQ_HASH_SZ];
36 -extern struct mutex ext4__aio_mutex[EXT4_WQ_HASH_SZ];
38  #define EXT4_RESIZING  0
39  extern int ext4_resize_begin(struct super_block *sb);
40 diff --git a/fs/ext4/file.c b/fs/ext4/file.c
41 index 1126436dada1..7d5fb122fd26 100644
42 --- a/fs/ext4/file.c
43 +++ b/fs/ext4/file.c
44 @@ -93,31 +93,29 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
45  {
46         struct file *file = iocb->ki_filp;
47         struct inode *inode = file_inode(iocb->ki_filp);
48 -       struct mutex *aio_mutex = NULL;
49         struct blk_plug plug;
50         int o_direct = iocb->ki_flags & IOCB_DIRECT;
51 +       int unaligned_aio = 0;
52         int overwrite = 0;
53         ssize_t ret;
55 +       inode_lock(inode);
56 +       ret = generic_write_checks(iocb, from);
57 +       if (ret <= 0)
58 +               goto out;
60         /*
61 -        * Unaligned direct AIO must be serialized; see comment above
62 -        * In the case of O_APPEND, assume that we must always serialize
63 +        * Unaligned direct AIO must be serialized among each other as zeroing
64 +        * of partial blocks of two competing unaligned AIOs can result in data
65 +        * corruption.
66          */
67 -       if (o_direct &&
68 -           ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) &&
69 +       if (o_direct && ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) &&
70             !is_sync_kiocb(iocb) &&
71 -           (iocb->ki_flags & IOCB_APPEND ||
72 -            ext4_unaligned_aio(inode, from, iocb->ki_pos))) {
73 -               aio_mutex = ext4_aio_mutex(inode);
74 -               mutex_lock(aio_mutex);
75 +           ext4_unaligned_aio(inode, from, iocb->ki_pos)) {
76 +               unaligned_aio = 1;
77                 ext4_unwritten_wait(inode);
78         }
80 -       inode_lock(inode);
81 -       ret = generic_write_checks(iocb, from);
82 -       if (ret <= 0)
83 -               goto out;
85         /*
86          * If we have encountered a bitmap-format file, the size limit
87          * is smaller than s_maxbytes, which is for extent-mapped files.
88 @@ -139,7 +137,7 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
89                 blk_start_plug(&plug);
91                 /* check whether we do a DIO overwrite or not */
92 -               if (ext4_should_dioread_nolock(inode) && !aio_mutex &&
93 +               if (ext4_should_dioread_nolock(inode) && !unaligned_aio &&
94                     !file->f_mapping->nrpages && pos + length <= i_size_read(inode)) {
95                         struct ext4_map_blocks map;
96                         unsigned int blkbits = inode->i_blkbits;
97 @@ -181,14 +179,10 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
98         if (o_direct)
99                 blk_finish_plug(&plug);
101 -       if (aio_mutex)
102 -               mutex_unlock(aio_mutex);
103         return ret;
105  out:
106         inode_unlock(inode);
107 -       if (aio_mutex)
108 -               mutex_unlock(aio_mutex);
109         return ret;
112 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
113 index 3ed01ec011d7..6d8a01b4f535 100644
114 --- a/fs/ext4/super.c
115 +++ b/fs/ext4/super.c
116 @@ -5321,7 +5321,6 @@ MODULE_ALIAS_FS("ext4");
118  /* Shared across all ext4 file systems */
119  wait_queue_head_t ext4__ioend_wq[EXT4_WQ_HASH_SZ];
120 -struct mutex ext4__aio_mutex[EXT4_WQ_HASH_SZ];
122  static int __init ext4_init_fs(void)
124 @@ -5334,10 +5333,8 @@ static int __init ext4_init_fs(void)
125         /* Build-time check for flags consistency */
126         ext4_check_flag_values();
128 -       for (i = 0; i < EXT4_WQ_HASH_SZ; i++) {
129 -               mutex_init(&ext4__aio_mutex[i]);
130 +       for (i = 0; i < EXT4_WQ_HASH_SZ; i++)
131                 init_waitqueue_head(&ext4__ioend_wq[i]);
132 -       }
134         err = ext4_init_es();
135         if (err)
136 -- 
137 2.6.2