Commit 8a266467 authored by Theodore Ts'o's avatar Theodore Ts'o

ext4: Allow read/only mounts with corrupted block group checksums

If the block group checksums are corrupted, still allow the mount to
succeed, so e2fsck can have a chance to try to fix things up.  Add
code in the remount r/w path to make sure the block group checksums
are valid before allowing the filesystem to be remounted read/write.
Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
parent d03856bd
...@@ -1626,7 +1626,8 @@ static int ext4_check_descriptors(struct super_block *sb) ...@@ -1626,7 +1626,8 @@ static int ext4_check_descriptors(struct super_block *sb)
"Checksum for group %lu failed (%u!=%u)\n", "Checksum for group %lu failed (%u!=%u)\n",
i, le16_to_cpu(ext4_group_desc_csum(sbi, i, i, le16_to_cpu(ext4_group_desc_csum(sbi, i,
gdp)), le16_to_cpu(gdp->bg_checksum)); gdp)), le16_to_cpu(gdp->bg_checksum));
return 0; if (!(sb->s_flags & MS_RDONLY))
return 0;
} }
if (!flexbg_flag) if (!flexbg_flag)
first_block += EXT4_BLOCKS_PER_GROUP(sb); first_block += EXT4_BLOCKS_PER_GROUP(sb);
...@@ -2961,6 +2962,7 @@ static int ext4_remount (struct super_block * sb, int * flags, char * data) ...@@ -2961,6 +2962,7 @@ static int ext4_remount (struct super_block * sb, int * flags, char * data)
ext4_fsblk_t n_blocks_count = 0; ext4_fsblk_t n_blocks_count = 0;
unsigned long old_sb_flags; unsigned long old_sb_flags;
struct ext4_mount_options old_opts; struct ext4_mount_options old_opts;
ext4_group_t g;
int err; int err;
#ifdef CONFIG_QUOTA #ifdef CONFIG_QUOTA
int i; int i;
...@@ -3038,6 +3040,26 @@ static int ext4_remount (struct super_block * sb, int * flags, char * data) ...@@ -3038,6 +3040,26 @@ static int ext4_remount (struct super_block * sb, int * flags, char * data)
goto restore_opts; goto restore_opts;
} }
/*
* Make sure the group descriptor checksums
* are sane. If they aren't, refuse to
* remount r/w.
*/
for (g = 0; g < sbi->s_groups_count; g++) {
struct ext4_group_desc *gdp =
ext4_get_group_desc(sb, g, NULL);
if (!ext4_group_desc_csum_verify(sbi, g, gdp)) {
printk(KERN_ERR
"EXT4-fs: ext4_remount: "
"Checksum for group %lu failed (%u!=%u)\n",
g, le16_to_cpu(ext4_group_desc_csum(sbi, g, gdp)),
le16_to_cpu(gdp->bg_checksum));
err = -EINVAL;
goto restore_opts;
}
}
/* /*
* If we have an unprocessed orphan list hanging * If we have an unprocessed orphan list hanging
* around from a previously readonly bdev mount, * around from a previously readonly bdev mount,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment