Clean up typo in patch but remove it for now.
[ext4-patch-queue.git] / cache-extent-hole-in-extent-status-tree-for-ext4_da_map_blocks
blobdde6c1f9f8d1696628f941f6c8e6a15f557970eb
1 ext4: cache extent hole in extent status tree for ext4_da_map_blocks()
3 From: Zheng Liu <wenqing.lz@taobao.com>
5 Currently extent status tree doesn't cache extent hole when a write
6 looks up in extent tree to make sure whether a block has been allocated
7 or not.  In this case, we don't put extent hole in extent cache because
8 later this extent might be removed and a new delayed extent might be
9 added back.  But it will cause a defect when we do a lot of writes.  If
10 we don't put extent hole in extent cache, the following writes also need
11 to access extent tree to look at whether or not a block has been
12 allocated.  It brings a cache miss.  This commit fixes this defect.
13 Also if the inode doesn't have any extent, this extent hole will be
14 cached as well.
16 Cc: Andreas Dilger <adilger.kernel@dilger.ca>
17 Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
18 Signed-off-by: Jan Kara <jack@suse.cz>
19 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
20 ---
21  fs/ext4/ext4.h              |  4 +---
22  fs/ext4/extents.c           | 31 ++++++++++++++++---------------
23  fs/ext4/inode.c             |  6 ++----
24  include/trace/events/ext4.h |  3 +--
25  4 files changed, 20 insertions(+), 24 deletions(-)
27 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
28 index 7b3f3b1..98da4cd 100644
29 --- a/fs/ext4/ext4.h
30 +++ b/fs/ext4/ext4.h
31 @@ -556,10 +556,8 @@ enum {
32  #define EXT4_GET_BLOCKS_KEEP_SIZE              0x0080
33         /* Do not take i_data_sem locking in ext4_map_blocks */
34  #define EXT4_GET_BLOCKS_NO_LOCK                        0x0100
35 -       /* Do not put hole in extent cache */
36 -#define EXT4_GET_BLOCKS_NO_PUT_HOLE            0x0200
37         /* Convert written extents to unwritten */
38 -#define EXT4_GET_BLOCKS_CONVERT_UNWRITTEN      0x0400
39 +#define EXT4_GET_BLOCKS_CONVERT_UNWRITTEN      0x0200
41  /*
42   * The bit position of these flags must not overlap with any of the
43 diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
44 index 7ef2f11..1ee24d7 100644
45 --- a/fs/ext4/extents.c
46 +++ b/fs/ext4/extents.c
47 @@ -2306,16 +2306,16 @@ ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path,
48                                 ext4_lblk_t block)
49  {
50         int depth = ext_depth(inode);
51 -       unsigned long len = 0;
52 -       ext4_lblk_t lblock = 0;
53 +       ext4_lblk_t len;
54 +       ext4_lblk_t lblock;
55         struct ext4_extent *ex;
56 +       struct extent_status es;
58         ex = path[depth].p_ext;
59         if (ex == NULL) {
60 -               /*
61 -                * there is no extent yet, so gap is [0;-] and we
62 -                * don't cache it
63 -                */
64 +               /* there is no extent yet, so gap is [0;-] */
65 +               lblock = 0;
66 +               len = EXT_MAX_BLOCKS;
67                 ext_debug("cache gap(whole file):");
68         } else if (block < le32_to_cpu(ex->ee_block)) {
69                 lblock = block;
70 @@ -2324,9 +2324,6 @@ ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path,
71                                 block,
72                                 le32_to_cpu(ex->ee_block),
73                                  ext4_ext_get_actual_len(ex));
74 -               if (!ext4_find_delalloc_range(inode, lblock, lblock + len - 1))
75 -                       ext4_es_insert_extent(inode, lblock, len, ~0,
76 -                                             EXTENT_STATUS_HOLE);
77         } else if (block >= le32_to_cpu(ex->ee_block)
78                         + ext4_ext_get_actual_len(ex)) {
79                 ext4_lblk_t next;
80 @@ -2340,14 +2337,19 @@ ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path,
81                                 block);
82                 BUG_ON(next == lblock);
83                 len = next - lblock;
84 -               if (!ext4_find_delalloc_range(inode, lblock, lblock + len - 1))
85 -                       ext4_es_insert_extent(inode, lblock, len, ~0,
86 -                                             EXTENT_STATUS_HOLE);
87         } else {
88                 BUG();
89         }
91 -       ext_debug(" -> %u:%lu\n", lblock, len);
92 +       ext4_es_find_delayed_extent_range(inode, lblock, lblock + len - 1, &es);
93 +       if (es.es_len) {
94 +               /* There's delayed extent containing lblock? */
95 +               if (es.es_lblk <= lblock)
96 +                       return;
97 +               len = min(es.es_lblk - lblock, len);
98 +       }
99 +       ext_debug(" -> %u:%u\n", lblock, len);
100 +       ext4_es_insert_extent(inode, lblock, len, ~0, EXTENT_STATUS_HOLE);
103  /*
104 @@ -4368,8 +4370,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
105                  * put just found gap into cache to speed up
106                  * subsequent requests
107                  */
108 -               if ((flags & EXT4_GET_BLOCKS_NO_PUT_HOLE) == 0)
109 -                       ext4_ext_put_gap_in_cache(inode, path, map->m_lblk);
110 +               ext4_ext_put_gap_in_cache(inode, path, map->m_lblk);
111                 goto out2;
112         }
114 diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
115 index ddd8e43..7bd272f 100644
116 --- a/fs/ext4/inode.c
117 +++ b/fs/ext4/inode.c
118 @@ -1432,11 +1432,9 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock,
119         if (ext4_has_inline_data(inode))
120                 retval = 0;
121         else if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
122 -               retval = ext4_ext_map_blocks(NULL, inode, map,
123 -                                            EXT4_GET_BLOCKS_NO_PUT_HOLE);
124 +               retval = ext4_ext_map_blocks(NULL, inode, map, 0);
125         else
126 -               retval = ext4_ind_map_blocks(NULL, inode, map,
127 -                                            EXT4_GET_BLOCKS_NO_PUT_HOLE);
128 +               retval = ext4_ind_map_blocks(NULL, inode, map, 0);
130  add_delayed:
131         if (retval == 0) {
132 diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
133 index 06343e1..d71b00d3 100644
134 --- a/include/trace/events/ext4.h
135 +++ b/include/trace/events/ext4.h
136 @@ -43,8 +43,7 @@ struct extent_status;
137         { EXT4_GET_BLOCKS_METADATA_NOFAIL,      "METADATA_NOFAIL" },    \
138         { EXT4_GET_BLOCKS_NO_NORMALIZE,         "NO_NORMALIZE" },       \
139         { EXT4_GET_BLOCKS_KEEP_SIZE,            "KEEP_SIZE" },          \
140 -       { EXT4_GET_BLOCKS_NO_LOCK,              "NO_LOCK" },            \
141 -       { EXT4_GET_BLOCKS_NO_PUT_HOLE,          "NO_PUT_HOLE" })
142 +       { EXT4_GET_BLOCKS_NO_LOCK,              "NO_LOCK" })
144  #define show_mflags(flags) __print_flags(flags, "",    \
145         { EXT4_MAP_NEW,         "N" },                  \