Add patches to fix kernel crashes on corrupted file systems
[ext4-patch-queue.git] / reuse-path-object-in-ext4_move_extents
blob3f28009d1b7301e24b0e662357cf396382695e00
1 ext4: reuse path object in ext4_move_extents()
3 Reuse the path object in ext4_move_extents() so we don't unnecessarily
4 free and reallocate it.
6 Also clean up the get_ext_path() wrapper so that it has the same
7 semantics of freeing the path object on error as ext4_ext_find_extent().
9 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
10 ---
11  fs/ext4/move_extent.c | 27 ++++++++++++---------------
12  1 file changed, 12 insertions(+), 15 deletions(-)
14 diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
15 index a34c076..7bf970d 100644
16 --- a/fs/ext4/move_extent.c
17 +++ b/fs/ext4/move_extent.c
18 @@ -32,20 +32,21 @@
19   */
20  static inline int
21  get_ext_path(struct inode *inode, ext4_lblk_t lblock,
22 -               struct ext4_ext_path **orig_path)
23 +               struct ext4_ext_path **ppath)
24  {
25 -       int ret = 0;
26         struct ext4_ext_path *path;
28 -       path = ext4_ext_find_extent(inode, lblock, orig_path, EXT4_EX_NOCACHE);
29 +       path = ext4_ext_find_extent(inode, lblock, ppath, EXT4_EX_NOCACHE);
30         if (IS_ERR(path))
31 -               ret = PTR_ERR(path);
32 -       else if (path[ext_depth(inode)].p_ext == NULL)
33 -               ret = -ENODATA;
34 -       else
35 -               *orig_path = path;
37 -       return ret;
38 +               return PTR_ERR(path);
39 +       if (path[ext_depth(inode)].p_ext == NULL) {
40 +               ext4_ext_drop_refs(path);
41 +               kfree(path);
42 +               *ppath = NULL;
43 +               return -ENODATA;
44 +       }
45 +       *ppath = path;
46 +       return 0;
47  }
49  /**
50 @@ -667,7 +668,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk,
51                         }
52                         d_start += next_blk - o_start;
53                         o_start = next_blk;
54 -                       goto repeat;
55 +                       continue;
56                 /* Check hole after the start pos */
57                 } else if (cur_blk > o_start) {
58                         /* Skip hole */
59 @@ -708,10 +709,6 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk,
60                         break;
61                 o_start += cur_len;
62                 d_start += cur_len;
63 -       repeat:
64 -               ext4_ext_drop_refs(path);
65 -               kfree(path);
66 -               path = NULL;
67         }
68         *moved_len = o_start - orig_blk;
69         if (*moved_len > len)