summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2019-02-11 13:30:32 -0500
committerBen Hutchings <ben@decadent.org.uk>2019-07-09 22:03:59 +0100
commit813b4ae11f6bd4a5efd88a82f061811baee60a7c (patch)
tree480de816927dc9b104a9609cd2594b4979e47f2b
parent96274e7dce62e69ea3233406043a3a0afdbba7c6 (diff)
downloadlinux-stable-813b4ae11f6bd4a5efd88a82f061811baee60a7c.tar.gz
linux-stable-813b4ae11f6bd4a5efd88a82f061811baee60a7c.tar.bz2
linux-stable-813b4ae11f6bd4a5efd88a82f061811baee60a7c.zip
ext4: fix crash during online resizing
commit f96c3ac8dfc24b4e38fc4c2eba5fea2107b929d1 upstream. When computing maximum size of filesystem possible with given number of group descriptor blocks, we forget to include s_first_data_block into the number of blocks. Thus for filesystems with non-zero s_first_data_block it can happen that computed maximum filesystem size is actually lower than current filesystem size which confuses the code and eventually leads to a BUG_ON in ext4_alloc_group_tables() hitting on flex_gd->count == 0. The problem can be reproduced like: truncate -s 100g /tmp/image mkfs.ext4 -b 1024 -E resize=262144 /tmp/image 32768 mount -t ext4 -o loop /tmp/image /mnt resize2fs /dev/loop0 262145 resize2fs /dev/loop0 300000 Fix the problem by properly including s_first_data_block into the computed number of filesystem blocks. Fixes: 1c6bd7173d66 "ext4: convert file system to meta_bg if needed..." Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Theodore Ts'o <tytso@mit.edu> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--fs/ext4/resize.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index b9d35d52889c..80c3f1ed1afa 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1931,7 +1931,8 @@ retry:
le16_to_cpu(es->s_reserved_gdt_blocks);
n_group = n_desc_blocks * EXT4_DESC_PER_BLOCK(sb);
n_blocks_count = (ext4_fsblk_t)n_group *
- EXT4_BLOCKS_PER_GROUP(sb);
+ EXT4_BLOCKS_PER_GROUP(sb) +
+ le32_to_cpu(es->s_first_data_block);
n_group--; /* set to last group number */
}