diff options
author | Theodore Ts'o <tytso@mit.edu> | 2008-07-26 14:34:21 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2008-07-26 14:34:21 -0400 |
commit | 8a266467b8c4841ca994d0fe59f39e584650e3df (patch) | |
tree | b9cde0d9ddf3d5eea87f609267b930e08024a9f1 /fs/ext4 | |
parent | d03856bd5e5abac717da137dc60fe4a691769bd0 (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>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/super.c | 24 |
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. |