reenable fix-races-between-changing-journal-mode-and-ext4_writepages
[ext4-patch-queue.git] / do-not-ask-jbd2-to-write-data-for-delalloc-buffers
blob1f9efd99cbf656f6a7887b7226643082ca2df9f6
1 From: Jan Kara <jack@suse.cz>
3 ext4: do not ask jbd2 to write data for delalloc buffers
5 Currently we ask jbd2 to write all dirty allocated buffers before
6 committing a transaction when doing writeback of delay allocated blocks.
7 However this is unnecessary since we move all pages to writeback state
8 before dropping a transaction handle and then submit all the necessary
9 IO. We still need the transaction commit to wait for all the outstanding
10 writeback before flushing disk caches during transaction commit to avoid
11 data exposure issues though. Use the new jbd2 capability and ask it to
12 only wait for outstanding writeback during transaction commit when
13 writing back data in ext4_writepages().
15 Tested-by: "HUANG Weller (CM/ESW12-CN)" <Weller.Huang@cn.bosch.com>
16 Signed-off-by: Jan Kara <jack@suse.cz>
17 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
18 ---
19  fs/ext4/ext4.h        |  3 +++
20  fs/ext4/ext4_jbd2.h   | 12 +++++++++++-
21  fs/ext4/inode.c       | 10 +++++++---
22  fs/ext4/move_extent.c |  2 +-
23  4 files changed, 22 insertions(+), 5 deletions(-)
25 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
26 index 8647d1253903..118bd14c1c20 100644
27 --- a/fs/ext4/ext4.h
28 +++ b/fs/ext4/ext4.h
29 @@ -581,6 +581,9 @@ enum {
30  #define EXT4_GET_BLOCKS_ZERO                   0x0200
31  #define EXT4_GET_BLOCKS_CREATE_ZERO            (EXT4_GET_BLOCKS_CREATE |\
32                                         EXT4_GET_BLOCKS_ZERO)
33 +       /* Caller will submit data before dropping transaction handle. This
34 +        * allows jbd2 to avoid submitting data before commit. */
35 +#define EXT4_GET_BLOCKS_IO_SUBMIT              0x0400
37  /*
38   * The bit position of these flags must not overlap with any of the
39 diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h
40 index f1c940b38b30..09c1ef38cbe6 100644
41 --- a/fs/ext4/ext4_jbd2.h
42 +++ b/fs/ext4/ext4_jbd2.h
43 @@ -359,7 +359,8 @@ static inline int ext4_journal_force_commit(journal_t *journal)
44         return 0;
45  }
47 -static inline int ext4_jbd2_file_inode(handle_t *handle, struct inode *inode)
48 +static inline int ext4_jbd2_inode_add_write(handle_t *handle,
49 +                                           struct inode *inode)
50  {
51         if (ext4_handle_valid(handle))
52                 return jbd2_journal_inode_add_write(handle,
53 @@ -367,6 +368,15 @@ static inline int ext4_jbd2_file_inode(handle_t *handle, struct inode *inode)
54         return 0;
55  }
57 +static inline int ext4_jbd2_inode_add_wait(handle_t *handle,
58 +                                          struct inode *inode)
60 +       if (ext4_handle_valid(handle))
61 +               return jbd2_journal_inode_add_wait(handle,
62 +                                                  EXT4_I(inode)->jinode);
63 +       return 0;
66  static inline void ext4_update_inode_fsync_trans(handle_t *handle,
67                                                  struct inode *inode,
68                                                  int datasync)
69 diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
70 index 8ffba0ec3b80..58e05feb999f 100644
71 --- a/fs/ext4/inode.c
72 +++ b/fs/ext4/inode.c
73 @@ -694,7 +694,10 @@ out_sem:
74                     !(map->m_flags & EXT4_MAP_UNWRITTEN) &&
75                     !(flags & EXT4_GET_BLOCKS_ZERO) &&
76                     ext4_should_order_data(inode)) {
77 -                       ret = ext4_jbd2_file_inode(handle, inode);
78 +                       if (flags & EXT4_GET_BLOCKS_IO_SUBMIT)
79 +                               ret = ext4_jbd2_inode_add_wait(handle, inode);
80 +                       else
81 +                               ret = ext4_jbd2_inode_add_write(handle, inode);
82                         if (ret)
83                                 return ret;
84                 }
85 @@ -2320,7 +2323,8 @@ static int mpage_map_one_extent(handle_t *handle, struct mpage_da_data *mpd)
86          * the data was copied into the page cache.
87          */
88         get_blocks_flags = EXT4_GET_BLOCKS_CREATE |
89 -                          EXT4_GET_BLOCKS_METADATA_NOFAIL;
90 +                          EXT4_GET_BLOCKS_METADATA_NOFAIL |
91 +                          EXT4_GET_BLOCKS_IO_SUBMIT;
92         dioread_nolock = ext4_should_dioread_nolock(inode);
93         if (dioread_nolock)
94                 get_blocks_flags |= EXT4_GET_BLOCKS_IO_CREATE_EXT;
95 @@ -3635,7 +3639,7 @@ static int __ext4_block_zero_page_range(handle_t *handle,
96                 err = 0;
97                 mark_buffer_dirty(bh);
98                 if (ext4_should_order_data(inode))
99 -                       err = ext4_jbd2_file_inode(handle, inode);
100 +                       err = ext4_jbd2_inode_add_write(handle, inode);
101         }
103  unlock:
104 diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
105 index 4098acc701c3..93e9635bc65e 100644
106 --- a/fs/ext4/move_extent.c
107 +++ b/fs/ext4/move_extent.c
108 @@ -400,7 +400,7 @@ data_copy:
110         /* Even in case of data=writeback it is reasonable to pin
111          * inode to transaction, to prevent unexpected data loss */
112 -       *err = ext4_jbd2_file_inode(handle, orig_inode);
113 +       *err = ext4_jbd2_inode_add_write(handle, orig_inode);
115  unlock_pages:
116         unlock_page(pagep[0]);
117 -- 
118 2.6.2