1 ext4: factor out determining of hole size
3 From: Jan Kara <jack@suse.cz>
5 ext4_ext_put_gap_in_cache() determines hole size in the extent tree,
6 then trims this with possible delayed allocated blocks, and inserts the
7 result into the extent status tree. Factor out determination of the size
8 of the hole in the extent tree as we will need this information in
9 ext4_ext_map_blocks() as well.
11 Signed-off-by: Jan Kara <jack@suse.cz>
12 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
14 fs/ext4/extents.c | 80 ++++++++++++++++++++++++++++++++-----------------------
15 1 file changed, 47 insertions(+), 33 deletions(-)
17 diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
18 index 3753ceb0b0dd..2dc6261e247f 100644
19 --- a/fs/ext4/extents.c
20 +++ b/fs/ext4/extents.c
21 @@ -2293,59 +2293,69 @@ static int ext4_fill_fiemap_extents(struct inode *inode,
25 - * ext4_ext_put_gap_in_cache:
26 - * calculate boundaries of the gap that the requested block fits into
27 - * and cache this gap
28 + * ext4_ext_determine_hole - determine hole around given block
29 + * @inode: inode we lookup in
30 + * @path: path in extent tree to @lblk
31 + * @lblk: pointer to logical block around which we want to determine hole
33 + * Determine hole length (and start if easily possible) around given logical
34 + * block. We don't try too hard to find the beginning of the hole but @path
35 + * actually points to extent before @lblk, we provide it.
37 + * The function returns the length of a hole starting at @lblk. We update @lblk
38 + * to the beginning of the hole if we managed to find it.
41 -ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path,
43 +static ext4_lblk_t ext4_ext_determine_hole(struct inode *inode,
44 + struct ext4_ext_path *path,
47 int depth = ext_depth(inode);
50 struct ext4_extent *ex;
51 - struct extent_status es;
54 ex = path[depth].p_ext;
56 /* there is no extent yet, so gap is [0;-] */
60 - ext_debug("cache gap(whole file):");
61 - } else if (block < le32_to_cpu(ex->ee_block)) {
63 - len = le32_to_cpu(ex->ee_block) - block;
64 - ext_debug("cache gap(before): %u [%u:%u]",
66 - le32_to_cpu(ex->ee_block),
67 - ext4_ext_get_actual_len(ex));
68 - } else if (block >= le32_to_cpu(ex->ee_block)
69 + } else if (*lblk < le32_to_cpu(ex->ee_block)) {
70 + len = le32_to_cpu(ex->ee_block) - *lblk;
71 + } else if (*lblk >= le32_to_cpu(ex->ee_block)
72 + ext4_ext_get_actual_len(ex)) {
74 - lblock = le32_to_cpu(ex->ee_block)
75 - + ext4_ext_get_actual_len(ex);
77 + *lblk = le32_to_cpu(ex->ee_block) + ext4_ext_get_actual_len(ex);
78 next = ext4_ext_next_allocated_block(path);
79 - ext_debug("cache gap(after): [%u:%u] %u",
80 - le32_to_cpu(ex->ee_block),
81 - ext4_ext_get_actual_len(ex),
83 - BUG_ON(next == lblock);
84 - len = next - lblock;
85 + BUG_ON(next == *lblk);
93 - ext4_es_find_delayed_extent_range(inode, lblock, lblock + len - 1, &es);
95 + * ext4_ext_put_gap_in_cache:
96 + * calculate boundaries of the gap that the requested block fits into
97 + * and cache this gap
100 +ext4_ext_put_gap_in_cache(struct inode *inode, ext4_lblk_t hole_start,
101 + ext4_lblk_t hole_len)
103 + struct extent_status es;
105 + ext4_es_find_delayed_extent_range(inode, hole_start,
106 + hole_start + hole_len - 1, &es);
108 /* There's delayed extent containing lblock? */
109 - if (es.es_lblk <= lblock)
110 + if (es.es_lblk <= hole_start)
112 - len = min(es.es_lblk - lblock, len);
113 + hole_len = min(es.es_lblk - hole_start, hole_len);
115 - ext_debug(" -> %u:%u\n", lblock, len);
116 - ext4_es_insert_extent(inode, lblock, len, ~0, EXTENT_STATUS_HOLE);
117 + ext_debug(" -> %u:%u\n", hole_start, hole_len);
118 + ext4_es_insert_extent(inode, hole_start, hole_len, ~0,
119 + EXTENT_STATUS_HOLE);
123 @@ -4368,11 +4378,15 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
124 * we couldn't try to create block if create flag is zero
126 if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) {
127 + ext4_lblk_t hole_start, hole_len;
130 * put just found gap into cache to speed up
131 * subsequent requests
133 - ext4_ext_put_gap_in_cache(inode, path, map->m_lblk);
134 + hole_start = map->m_lblk;
135 + hole_len = ext4_ext_determine_hole(inode, path, &hole_start);
136 + ext4_ext_put_gap_in_cache(inode, hole_start, hole_len);