aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2008-07-26 14:34:21 -0400
committerTheodore Ts'o <tytso@mit.edu>2008-07-26 14:34:21 -0400
commit8a266467b8c4841ca994d0fe59f39e584650e3df (patch)
treeb9cde0d9ddf3d5eea87f609267b930e08024a9f1
parentd03856bd5e5abac717da137dc60fe4a691769bd0 (diff)
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: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r--fs/ext4/super.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index b5479b1dff14..876e1c620365 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1626,7 +1626,8 @@ static int ext4_check_descriptors(struct super_block *sb)
1626 "Checksum for group %lu failed (%u!=%u)\n", 1626 "Checksum for group %lu failed (%u!=%u)\n",
1627 i, le16_to_cpu(ext4_group_desc_csum(sbi, i, 1627 i, le16_to_cpu(ext4_group_desc_csum(sbi, i,
1628 gdp)), le16_to_cpu(gdp->bg_checksum)); 1628 gdp)), le16_to_cpu(gdp->bg_checksum));
1629 return 0; 1629 if (!(sb->s_flags & MS_RDONLY))
1630 return 0;
1630 } 1631 }
1631 if (!flexbg_flag) 1632 if (!flexbg_flag)
1632 first_block += EXT4_BLOCKS_PER_GROUP(sb); 1633 first_block += EXT4_BLOCKS_PER_GROUP(sb);
@@ -2961,6 +2962,7 @@ static int ext4_remount (struct super_block * sb, int * flags, char * data)
2961 ext4_fsblk_t n_blocks_count = 0; 2962 ext4_fsblk_t n_blocks_count = 0;
2962 unsigned long old_sb_flags; 2963 unsigned long old_sb_flags;
2963 struct ext4_mount_options old_opts; 2964 struct ext4_mount_options old_opts;
2965 ext4_group_t g;
2964 int err; 2966 int err;
2965#ifdef CONFIG_QUOTA 2967#ifdef CONFIG_QUOTA
2966 int i; 2968 int i;
@@ -3039,6 +3041,26 @@ static int ext4_remount (struct super_block * sb, int * flags, char * data)
3039 } 3041 }
3040 3042
3041 /* 3043 /*
3044 * Make sure the group descriptor checksums
3045 * are sane. If they aren't, refuse to
3046 * remount r/w.
3047 */
3048 for (g = 0; g < sbi->s_groups_count; g++) {
3049 struct ext4_group_desc *gdp =
3050 ext4_get_group_desc(sb, g, NULL);
3051
3052 if (!ext4_group_desc_csum_verify(sbi, g, gdp)) {
3053 printk(KERN_ERR
3054 "EXT4-fs: ext4_remount: "
3055 "Checksum for group %lu failed (%u!=%u)\n",
3056 g, le16_to_cpu(ext4_group_desc_csum(sbi, g, gdp)),
3057 le16_to_cpu(gdp->bg_checksum));
3058 err = -EINVAL;
3059 goto restore_opts;
3060 }
3061 }
3062
3063 /*
3042 * If we have an unprocessed orphan list hanging 3064 * If we have an unprocessed orphan list hanging
3043 * around from a previously readonly bdev mount, 3065 * around from a previously readonly bdev mount,
3044 * require a full umount/remount for now. 3066 * require a full umount/remount for now.