add patch drop-unneeded-BUFFER_TRACE-in-ext4_delete_inline_entry
[ext4-patch-queue.git] / move-trans-handling-and-completion-deferal-out-of-_ext4_get_block
blobe230ec54620b9ab4bf600516c4a08e4ef6ecda4d
1 ext4: move trans handling and completion deferal out of _ext4_get_block
3 From: Jan Kara <jack@suse.cz>
5 There is no need to handle starting of a transaction and deferal of DIO
6 completion in _ext4_get_block() function. We can move this out to get
7 block functions for direct IO that need it. That way we can add stricter
8 checks verifying things work as we expect.
10 Signed-off-by: Jan Kara <jack@suse.cz>
11 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
12 ---
13  fs/ext4/inode.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
14  1 file changed, 59 insertions(+), 32 deletions(-)
16 diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
17 index bf545d0..aea67d9 100644
18 --- a/fs/ext4/inode.c
19 +++ b/fs/ext4/inode.c
20 @@ -714,16 +714,11 @@ static void ext4_update_bh_state(struct buffer_head *bh, unsigned long flags)
21                  cmpxchg(&bh->b_state, old_state, new_state) != old_state));
22  }
24 -/* Maximum number of blocks we map for direct IO at once. */
25 -#define DIO_MAX_BLOCKS 4096
27  static int _ext4_get_block(struct inode *inode, sector_t iblock,
28                            struct buffer_head *bh, int flags)
29  {
30 -       handle_t *handle = ext4_journal_current_handle();
31         struct ext4_map_blocks map;
32 -       int ret = 0, started = 0;
33 -       int dio_credits;
34 +       int ret = 0;
36         if (ext4_has_inline_data(inode))
37                 return -ERANGE;
38 @@ -731,33 +726,14 @@ static int _ext4_get_block(struct inode *inode, sector_t iblock,
39         map.m_lblk = iblock;
40         map.m_len = bh->b_size >> inode->i_blkbits;
42 -       if (flags && !handle) {
43 -               /* Direct IO write... */
44 -               if (map.m_len > DIO_MAX_BLOCKS)
45 -                       map.m_len = DIO_MAX_BLOCKS;
46 -               dio_credits = ext4_chunk_trans_blocks(inode, map.m_len);
47 -               handle = ext4_journal_start(inode, EXT4_HT_MAP_BLOCKS,
48 -                                           dio_credits);
49 -               if (IS_ERR(handle)) {
50 -                       ret = PTR_ERR(handle);
51 -                       return ret;
52 -               }
53 -               started = 1;
54 -       }
56 -       ret = ext4_map_blocks(handle, inode, &map, flags);
57 +       ret = ext4_map_blocks(ext4_journal_current_handle(), inode, &map,
58 +                             flags);
59         if (ret > 0) {
60 -               ext4_io_end_t *io_end = ext4_inode_aio(inode);
62                 map_bh(bh, inode->i_sb, map.m_pblk);
63                 ext4_update_bh_state(bh, map.m_flags);
64 -               if (io_end && io_end->flag & EXT4_IO_END_UNWRITTEN)
65 -                       set_buffer_defer_completion(bh);
66                 bh->b_size = inode->i_sb->s_blocksize * map.m_len;
67                 ret = 0;
68         }
69 -       if (started)
70 -               ext4_journal_stop(handle);
71         return ret;
72  }
74 @@ -782,12 +758,42 @@ int ext4_get_block_unwritten(struct inode *inode, sector_t iblock,
75                                EXT4_GET_BLOCKS_IO_CREATE_EXT);
76  }
78 +/* Maximum number of blocks we map for direct IO at once. */
79 +#define DIO_MAX_BLOCKS 4096
81 +static handle_t *start_dio_trans(struct inode *inode,
82 +                                struct buffer_head *bh_result)
84 +       int dio_credits;
86 +       /* Trim mapping request to maximum we can map at once for DIO */
87 +       if (bh_result->b_size >> inode->i_blkbits > DIO_MAX_BLOCKS)
88 +               bh_result->b_size = DIO_MAX_BLOCKS << inode->i_blkbits;
89 +       dio_credits = ext4_chunk_trans_blocks(inode,
90 +                                     bh_result->b_size >> inode->i_blkbits);
91 +       return ext4_journal_start(inode, EXT4_HT_MAP_BLOCKS, dio_credits);
94  /* Get block function for DIO reads and writes to inodes without extents */
95  int ext4_dio_get_block(struct inode *inode, sector_t iblock,
96                        struct buffer_head *bh, int create)
97  {
98 -       return _ext4_get_block(inode, iblock, bh,
99 -                              create ? EXT4_GET_BLOCKS_CREATE : 0);
100 +       handle_t *handle;
101 +       int ret;
103 +       /* We don't expect handle for direct IO */
104 +       WARN_ON_ONCE(ext4_journal_current_handle());
106 +       if (create) {
107 +               handle = start_dio_trans(inode, bh);
108 +               if (IS_ERR(handle))
109 +                       return PTR_ERR(handle);
110 +       }
111 +       ret = _ext4_get_block(inode, iblock, bh,
112 +                             create ? EXT4_GET_BLOCKS_CREATE : 0);
113 +       if (create)
114 +               ext4_journal_stop(handle);
115 +       return ret;
118  /*
119 @@ -798,10 +804,28 @@ int ext4_dio_get_block(struct inode *inode, sector_t iblock,
120  static int ext4_dio_get_block_unwritten(struct inode *inode, sector_t iblock,
121                         struct buffer_head *bh_result, int create)
123 +       handle_t *handle;
124 +       int ret;
126         ext4_debug("ext4_dio_get_block_unwritten: inode %lu, create flag %d\n",
127                    inode->i_ino, create);
128 -       return _ext4_get_block(inode, iblock, bh_result,
129 -                              EXT4_GET_BLOCKS_IO_CREATE_EXT);
130 +       /* We don't expect handle for direct IO */
131 +       WARN_ON_ONCE(ext4_journal_current_handle());
133 +       handle = start_dio_trans(inode, bh_result);
134 +       if (IS_ERR(handle))
135 +               return PTR_ERR(handle);
136 +       ret = _ext4_get_block(inode, iblock, bh_result,
137 +                             EXT4_GET_BLOCKS_IO_CREATE_EXT);
138 +       ext4_journal_stop(handle);
139 +       if (!ret && buffer_unwritten(bh_result)) {
140 +               ext4_io_end_t *io_end = ext4_inode_aio(inode);
142 +               set_buffer_defer_completion(bh_result);
143 +               WARN_ON_ONCE(io_end && !(io_end->flag & EXT4_IO_END_UNWRITTEN));
144 +       }
146 +       return ret;
149  static int ext4_dio_get_block_overwrite(struct inode *inode, sector_t iblock,
150 @@ -811,12 +835,15 @@ static int ext4_dio_get_block_overwrite(struct inode *inode, sector_t iblock,
152         ext4_debug("ext4_dio_get_block_overwrite: inode %lu, create flag %d\n",
153                    inode->i_ino, create);
154 +       /* We don't expect handle for direct IO */
155 +       WARN_ON_ONCE(ext4_journal_current_handle());
157         ret = _ext4_get_block(inode, iblock, bh_result, 0);
158         /*
159          * Blocks should have been preallocated! ext4_file_write_iter() checks
160          * that.
161          */
162 -       WARN_ON_ONCE(!buffer_mapped(bh_result));
163 +       WARN_ON_ONCE(!buffer_mapped(bh_result) || buffer_unwritten(bh_result));
165         return ret;