Skip to content

Commit e5cc463

Browse files
tytsovijay-suman
authored andcommitted
ext4: update the backup superblock's at the end of the online resize
When expanding a file system using online resize, various fields in the superblock (e.g., s_blocks_count, s_inodes_count, etc.) change. To update the backup superblocks, the online resize uses the function update_backups() in fs/ext4/resize.c. This function was not updating the checksum field in the backup superblocks. This wasn't a big deal previously, because e2fsck didn't care about the checksum field in the backup superblock. (And indeed, update_backups() goes all the way back to the ext3 days, well before we had support for metadata checksums.) However, there is an alternate, more general way of updating superblock fields, ext4_update_primary_sb() in fs/ext4/ioctl.c. This function does check the checksum of the backup superblock, and if it doesn't match will mark the file system as corrupted. That was clearly not the intent, so avoid to aborting the resize when a bad superblock is found. In addition, teach update_backups() to properly update the checksum in the backup superblocks. We will eventually want to unify updapte_backups() with the infrasture in ext4_update_primary_sb(), but that's for another day. Note: The problem has been around for a while; it just didn't really matter until ext4_update_primary_sb() was added by commit bbc605c ("ext4: implement support for get/set fs label"). And it became trivially easy to reproduce after commit 827891a ("ext4: update the s_overhead_clusters in the backup sb's when resizing") in v6.0. Cc: [email protected] # 5.17+ Fixes: bbc605c ("ext4: implement support for get/set fs label") Signed-off-by: Theodore Ts'o <[email protected]> (cherry picked from commit 9a8c5b0) Orabug: 37356729 Signed-off-by: Yifei Liu <[email protected]> Reviewed-by: Saeed Mirzamohammadi <[email protected]> Signed-off-by: Vijayendra Suman <[email protected]>
1 parent 7aa5d31 commit e5cc463

File tree

2 files changed

+6
-2
lines changed

2 files changed

+6
-2
lines changed

fs/ext4/ioctl.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,8 @@ static int ext4_update_backup_sb(struct super_block *sb,
146146
if (ext4_has_metadata_csum(sb) &&
147147
es->s_checksum != ext4_superblock_csum(sb, es)) {
148148
ext4_msg(sb, KERN_ERR, "Invalid checksum for backup "
149-
"superblock %llu\n", sb_block);
149+
"superblock %llu", sb_block);
150150
unlock_buffer(bh);
151-
err = -EFSBADCRC;
152151
goto out_bh;
153152
}
154153
func(es, arg);

fs/ext4/resize.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,7 @@ static void update_backups(struct super_block *sb, sector_t blk_off, char *data,
11571157
while (group < sbi->s_groups_count) {
11581158
struct buffer_head *bh;
11591159
ext4_fsblk_t backup_block;
1160+
struct ext4_super_block *es;
11601161

11611162
/* Out of journal space, and can't get more - abort - so sad */
11621163
err = ext4_resize_ensure_credits_batch(handle, 1);
@@ -1187,6 +1188,10 @@ static void update_backups(struct super_block *sb, sector_t blk_off, char *data,
11871188
memcpy(bh->b_data, data, size);
11881189
if (rest)
11891190
memset(bh->b_data + size, 0, rest);
1191+
es = (struct ext4_super_block *) bh->b_data;
1192+
es->s_block_group_nr = cpu_to_le16(group);
1193+
if (ext4_has_metadata_csum(sb))
1194+
es->s_checksum = ext4_superblock_csum(sb, es);
11901195
set_buffer_uptodate(bh);
11911196
unlock_buffer(bh);
11921197
err = ext4_handle_dirty_metadata(handle, NULL, bh);

0 commit comments

Comments
 (0)