add patch fold-ext4_sync_fs_nojournal
[ext4-patch-queue.git] / cache-extent-hole-in-extent-status-tree-for-ext4_da_map_blocks
blob7f14cc9491d1d7152cd0336f5f998e649b81a2e8
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.
10 If we don't put extent hole in extent cache, the following writes also
11 need 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 Meanwhile, if an inode has no any extent, this extent hole also will
14 be cached.
16 Cc: Andreas Dilger <adilger.kernel@dilger.ca>
17 Cc: Jan Kara <jack@suse.cz>
18 Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
19 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
20 ---
21  fs/ext4/ext4.h              |    4 +---
22  fs/ext4/extents.c           |   23 +++++++++--------------
23  fs/ext4/inode.c             |    6 ++----
24  include/trace/events/ext4.h |    3 +--
25  4 files changed, 13 insertions(+), 23 deletions(-)
27 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
28 index 6f294d3..7df9220 100644
29 --- a/fs/ext4/ext4.h
30 +++ b/fs/ext4/ext4.h
31 @@ -565,10 +565,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 76c2df3..6463d34 100644
45 --- a/fs/ext4/extents.c
46 +++ b/fs/ext4/extents.c
47 @@ -2284,16 +2284,15 @@ 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 +       unsigned long len;
54 +       ext4_lblk_t lblock;
55         struct ext4_extent *ex;
57         ex = path[depth].p_ext;
58         if (ex == NULL) {
59 -               /*
60 -                * there is no extent yet, so gap is [0;-] and we
61 -                * don't cache it
62 -                */
63 +               /* there is no extent yet, so gap is [0;-] */
64 +               lblock = 0;
65 +               len = EXT_MAX_BLOCKS;
66                 ext_debug("cache gap(whole file):");
67         } else if (block < le32_to_cpu(ex->ee_block)) {
68                 lblock = block;
69 @@ -2302,9 +2301,6 @@ ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path,
70                                 block,
71                                 le32_to_cpu(ex->ee_block),
72                                  ext4_ext_get_actual_len(ex));
73 -               if (!ext4_find_delalloc_range(inode, lblock, lblock + len - 1))
74 -                       ext4_es_insert_extent(inode, lblock, len, ~0,
75 -                                             EXTENT_STATUS_HOLE);
76         } else if (block >= le32_to_cpu(ex->ee_block)
77                         + ext4_ext_get_actual_len(ex)) {
78                 ext4_lblk_t next;
79 @@ -2318,14 +2314,14 @@ ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path,
80                                 block);
81                 BUG_ON(next == lblock);
82                 len = next - lblock;
83 -               if (!ext4_find_delalloc_range(inode, lblock, lblock + len - 1))
84 -                       ext4_es_insert_extent(inode, lblock, len, ~0,
85 -                                             EXTENT_STATUS_HOLE);
86         } else {
87                 BUG();
88         }
90         ext_debug(" -> %u:%lu\n", lblock, len);
91 +       if (!ext4_find_delalloc_range(inode, lblock, lblock + len - 1))
92 +               ext4_es_insert_extent(inode, lblock, len, ~0,
93 +                                     EXTENT_STATUS_HOLE);
94  }
96  /*
97 @@ -4362,8 +4358,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
98                  * put just found gap into cache to speed up
99                  * subsequent requests
100                  */
101 -               if ((flags & EXT4_GET_BLOCKS_NO_PUT_HOLE) == 0)
102 -                       ext4_ext_put_gap_in_cache(inode, path, map->m_lblk);
103 +               ext4_ext_put_gap_in_cache(inode, path, map->m_lblk);
104                 goto out2;
105         }
107 diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
108 index 367a60c..d1ad9f9 100644
109 --- a/fs/ext4/inode.c
110 +++ b/fs/ext4/inode.c
111 @@ -1485,11 +1485,9 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock,
112                         map->m_flags |= EXT4_MAP_FROM_CLUSTER;
113                 retval = 0;
114         } else if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
115 -               retval = ext4_ext_map_blocks(NULL, inode, map,
116 -                                            EXT4_GET_BLOCKS_NO_PUT_HOLE);
117 +               retval = ext4_ext_map_blocks(NULL, inode, map, 0);
118         else
119 -               retval = ext4_ind_map_blocks(NULL, inode, map,
120 -                                            EXT4_GET_BLOCKS_NO_PUT_HOLE);
121 +               retval = ext4_ind_map_blocks(NULL, inode, map, 0);
123  add_delayed:
124         if (retval == 0) {
125 diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
126 index ff4bd1b..9337d36 100644
127 --- a/include/trace/events/ext4.h
128 +++ b/include/trace/events/ext4.h
129 @@ -43,8 +43,7 @@ struct extent_status;
130         { EXT4_GET_BLOCKS_METADATA_NOFAIL,      "METADATA_NOFAIL" },    \
131         { EXT4_GET_BLOCKS_NO_NORMALIZE,         "NO_NORMALIZE" },       \
132         { EXT4_GET_BLOCKS_KEEP_SIZE,            "KEEP_SIZE" },          \
133 -       { EXT4_GET_BLOCKS_NO_LOCK,              "NO_LOCK" },            \
134 -       { EXT4_GET_BLOCKS_NO_PUT_HOLE,          "NO_PUT_HOLE" })
135 +       { EXT4_GET_BLOCKS_NO_LOCK,              "NO_LOCK" })
137  #define show_mflags(flags) __print_flags(flags, "",    \
138         { EXT4_MAP_NEW,         "N" },                  \
139 -- 
140 1.7.9.7