aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/extents.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r--fs/ext4/extents.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 7844bbb2bac0..dabc3b68d249 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -248,6 +248,36 @@ static int ext4_ext_space_root_idx(struct inode *inode)
248 return size; 248 return size;
249} 249}
250 250
251/*
252 * Calculate the number of metadata blocks needed
253 * to allocate @blocks
254 * Worse case is one block per extent
255 */
256int ext4_ext_calc_metadata_amount(struct inode *inode, int blocks)
257{
258 int lcap, icap, rcap, leafs, idxs, num;
259 int newextents = blocks;
260
261 rcap = ext4_ext_space_root_idx(inode);
262 lcap = ext4_ext_space_block(inode);
263 icap = ext4_ext_space_block_idx(inode);
264
265 /* number of new leaf blocks needed */
266 num = leafs = (newextents + lcap - 1) / lcap;
267
268 /*
269 * Worse case, we need separate index block(s)
270 * to link all new leaf blocks
271 */
272 idxs = (leafs + icap - 1) / icap;
273 do {
274 num += idxs;
275 idxs = (idxs + icap - 1) / icap;
276 } while (idxs > rcap);
277
278 return num;
279}
280
251static int 281static int
252ext4_ext_max_entries(struct inode *inode, int depth) 282ext4_ext_max_entries(struct inode *inode, int depth)
253{ 283{
@@ -2910,7 +2940,7 @@ retry:
2910 } 2940 }
2911 ret = ext4_get_blocks_wrap(handle, inode, block, 2941 ret = ext4_get_blocks_wrap(handle, inode, block,
2912 max_blocks, &map_bh, 2942 max_blocks, &map_bh,
2913 EXT4_CREATE_UNINITIALIZED_EXT, 0); 2943 EXT4_CREATE_UNINITIALIZED_EXT, 0, 0);
2914 if (ret <= 0) { 2944 if (ret <= 0) {
2915#ifdef EXT4FS_DEBUG 2945#ifdef EXT4FS_DEBUG
2916 WARN_ON(ret <= 0); 2946 WARN_ON(ret <= 0);