1 ext4: teach ext4_ext_find_extent() to realloc path if necessary
3 This adds additional safety in case for some reason we end reusing a
4 path structure which isn't big enough for current depth of the inode.
6 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
7 diff --git a/fs/ext4/ext4_extents.h b/fs/ext4/ext4_extents.h
8 index a867f5c..3c93815 100644
9 --- a/fs/ext4/ext4_extents.h
10 +++ b/fs/ext4/ext4_extents.h
11 @@ -123,6 +123,7 @@ find_ext4_extent_tail(struct ext4_extent_header *eh)
12 struct ext4_ext_path {
16 struct ext4_extent *p_ext;
17 struct ext4_extent_idx *p_idx;
18 struct ext4_extent_header *p_hdr;
19 diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
20 index d3fe3b2..ecd86e0 100644
21 --- a/fs/ext4/extents.c
22 +++ b/fs/ext4/extents.c
23 @@ -861,14 +861,20 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block,
24 eh = ext_inode_hdr(inode);
25 depth = ext_depth(inode);
29 ext4_ext_drop_refs(path);
31 + if (depth > path[0].p_maxdepth) {
33 + *orig_path = path = NULL;
37 /* account possible depth increase */
38 path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 2),
41 return ERR_PTR(-ENOMEM);
42 + path[0].p_maxdepth = depth + 1;
46 @@ -1812,6 +1818,7 @@ static void ext4_ext_try_to_merge_up(handle_t *handle,
47 sizeof(struct ext4_extent_idx);
48 s += sizeof(struct ext4_extent_header);
50 + path[1].p_maxdepth = path[0].p_maxdepth;
51 memcpy(path[0].p_hdr, path[1].p_hdr, s);
53 path[0].p_ext = EXT_FIRST_EXTENT(path[0].p_hdr) +
54 @@ -2142,12 +2149,6 @@ static int ext4_fill_fiemap_extents(struct inode *inode,
55 /* find extent for this block */
56 down_read(&EXT4_I(inode)->i_data_sem);
58 - if (path && ext_depth(inode) != depth) {
59 - /* depth was changed. we have to realloc path */
64 path = ext4_ext_find_extent(inode, block, &path, 0);
66 up_read(&EXT4_I(inode)->i_data_sem);
67 @@ -2165,7 +2166,6 @@ static int ext4_fill_fiemap_extents(struct inode *inode,
69 ex = path[depth].p_ext;
70 next = ext4_ext_next_allocated_block(path);
71 - ext4_ext_drop_refs(path);
75 @@ -2889,7 +2889,7 @@ again:
76 ext4_journal_stop(handle);
79 - path[0].p_depth = depth;
80 + path[0].p_maxdepth = path[0].p_depth = depth;
81 path[0].p_hdr = ext_inode_hdr(inode);