1 ext4: fix growing of tiny filesystems
3 From: Jan Kara <jack@suse.cz>
5 The estimate of necessary transaction credits in ext4_flex_group_add()
6 is too pessimistic. It reserves credit for sb, resize inode, and resize
7 inode dindirect block for each group added in a flex group although they
8 are always the same block and thus it is enough to account them only
9 once. Also the number of modified GDT block is overestimated since we
10 fit EXT4_DESC_PER_BLOCK(sb) descriptors in one block.
12 Make the estimation more precise. That reduces number of requested
13 credits enough that we can grow 20 MB filesystem (which has 1 MB
14 journal, 79 reserved GDT blocks, and flex group size 16 by default).
16 Signed-off-by: Jan Kara <jack@suse.cz>
17 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
18 Reviewed-by: Eric Sandeen <sandeen@redhat.com>
20 fs/ext4/resize.c | 7 +++++--
21 1 file changed, 5 insertions(+), 2 deletions(-)
23 diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
24 index 8a8ec62..cf0c472 100644
25 --- a/fs/ext4/resize.c
26 +++ b/fs/ext4/resize.c
27 @@ -1432,12 +1432,15 @@ static int ext4_flex_group_add(struct super_block *sb,
30 * We will always be modifying at least the superblock and GDT
31 - * block. If we are adding a group past the last current GDT block,
32 + * blocks. If we are adding a group past the last current GDT block,
33 * we will also modify the inode and the dindirect block. If we
34 * are adding a group with superblock/GDT backups we will also
35 * modify each of the reserved GDT dindirect blocks.
37 - credit = flex_gd->count * 4 + reserved_gdb;
38 + credit = 3; /* sb, resize inode, resize inode dindirect */
40 + credit += 1 + DIV_ROUND_UP(flex_gd->count, EXT4_DESC_PER_BLOCK(sb));
41 + credit += reserved_gdb; /* Reserved GDT dindirect blocks */
42 handle = ext4_journal_start_sb(sb, EXT4_HT_RESIZE, credit);
44 err = PTR_ERR(handle);