Skip to content

Commit bdfb6ff

Browse files
djwongtytso
authored andcommitted
ext4: mark group corrupt on group descriptor checksum
If the group descriptor fails validation, mark the whole blockgroup corrupt so that the inode/block allocators skip this group. The previous approach takes the risk of writing to a damaged group descriptor; hopefully it was never the case that the [ib]bitmap fields pointed to another valid block and got dirtied, since the memset would fill the page with 1s. Signed-off-by: Darrick J. Wong <[email protected]> Signed-off-by: "Theodore Ts'o" <[email protected]>
1 parent 87a3938 commit bdfb6ff

File tree

2 files changed

+8
-11
lines changed

2 files changed

+8
-11
lines changed

fs/ext4/balloc.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -184,18 +184,17 @@ void ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
184184
struct ext4_sb_info *sbi = EXT4_SB(sb);
185185
ext4_fsblk_t start, tmp;
186186
int flex_bg = 0;
187+
struct ext4_group_info *grp;
187188

188189
J_ASSERT_BH(bh, buffer_locked(bh));
189190

190191
/* If checksum is bad mark all blocks used to prevent allocation
191192
* essentially implementing a per-group read-only flag. */
192193
if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) {
193194
ext4_error(sb, "Checksum bad for group %u", block_group);
194-
ext4_free_group_clusters_set(sb, gdp, 0);
195-
ext4_free_inodes_set(sb, gdp, 0);
196-
ext4_itable_unused_set(sb, gdp, 0);
197-
memset(bh->b_data, 0xff, sb->s_blocksize);
198-
ext4_block_bitmap_csum_set(sb, block_group, gdp, bh);
195+
grp = ext4_get_group_info(sb, block_group);
196+
set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state);
197+
set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state);
199198
return;
200199
}
201200
memset(bh->b_data, 0, sb->s_blocksize);

fs/ext4/ialloc.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,18 +70,16 @@ static unsigned ext4_init_inode_bitmap(struct super_block *sb,
7070
ext4_group_t block_group,
7171
struct ext4_group_desc *gdp)
7272
{
73+
struct ext4_group_info *grp;
7374
J_ASSERT_BH(bh, buffer_locked(bh));
7475

7576
/* If checksum is bad mark all blocks and inodes use to prevent
7677
* allocation, essentially implementing a per-group read-only flag. */
7778
if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) {
7879
ext4_error(sb, "Checksum bad for group %u", block_group);
79-
ext4_free_group_clusters_set(sb, gdp, 0);
80-
ext4_free_inodes_set(sb, gdp, 0);
81-
ext4_itable_unused_set(sb, gdp, 0);
82-
memset(bh->b_data, 0xff, sb->s_blocksize);
83-
ext4_inode_bitmap_csum_set(sb, block_group, gdp, bh,
84-
EXT4_INODES_PER_GROUP(sb) / 8);
80+
grp = ext4_get_group_info(sb, block_group);
81+
set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state);
82+
set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state);
8583
return 0;
8684
}
8785

0 commit comments

Comments
 (0)