add patch move-error-report-out-of-atomic-context
[ext4-patch-queue.git] / drop-EXT4_EX_NOFREE_ON_ERR-from-rest-of-extents-code
blob9af13bad9910e38230ffc3c96c3fb0744594de6b
1 ext4: drop EXT4_EX_NOFREE_ON_ERR from rest of extents handling code
3 Drop EXT4_EX_NOFREE_ON_ERR from ext4_ext_create_new_leaf(),
4 ext4_split_extent(), ext4_convert_unwritten_extents_endio().
6 This requires fixing all of their callers to potentially
7 ext4_ext_find_extent() to free the struct ext4_ext_path object in case
8 of an error, and there are interlocking dependencies all the way up to
9 ext4_ext_map_blocks(), ext4_swap_extents(), and
10 ext4_ext_remove_space().
12 Once this is done, we can drop the EXT4_EX_NOFREE_ON_ERR flag since it
13 is no longer necessary.
15 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
17 ---
18  fs/ext4/ext4.h    |   3 +-
19  fs/ext4/extents.c | 112 ++++++++++++++++++++++++++++++++-------------------------------
20  fs/ext4/migrate.c |   2 +-
21  3 files changed, 59 insertions(+), 58 deletions(-)
23 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
24 index 696e51a..4a5a6b9 100644
25 --- a/fs/ext4/ext4.h
26 +++ b/fs/ext4/ext4.h
27 @@ -582,7 +582,6 @@ enum {
28   */
29  #define EXT4_EX_NOCACHE                                0x0800
30  #define EXT4_EX_FORCE_CACHE                    0x1000
31 -#define EXT4_EX_NOFREE_ON_ERR                  0x2000
33  /*
34   * Flags used by ext4_free_blocks
35 @@ -2731,7 +2730,7 @@ extern int ext4_can_extents_be_merged(struct inode *inode,
36                                       struct ext4_extent *ex1,
37                                       struct ext4_extent *ex2);
38  extern int ext4_ext_insert_extent(handle_t *, struct inode *,
39 -                                 struct ext4_ext_path *,
40 +                                 struct ext4_ext_path **,
41                                   struct ext4_extent *, int);
42  extern struct ext4_ext_path *ext4_ext_find_extent(struct inode *, ext4_lblk_t,
43                                                   struct ext4_ext_path **,
44 diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
45 index acb92ac..ccdd2af 100644
46 --- a/fs/ext4/extents.c
47 +++ b/fs/ext4/extents.c
48 @@ -98,14 +98,14 @@ static void ext4_extent_block_csum_set(struct inode *inode,
50  static int ext4_split_extent(handle_t *handle,
51                                 struct inode *inode,
52 -                               struct ext4_ext_path *path,
53 +                               struct ext4_ext_path **ppath,
54                                 struct ext4_map_blocks *map,
55                                 int split_flag,
56                                 int flags);
58  static int ext4_split_extent_at(handle_t *handle,
59                              struct inode *inode,
60 -                            struct ext4_ext_path *path,
61 +                            struct ext4_ext_path **ppath,
62                              ext4_lblk_t split,
63                              int split_flag,
64                              int flags);
65 @@ -293,12 +293,13 @@ static inline int ext4_ext_space_root_idx(struct inode *inode, int check)
67  static inline int
68  ext4_force_split_extent_at(handle_t *handle, struct inode *inode,
69 -                          struct ext4_ext_path *path, ext4_lblk_t lblk,
70 +                          struct ext4_ext_path **ppath, ext4_lblk_t lblk,
71                            int nofail)
72  {
73 +       struct ext4_ext_path *path = *ppath;
74         int unwritten = ext4_ext_is_unwritten(path[path->p_depth].p_ext);
76 -       return ext4_split_extent_at(handle, inode, path, lblk, unwritten ?
77 +       return ext4_split_extent_at(handle, inode, ppath, lblk, unwritten ?
78                         EXT4_EXT_MARK_UNWRIT1|EXT4_EXT_MARK_UNWRIT2 : 0,
79                         EXT4_EX_NOCACHE | EXT4_GET_BLOCKS_PRE_IO |
80                         (nofail ? EXT4_GET_BLOCKS_METADATA_NOFAIL:0));
81 @@ -861,7 +862,6 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block,
82         struct buffer_head *bh;
83         struct ext4_ext_path *path = orig_path ? *orig_path : NULL;
84         short int depth, i, ppos = 0;
85 -       short free_on_err = (flags & EXT4_EX_NOFREE_ON_ERR) == 0;
86         int ret;
88         eh = ext_inode_hdr(inode);
89 @@ -873,7 +873,6 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block,
90                                 GFP_NOFS);
91                 if (unlikely(!path))
92                         return ERR_PTR(-ENOMEM);
93 -               free_on_err = 1;
94         }
95         path[0].p_hdr = eh;
96         path[0].p_bh = NULL;
97 @@ -925,11 +924,9 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block,
99  err:
100         ext4_ext_drop_refs(path);
101 -       if (free_on_err) {
102 -               kfree(path);
103 -               if (orig_path)
104 -                       *orig_path = NULL;
105 -       }
106 +       kfree(path);
107 +       if (orig_path)
108 +               *orig_path = NULL;
109         return ERR_PTR(ret);
112 @@ -1332,9 +1329,10 @@ out:
113  static int ext4_ext_create_new_leaf(handle_t *handle, struct inode *inode,
114                                     unsigned int mb_flags,
115                                     unsigned int gb_flags,
116 -                                   struct ext4_ext_path *path,
117 +                                   struct ext4_ext_path **ppath,
118                                     struct ext4_extent *newext)
120 +       struct ext4_ext_path *path = *ppath;
121         struct ext4_ext_path *curp;
122         int depth, i, err = 0;
124 @@ -1361,7 +1359,7 @@ repeat:
125                 ext4_ext_drop_refs(path);
126                 path = ext4_ext_find_extent(inode,
127                                     (ext4_lblk_t)le32_to_cpu(newext->ee_block),
128 -                                   &path, gb_flags | EXT4_EX_NOFREE_ON_ERR);
129 +                                   ppath, gb_flags);
130                 if (IS_ERR(path))
131                         err = PTR_ERR(path);
132         } else {
133 @@ -1374,7 +1372,7 @@ repeat:
134                 ext4_ext_drop_refs(path);
135                 path = ext4_ext_find_extent(inode,
136                                    (ext4_lblk_t)le32_to_cpu(newext->ee_block),
137 -                                   &path, gb_flags | EXT4_EX_NOFREE_ON_ERR);
138 +                                   ppath, gb_flags);
139                 if (IS_ERR(path)) {
140                         err = PTR_ERR(path);
141                         goto out;
142 @@ -1914,9 +1912,10 @@ out:
143   * creating new leaf in the no-space case.
144   */
145  int ext4_ext_insert_extent(handle_t *handle, struct inode *inode,
146 -                               struct ext4_ext_path *path,
147 +                               struct ext4_ext_path **ppath,
148                                 struct ext4_extent *newext, int gb_flags)
150 +       struct ext4_ext_path *path = *ppath;
151         struct ext4_extent_header *eh;
152         struct ext4_extent *ex, *fex;
153         struct ext4_extent *nearex; /* nearest extent */
154 @@ -2048,7 +2047,7 @@ prepend:
155         if (gb_flags & EXT4_GET_BLOCKS_METADATA_NOFAIL)
156                 mb_flags = EXT4_MB_USE_RESERVED;
157         err = ext4_ext_create_new_leaf(handle, inode, mb_flags, gb_flags,
158 -                                      path, newext);
159 +                                      ppath, newext);
160         if (err)
161                 goto cleanup;
162         depth = ext_depth(inode);
163 @@ -2878,7 +2877,7 @@ again:
164                          * fail removing space due to ENOSPC so try to use
165                          * reserved block if that happens.
166                          */
167 -                       err = ext4_force_split_extent_at(handle, inode, path,
168 +                       err = ext4_force_split_extent_at(handle, inode, &path,
169                                                          end + 1, 1);
170                         if (err < 0)
171                                 goto out;
172 @@ -3019,12 +3018,13 @@ again:
173                 }
174         }
175  out:
176 -       ext4_ext_drop_refs(path);
177 -       kfree(path);
178 -       if (err == -EAGAIN) {
179 +       if (path) {
180 +               ext4_ext_drop_refs(path);
181 +               kfree(path);
182                 path = NULL;
183 -               goto again;
184         }
185 +       if (err == -EAGAIN)
186 +               goto again;
187         ext4_journal_stop(handle);
189         return err;
190 @@ -3138,11 +3138,12 @@ static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex)
191   */
192  static int ext4_split_extent_at(handle_t *handle,
193                              struct inode *inode,
194 -                            struct ext4_ext_path *path,
195 +                            struct ext4_ext_path **ppath,
196                              ext4_lblk_t split,
197                              int split_flag,
198                              int flags)
200 +       struct ext4_ext_path *path = *ppath;
201         ext4_fsblk_t newblock;
202         ext4_lblk_t ee_block;
203         struct ext4_extent *ex, newex, orig_ex, zero_ex;
204 @@ -3213,7 +3214,7 @@ static int ext4_split_extent_at(handle_t *handle,
205         if (split_flag & EXT4_EXT_MARK_UNWRIT2)
206                 ext4_ext_mark_unwritten(ex2);
208 -       err = ext4_ext_insert_extent(handle, inode, path, &newex, flags);
209 +       err = ext4_ext_insert_extent(handle, inode, ppath, &newex, flags);
210         if (err == -ENOSPC && (EXT4_EXT_MAY_ZEROOUT & split_flag)) {
211                 if (split_flag & (EXT4_EXT_DATA_VALID1|EXT4_EXT_DATA_VALID2)) {
212                         if (split_flag & EXT4_EXT_DATA_VALID1) {
213 @@ -3279,11 +3280,12 @@ fix_extent_len:
214   */
215  static int ext4_split_extent(handle_t *handle,
216                               struct inode *inode,
217 -                             struct ext4_ext_path *path,
218 +                             struct ext4_ext_path **ppath,
219                               struct ext4_map_blocks *map,
220                               int split_flag,
221                               int flags)
223 +       struct ext4_ext_path *path = *ppath;
224         ext4_lblk_t ee_block;
225         struct ext4_extent *ex;
226         unsigned int ee_len, depth;
227 @@ -3306,7 +3308,7 @@ static int ext4_split_extent(handle_t *handle,
228                                        EXT4_EXT_MARK_UNWRIT2;
229                 if (split_flag & EXT4_EXT_DATA_VALID2)
230                         split_flag1 |= EXT4_EXT_DATA_VALID1;
231 -               err = ext4_split_extent_at(handle, inode, path,
232 +               err = ext4_split_extent_at(handle, inode, ppath,
233                                 map->m_lblk + map->m_len, split_flag1, flags1);
234                 if (err)
235                         goto out;
236 @@ -3318,8 +3320,7 @@ static int ext4_split_extent(handle_t *handle,
237          * result in split of original leaf or extent zeroout.
238          */
239         ext4_ext_drop_refs(path);
240 -       path = ext4_ext_find_extent(inode, map->m_lblk, &path,
241 -                                   EXT4_EX_NOFREE_ON_ERR);
242 +       path = ext4_ext_find_extent(inode, map->m_lblk, ppath, 0);
243         if (IS_ERR(path))
244                 return PTR_ERR(path);
245         depth = ext_depth(inode);
246 @@ -3339,7 +3340,7 @@ static int ext4_split_extent(handle_t *handle,
247                         split_flag1 |= split_flag & (EXT4_EXT_MAY_ZEROOUT |
248                                                      EXT4_EXT_MARK_UNWRIT2);
249                 }
250 -               err = ext4_split_extent_at(handle, inode, path,
251 +               err = ext4_split_extent_at(handle, inode, ppath,
252                                 map->m_lblk, split_flag1, flags);
253                 if (err)
254                         goto out;
255 @@ -3373,9 +3374,10 @@ out:
256  static int ext4_ext_convert_to_initialized(handle_t *handle,
257                                            struct inode *inode,
258                                            struct ext4_map_blocks *map,
259 -                                          struct ext4_ext_path *path,
260 +                                          struct ext4_ext_path **ppath,
261                                            int flags)
263 +       struct ext4_ext_path *path = *ppath;
264         struct ext4_sb_info *sbi;
265         struct ext4_extent_header *eh;
266         struct ext4_map_blocks split_map;
267 @@ -3599,7 +3601,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
268                 }
269         }
271 -       allocated = ext4_split_extent(handle, inode, path,
272 +       allocated = ext4_split_extent(handle, inode, ppath,
273                                       &split_map, split_flag, flags);
274         if (allocated < 0)
275                 err = allocated;
276 @@ -3638,9 +3640,10 @@ out:
277  static int ext4_split_convert_extents(handle_t *handle,
278                                         struct inode *inode,
279                                         struct ext4_map_blocks *map,
280 -                                       struct ext4_ext_path *path,
281 +                                       struct ext4_ext_path **ppath,
282                                         int flags)
284 +       struct ext4_ext_path *path = *ppath;
285         ext4_lblk_t eof_block;
286         ext4_lblk_t ee_block;
287         struct ext4_extent *ex;
288 @@ -3674,14 +3677,15 @@ static int ext4_split_convert_extents(handle_t *handle,
289                 split_flag |= (EXT4_EXT_MARK_UNWRIT2 | EXT4_EXT_DATA_VALID2);
290         }
291         flags |= EXT4_GET_BLOCKS_PRE_IO;
292 -       return ext4_split_extent(handle, inode, path, map, split_flag, flags);
293 +       return ext4_split_extent(handle, inode, ppath, map, split_flag, flags);
296  static int ext4_convert_unwritten_extents_endio(handle_t *handle,
297                                                 struct inode *inode,
298                                                 struct ext4_map_blocks *map,
299 -                                               struct ext4_ext_path *path)
300 +                                               struct ext4_ext_path **ppath)
302 +       struct ext4_ext_path *path = *ppath;
303         struct ext4_extent *ex;
304         ext4_lblk_t ee_block;
305         unsigned int ee_len;
306 @@ -3710,17 +3714,14 @@ static int ext4_convert_unwritten_extents_endio(handle_t *handle,
307                              inode->i_ino, (unsigned long long)ee_block, ee_len,
308                              (unsigned long long)map->m_lblk, map->m_len);
309  #endif
310 -               err = ext4_split_convert_extents(handle, inode, map, path,
311 +               err = ext4_split_convert_extents(handle, inode, map, ppath,
312                                                  EXT4_GET_BLOCKS_CONVERT);
313                 if (err < 0)
314 -                       goto out;
315 +                       return err;
316                 ext4_ext_drop_refs(path);
317 -               path = ext4_ext_find_extent(inode, map->m_lblk, &path,
318 -                                           EXT4_EX_NOFREE_ON_ERR);
319 -               if (IS_ERR(path)) {
320 -                       err = PTR_ERR(path);
321 -                       goto out;
322 -               }
323 +               path = ext4_ext_find_extent(inode, map->m_lblk, ppath, 0);
324 +               if (IS_ERR(path))
325 +                       return PTR_ERR(path);
326                 depth = ext_depth(inode);
327                 ex = path[depth].p_ext;
328         }
329 @@ -3942,7 +3943,7 @@ convert_initialized_extent(handle_t *handle, struct inode *inode,
330                   (unsigned long long)ee_block, ee_len);
332         if (ee_block != map->m_lblk || ee_len > map->m_len) {
333 -               err = ext4_split_convert_extents(handle, inode, map, path,
334 +               err = ext4_split_convert_extents(handle, inode, map, ppath,
335                                 EXT4_GET_BLOCKS_CONVERT_UNWRITTEN);
336                 if (err < 0)
337                         return err;
338 @@ -3990,9 +3991,10 @@ convert_initialized_extent(handle_t *handle, struct inode *inode,
339  static int
340  ext4_ext_handle_unwritten_extents(handle_t *handle, struct inode *inode,
341                         struct ext4_map_blocks *map,
342 -                       struct ext4_ext_path *path, int flags,
343 +                       struct ext4_ext_path **ppath, int flags,
344                         unsigned int allocated, ext4_fsblk_t newblock)
346 +       struct ext4_ext_path *path = *ppath;
347         int ret = 0;
348         int err = 0;
349         ext4_io_end_t *io = ext4_inode_aio(inode);
350 @@ -4014,8 +4016,8 @@ ext4_ext_handle_unwritten_extents(handle_t *handle, struct inode *inode,
352         /* get_block() before submit the IO, split the extent */
353         if (flags & EXT4_GET_BLOCKS_PRE_IO) {
354 -               ret = ext4_split_convert_extents(handle, inode, map,
355 -                                        path, flags | EXT4_GET_BLOCKS_CONVERT);
356 +               ret = ext4_split_convert_extents(handle, inode, map, ppath,
357 +                                        flags | EXT4_GET_BLOCKS_CONVERT);
358                 if (ret <= 0)
359                         goto out;
360                 /*
361 @@ -4033,7 +4035,7 @@ ext4_ext_handle_unwritten_extents(handle_t *handle, struct inode *inode,
362         /* IO end_io complete, convert the filled extent to written */
363         if (flags & EXT4_GET_BLOCKS_CONVERT) {
364                 ret = ext4_convert_unwritten_extents_endio(handle, inode, map,
365 -                                                       path);
366 +                                                          ppath);
367                 if (ret >= 0) {
368                         ext4_update_inode_fsync_trans(handle, inode, 1);
369                         err = check_eofblocks_fl(handle, inode, map->m_lblk,
370 @@ -4071,7 +4073,7 @@ ext4_ext_handle_unwritten_extents(handle_t *handle, struct inode *inode,
371         }
373         /* buffered write, writepage time, convert*/
374 -       ret = ext4_ext_convert_to_initialized(handle, inode, map, path, flags);
375 +       ret = ext4_ext_convert_to_initialized(handle, inode, map, ppath, flags);
376         if (ret >= 0)
377                 ext4_update_inode_fsync_trans(handle, inode, 1);
378  out:
379 @@ -4332,7 +4334,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
380                                 goto out;
382                         ret = ext4_ext_handle_unwritten_extents(
383 -                               handle, inode, map, path, flags,
384 +                               handle, inode, map, &path, flags,
385                                 allocated, newblock);
386                         if (ret < 0)
387                                 err = ret;
388 @@ -4479,7 +4481,7 @@ got_allocated_blocks:
389                 err = check_eofblocks_fl(handle, inode, map->m_lblk,
390                                          path, ar.len);
391         if (!err)
392 -               err = ext4_ext_insert_extent(handle, inode, path,
393 +               err = ext4_ext_insert_extent(handle, inode, &path,
394                                              &newex, flags);
396         if (!err && set_unwritten) {
397 @@ -5611,18 +5613,18 @@ ext4_swap_extents(handle_t *handle, struct inode *inode1,
398                 if (e1_blk < lblk1) {
399                         split = 1;
400                         *erp = ext4_force_split_extent_at(handle, inode1,
401 -                                               path1, lblk1, 0);
402 +                                               &path1, lblk1, 0);
403                         if (unlikely(*erp))
404                                 goto finish;
405                 }
406                 if (e2_blk < lblk2) {
407                         split = 1;
408                         *erp = ext4_force_split_extent_at(handle, inode2,
409 -                                               path2,  lblk2, 0);
410 +                                               &path2,  lblk2, 0);
411                         if (unlikely(*erp))
412                                 goto finish;
413                 }
414 -               /* ext4_split_extent_at() may retult in leaf extent split,
415 +               /* ext4_split_extent_at() may result in leaf extent split,
416                  * path must to be revalidated. */
417                 if (split)
418                         goto repeat;
419 @@ -5637,18 +5639,18 @@ ext4_swap_extents(handle_t *handle, struct inode *inode1,
420                 if (len != e1_len) {
421                         split = 1;
422                         *erp = ext4_force_split_extent_at(handle, inode1,
423 -                                               path1, lblk1 + len, 0);
424 +                                               &path1, lblk1 + len, 0);
425                         if (unlikely(*erp))
426                                 goto finish;
427                 }
428                 if (len != e2_len) {
429                         split = 1;
430                         *erp = ext4_force_split_extent_at(handle, inode2,
431 -                                               path2, lblk2 + len, 0);
432 +                                               &path2, lblk2 + len, 0);
433                         if (*erp)
434                                 goto finish;
435                 }
436 -               /* ext4_split_extent_at() may retult in leaf extent split,
437 +               /* ext4_split_extent_at() may result in leaf extent split,
438                  * path must to be revalidated. */
439                 if (split)
440                         goto repeat;
441 diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
442 index d3567f2..aff7bdf 100644
443 --- a/fs/ext4/migrate.c
444 +++ b/fs/ext4/migrate.c
445 @@ -81,7 +81,7 @@ static int finish_range(handle_t *handle, struct inode *inode,
446                                 goto err_out;
447                 }
448         }
449 -       retval = ext4_ext_insert_extent(handle, inode, path, &newext, 0);
450 +       retval = ext4_ext_insert_extent(handle, inode, &path, &newext, 0);
451  err_out:
452         up_write((&EXT4_I(inode)->i_data_sem));
453         if (path) {