Online resizing of filesystem mounted with backup superblock causes corruption
# mkfs.ext4 /dev/loop0 100M # adjust if necessary, should be less than partition size
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729
(pick one)
# mount -t ext4 -o sb=40961 /dev/loop0 /media/ # resize2fs /dev/loop0 resize2fs 1.42.12 (29-Aug-2014) Filesystem at /dev/loop0 is mounted on /media; on-line resizing required old_desc_blocks = 1, new_desc_blocks = 4
Now, depending on your luck, various things may happen. resize2fs may hang. You might see BUG() in your dmesg. Either way, system will become severely corrupted (as indicated by fsck). You won't be able to mount it, either.
[ 2669.510800] EXT4-fs (loop0): resizing filesystem from 128000 to 256000 blocks [ 2669.513558] EXT4-fs warning (device loop0): reserve_backup_gdb:969: reserved block 32770 not at offset 1 [ 2669.513569] EXT4-fs (loop0): resized filesystem to 256000 [ 2669.516328] EXT4-fs warning (device loop0): ext4_group_extend:1734:
can't shrink FS - resize aborted
Signature · 2 lines
Maxim Malkov Software Engineering Department, ISPRAS
Theodore Ts'o
maintainerQuoted 13 lines · Maxim Malkov
# mkfs.ext4 /dev/loop0 100M # adjust if necessary, should be less than partition sizeSuperblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729(pick one)
# mount -t ext4 -o sb=40961 /dev/loop0 /media/ # resize2fs /dev/loop0 resize2fs 1.42.12 (29-Aug-2014) Filesystem at /dev/loop0 is mounted on /media; on-line resizing required old_desc_blocks = 1, new_desc_blocks = 4
Quoted 4 lines
Now, depending on your luck, various things may happen. resize2fs may hang. You might see
BUG()in your dmesg. Either way, system will become severely corrupted (as indicated by fsck). You won't be able to mount it, either.
Thanks for the bug report; I've can reproduce this using a 3.18 based kernel.
It may be that simplest bug fix is to simply disallow resizing if we are using a backup superblock.
- Ted
Theodore Ts'o
maintainerPATCH 1/1 ext4: prevent online resize with backup superblock
Prevent BUG or corrupted file systems after the following:
mkfs.ext4 /dev/vdc 100M
mount -t ext4 -o sb=40961 /dev/vdc /vdc
resize2fs /dev/vdc
We previously prevented online resizing using the old resize ioctl. Move the code to ext4_resize_begin(), so the check applies for all of the resize ioctl's.
--- fs/ext4/resize.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
fs/ext4/resize.c +12 -11
@@ -24,6 +24,18 @@ int ext4_resize_begin(struct super_block *sb)return -EPERM ;/* +* If we are not using the primary superblock/GDT copy don't resize, +* because the user tools have no way of handling this. Probably a +* bad time to do it anyways. +*/ +if (EXT4_SB (sb)->s_sbh->b_blocknr != +le32_to_cpu (EXT4_SB (sb)->s_es->s_first_data_block)) { +ext4_warning (sb,"won't resize using backup superblock at %llu" , + (unsigned long long )EXT4_SB (sb)->s_sbh->b_blocknr); +return -EPERM ; + } + +/* * We are not allowed to do online-resizing on a filesystem mounted * with error, because it can destroy the filesystem easily. */
@@ -758,18 +770,6 @@ static int add_new_gdb(handle_t *handle, struct inode *inode,"EXT4-fs: ext4_add_new_gdb: adding group block %lu\n" , gdb_num); -/* -* If we are not using the primary superblock/GDT copy don't resize, -* because the user tools have no way of handling this. Probably a -* bad time to do it anyways. -*/ -if (EXT4_SB (sb)->s_sbh->b_blocknr != -le32_to_cpu (EXT4_SB (sb)->s_es->s_first_data_block)) { -ext4_warning (sb,"won't resize using backup superblock at %llu" , - (unsigned long long )EXT4_SB (sb)->s_sbh->b_blocknr); -return -EPERM ; - }