1 ext4: better estimate credits needed for ext4_da_writepages()
3 From: Jan Kara <jack@suse.cz>
5 We limit the number of blocks written in a single loop of
6 ext4_da_writepages() to 64 when inode uses indirect blocks. That is
7 unnecessary as credit estimates for mapping logically continguous run
8 of blocks is rather low even for inode with indirect blocks. So just
9 lift this limitation and properly calculate the number of necessary
12 This better credit estimate will also later allow us to always write
13 at least a single page in one iteration.
15 Reviewed-by: Zheng Liu <wenqing.lz@taobao.com>
16 Signed-off-by: Jan Kara <jack@suse.cz>
17 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
19 fs/ext4/ext4.h | 3 +--
20 fs/ext4/extents.c | 16 +++++++---------
21 fs/ext4/inode.c | 62 +++++++++++++++++++++++++++-----------------------------------
22 3 files changed, 35 insertions(+), 46 deletions(-)
24 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
25 index 25e261d..2ebfcde 100644
28 @@ -2596,8 +2596,7 @@ struct ext4_extent;
30 extern int ext4_ext_tree_init(handle_t *handle, struct inode *);
31 extern int ext4_ext_writepage_trans_blocks(struct inode *, int);
32 -extern int ext4_ext_index_trans_blocks(struct inode *inode, int nrblocks,
34 +extern int ext4_ext_index_trans_blocks(struct inode *inode, int extents);
35 extern int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
36 struct ext4_map_blocks *map, int flags);
37 extern void ext4_ext_truncate(handle_t *, struct inode *);
38 diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
39 index 299ee9d..94283d0 100644
40 --- a/fs/ext4/extents.c
41 +++ b/fs/ext4/extents.c
42 @@ -2328,17 +2328,15 @@ int ext4_ext_calc_credits_for_single_extent(struct inode *inode, int nrblocks,
46 - * How many index/leaf blocks need to change/allocate to modify nrblocks?
47 + * How many index/leaf blocks need to change/allocate to add @extents extents?
49 - * if nrblocks are fit in a single extent (chunk flag is 1), then
50 - * in the worse case, each tree level index/leaf need to be changed
51 - * if the tree split due to insert a new extent, then the old tree
52 - * index/leaf need to be updated too
53 + * If we add a single extent, then in the worse case, each tree level
54 + * index/leaf need to be changed in case of the tree split.
56 - * If the nrblocks are discontiguous, they could cause
57 - * the whole tree split more than once, but this is really rare.
58 + * If more extents are inserted, they could cause the whole tree split more
59 + * than once, but this is really rare.
61 -int ext4_ext_index_trans_blocks(struct inode *inode, int nrblocks, int chunk)
62 +int ext4_ext_index_trans_blocks(struct inode *inode, int extents)
66 @@ -2349,7 +2347,7 @@ int ext4_ext_index_trans_blocks(struct inode *inode, int nrblocks, int chunk)
68 depth = ext_depth(inode);
75 diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
76 index 23d9a44..2b777e5 100644
79 @@ -136,6 +136,8 @@ static void ext4_invalidatepage(struct page *page, unsigned int offset,
81 static int __ext4_journalled_writepage(struct page *page, unsigned int len);
82 static int ext4_bh_delay_or_unwritten(handle_t *handle, struct buffer_head *bh);
83 +static int ext4_meta_trans_blocks(struct inode *inode, int lblocks,
87 * Test whether an inode is a fast symlink.
88 @@ -2203,28 +2205,25 @@ static int ext4_writepage(struct page *page,
92 - * This is called via ext4_da_writepages() to
93 - * calculate the total number of credits to reserve to fit
94 - * a single extent allocation into a single transaction,
95 - * ext4_da_writpeages() will loop calling this before
96 - * the block allocation.
97 + * mballoc gives us at most this number of blocks...
98 + * XXX: That seems to be only a limitation of ext4_mb_normalize_request().
99 + * The rest of mballoc seems to handle chunks upto full group size.
101 +#define MAX_WRITEPAGES_EXTENT_LEN 2048
104 + * Calculate the total number of credits to reserve for one writepages
105 + * iteration. This is called from ext4_da_writepages(). We map an extent of
106 + * upto MAX_WRITEPAGES_EXTENT_LEN blocks and then we go on and finish mapping
107 + * the last partial page. So in total we can map MAX_WRITEPAGES_EXTENT_LEN +
108 + * bpp - 1 blocks in bpp different extents.
110 static int ext4_da_writepages_trans_blocks(struct inode *inode)
112 - int max_blocks = EXT4_I(inode)->i_reserved_data_blocks;
115 - * With non-extent format the journal credit needed to
116 - * insert nrblocks contiguous block is dependent on
117 - * number of contiguous block. So we will limit
118 - * number of contiguous block to a sane value
120 - if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) &&
121 - (max_blocks > EXT4_MAX_TRANS_DATA))
122 - max_blocks = EXT4_MAX_TRANS_DATA;
123 + int bpp = ext4_journal_blocks_per_page(inode);
125 - return ext4_chunk_trans_blocks(inode, max_blocks);
126 + return ext4_meta_trans_blocks(inode,
127 + MAX_WRITEPAGES_EXTENT_LEN + bpp - 1, bpp);
131 @@ -4650,11 +4649,12 @@ int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry,
135 -static int ext4_index_trans_blocks(struct inode *inode, int nrblocks, int chunk)
136 +static int ext4_index_trans_blocks(struct inode *inode, int lblocks,
139 if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
140 - return ext4_ind_trans_blocks(inode, nrblocks);
141 - return ext4_ext_index_trans_blocks(inode, nrblocks, chunk);
142 + return ext4_ind_trans_blocks(inode, lblocks);
143 + return ext4_ext_index_trans_blocks(inode, pextents);
147 @@ -4668,7 +4668,8 @@ static int ext4_index_trans_blocks(struct inode *inode, int nrblocks, int chunk)
149 * Also account for superblock, inode, quota and xattr blocks
151 -static int ext4_meta_trans_blocks(struct inode *inode, int nrblocks, int chunk)
152 +static int ext4_meta_trans_blocks(struct inode *inode, int lblocks,
155 ext4_group_t groups, ngroups = ext4_get_groups_count(inode->i_sb);
157 @@ -4676,14 +4677,10 @@ static int ext4_meta_trans_blocks(struct inode *inode, int nrblocks, int chunk)
161 - * How many index blocks need to touch to modify nrblocks?
162 - * The "Chunk" flag indicating whether the nrblocks is
163 - * physically contiguous on disk
165 - * For Direct IO and fallocate, they calls get_block to allocate
166 - * one single extent at a time, so they could set the "Chunk" flag
167 + * How many index blocks need to touch to map @lblocks logical blocks
168 + * to @pextents physical extents?
170 - idxblocks = ext4_index_trans_blocks(inode, nrblocks, chunk);
171 + idxblocks = ext4_index_trans_blocks(inode, lblocks, pextents);
175 @@ -4691,12 +4688,7 @@ static int ext4_meta_trans_blocks(struct inode *inode, int nrblocks, int chunk)
176 * Now let's see how many group bitmaps and group descriptors need
179 - groups = idxblocks;
183 - groups += nrblocks;
185 + groups = idxblocks + pextents;
187 if (groups > ngroups)
189 @@ -4727,7 +4719,7 @@ int ext4_writepage_trans_blocks(struct inode *inode)
190 int bpp = ext4_journal_blocks_per_page(inode);
193 - ret = ext4_meta_trans_blocks(inode, bpp, 0);
194 + ret = ext4_meta_trans_blocks(inode, bpp, bpp);
196 /* Account for data blocks for journalled mode */
197 if (ext4_should_journal_data(inode))