add patch more-efficient-SEEK_DATA-implementation
[ext4-patch-queue.git] / factor-out-determining-of-hole-size
blob406d1cd56324a371a8f9bc10237b5c373f0a78ea
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>
13 ---
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,
22  }
24  /*
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
32 + *
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.
36 + *
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.
39   */
40 -static void
41 -ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path,
42 -                               ext4_lblk_t block)
43 +static ext4_lblk_t ext4_ext_determine_hole(struct inode *inode,
44 +                                          struct ext4_ext_path *path,
45 +                                          ext4_lblk_t *lblk)
46  {
47         int depth = ext_depth(inode);
48 -       ext4_lblk_t len;
49 -       ext4_lblk_t lblock;
50         struct ext4_extent *ex;
51 -       struct extent_status es;
52 +       ext4_lblk_t len;
54         ex = path[depth].p_ext;
55         if (ex == NULL) {
56                 /* there is no extent yet, so gap is [0;-] */
57 -               lblock = 0;
58 +               *lblk = 0;
59                 len = EXT_MAX_BLOCKS;
60 -               ext_debug("cache gap(whole file):");
61 -       } else if (block < le32_to_cpu(ex->ee_block)) {
62 -               lblock = block;
63 -               len = le32_to_cpu(ex->ee_block) - block;
64 -               ext_debug("cache gap(before): %u [%u:%u]",
65 -                               block,
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)) {
73                 ext4_lblk_t next;
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),
82 -                               block);
83 -               BUG_ON(next == lblock);
84 -               len = next - lblock;
85 +               BUG_ON(next == *lblk);
86 +               len = next - *lblk;
87         } else {
88                 BUG();
89         }
90 +       return len;
93 -       ext4_es_find_delayed_extent_range(inode, lblock, lblock + len - 1, &es);
94 +/*
95 + * ext4_ext_put_gap_in_cache:
96 + * calculate boundaries of the gap that the requested block fits into
97 + * and cache this gap
98 + */
99 +static void
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);
107         if (es.es_len) {
108                 /* There's delayed extent containing lblock? */
109 -               if (es.es_lblk <= lblock)
110 +               if (es.es_lblk <= hole_start)
111                         return;
112 -               len = min(es.es_lblk - lblock, len);
113 +               hole_len = min(es.es_lblk - hole_start, hole_len);
114         }
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);
122  /*
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
125          */
126         if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) {
127 +               ext4_lblk_t hole_start, hole_len;
129                 /*
130                  * put just found gap into cache to speed up
131                  * subsequent requests
132                  */
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);
137                 goto out2;
138         }
140 -- 
141 2.6.2