1 diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
2 index 61aeacb..6557100 100644
5 @@ -90,6 +90,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
6 ext4_group_t ngroups = ext4_get_groups_count(sb);
7 unsigned free_blocks, group_blocks;
8 struct ext4_sb_info *sbi = EXT4_SB(sb);
9 + struct ext4_group_info *grp;
12 J_ASSERT_BH(bh, buffer_locked(bh));
13 @@ -97,12 +98,11 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
14 /* If checksum is bad mark all blocks used to prevent allocation
15 * essentially implementing a per-group read-only flag. */
16 if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
17 - ext4_error(sb, "Checksum bad for group %u",
18 + ext4_warning(sb, "Checksum bad for group %u",
20 - ext4_free_blks_set(sb, gdp, 0);
21 - ext4_free_inodes_set(sb, gdp, 0);
22 - ext4_itable_unused_set(sb, gdp, 0);
23 - memset(bh->b_data, 0xff, sb->s_blocksize);
24 + grp = ext4_get_group_info(sb, block_group);
25 + set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state);
26 + set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state);
29 memset(bh->b_data, 0, sb->s_blocksize);
30 @@ -240,6 +240,7 @@ static int ext4_valid_block_bitmap(struct super_block *sb,
31 ext4_grpblk_t next_zero_bit;
32 ext4_fsblk_t bitmap_blk;
33 ext4_fsblk_t group_first_block;
34 + struct ext4_group_info *grp = ext4_get_group_info(sb, block_group);
36 if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) {
37 /* with FLEX_BG, the inode/block bitmaps and itable
38 @@ -277,8 +278,9 @@ static int ext4_valid_block_bitmap(struct super_block *sb,
42 - ext4_error(sb, "Invalid block bitmap - block_group = %d, block = %llu",
43 + ext4_warning(sb, "Invalid block bitmap - block_group = %d, block = %llu",
44 block_group, bitmap_blk);
45 + set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state);
49 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
50 index f71111c..86953d0 100644
53 @@ -2209,9 +2209,15 @@ struct ext4_group_info {
55 #define EXT4_GROUP_INFO_NEED_INIT_BIT 0
56 #define EXT4_GROUP_INFO_WAS_TRIMMED_BIT 1
57 +#define EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT 2
58 +#define EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT 3
60 #define EXT4_MB_GRP_NEED_INIT(grp) \
61 (test_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &((grp)->bb_state)))
62 +#define EXT4_MB_GRP_BBITMAP_CORRUPT(grp) \
63 + (test_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &((grp)->bb_state)))
64 +#define EXT4_MB_GRP_IBITMAP_CORRUPT(grp) \
65 + (test_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &((grp)->bb_state)))
67 #define EXT4_MB_GRP_WAS_TRIMMED(grp) \
68 (test_bit(EXT4_GROUP_INFO_WAS_TRIMMED_BIT, &((grp)->bb_state)))
69 diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
70 index f3509ba..9e92917 100644
71 --- a/fs/ext4/ialloc.c
72 +++ b/fs/ext4/ialloc.c
73 @@ -70,17 +70,17 @@ unsigned ext4_init_inode_bitmap(struct super_block *sb, struct buffer_head *bh,
74 struct ext4_group_desc *gdp)
76 struct ext4_sb_info *sbi = EXT4_SB(sb);
77 + struct ext4_group_info *grp;
79 J_ASSERT_BH(bh, buffer_locked(bh));
81 /* If checksum is bad mark all blocks and inodes use to prevent
82 * allocation, essentially implementing a per-group read-only flag. */
83 if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
84 - ext4_error(sb, "Checksum bad for group %u", block_group);
85 - ext4_free_blks_set(sb, gdp, 0);
86 - ext4_free_inodes_set(sb, gdp, 0);
87 - ext4_itable_unused_set(sb, gdp, 0);
88 - memset(bh->b_data, 0xff, sb->s_blocksize);
89 + ext4_warning(sb, "Checksum bad for group %u", block_group);
90 + grp = ext4_get_group_info(sb, block_group);
91 + set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state);
92 + set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state);
96 @@ -192,6 +192,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
97 struct ext4_super_block *es;
98 struct ext4_sb_info *sbi;
99 int fatal = 0, err, count, cleared;
100 + struct ext4_group_info *grp;
102 if (atomic_read(&inode->i_count) > 1) {
103 printk(KERN_ERR "ext4_free_inode: inode has count=%d\n",
104 @@ -235,7 +236,9 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
105 block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb);
106 bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb);
107 bitmap_bh = ext4_read_inode_bitmap(sb, block_group);
109 + /* Don't bother if the inode bitmap is corrupt. */
110 + grp = ext4_get_group_info(sb, block_group);
111 + if (unlikely(EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) || !bitmap_bh)
114 BUFFER_TRACE(bitmap_bh, "get_write_access");
115 @@ -247,9 +250,10 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
116 ext4_lock_group(sb, block_group);
117 cleared = ext4_clear_bit(bit, bitmap_bh->b_data);
118 ext4_unlock_group(sb, block_group);
120 - ext4_error(sb, "bit already cleared for inode %lu", ino);
123 + ext4_warning(sb, "bit already cleared for inode %lu", ino);
124 + set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state);
126 gdp = ext4_get_group_desc(sb, block_group, &bh2);
128 BUFFER_TRACE(bh2, "get_write_access");
129 @@ -825,6 +829,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode,
132 ext4_group_t flex_group;
133 + struct ext4_group_info *grp;
135 /* Cannot create files in a deleted directory */
136 if (!dir || !dir->i_nlink)
137 @@ -884,10 +889,21 @@ got_group:
141 + grp = ext4_get_group_info(sb, group);
142 + /* Skip groups with already-known suspicious inode tables */
143 + if (EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) {
144 + if (++group == ngroups)
148 brelse(inode_bitmap_bh);
149 inode_bitmap_bh = ext4_read_inode_bitmap(sb, group);
150 - if (!inode_bitmap_bh)
152 + /* Skip groups with suspicious inode tables */
153 + if (EXT4_MB_GRP_IBITMAP_CORRUPT(grp) || !inode_bitmap_bh) {
154 + if (++group == ngroups)
159 repeat_in_this_group:
160 ino = ext4_find_next_zero_bit((unsigned long *)
161 diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
162 index efcf909..dc88197 100644
163 --- a/fs/ext4/mballoc.c
164 +++ b/fs/ext4/mballoc.c
165 @@ -1291,6 +1291,10 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b,
167 BUG_ON(first + count > (sb->s_blocksize << 3));
168 assert_spin_locked(ext4_group_lock_ptr(sb, e4b->bd_group));
169 + /* Don't bother if the block group is corrupt. */
170 + if (unlikely(EXT4_MB_GRP_BBITMAP_CORRUPT(e4b->bd_info)))
174 mb_free_blocks_double(inode, e4b, first, count);
176 @@ -1321,9 +1325,12 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b,
177 le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block);
178 ext4_grp_locked_error(sb, e4b->bd_group,
179 __func__, "double-free of inode"
180 - " %lu's block %llu(bit %u in group %u)",
181 + " %lu's block %llu(bit %u in group %u) block bitmap corrupt",
182 inode ? inode->i_ino : 0, blocknr, block,
184 + /* Mark the block group as corrupt. */
185 + set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT,
186 + &e4b->bd_info->bb_state);
188 mb_clear_bit(block, EXT4_MB_BITMAP(e4b));
189 e4b->bd_info->bb_counters[order]++;
190 @@ -1700,6 +1707,11 @@ int ext4_mb_find_by_goal(struct ext4_allocation_context *ac,
194 + if (unlikely(EXT4_MB_GRP_BBITMAP_CORRUPT(e4b->bd_info))) {
195 + ext4_mb_release_desc(e4b);
199 ext4_lock_group(ac->ac_sb, group);
200 max = mb_find_extent(e4b, 0, ac->ac_g_ex.fe_start,
201 ac->ac_g_ex.fe_len, &ex);
202 @@ -1912,6 +1924,9 @@ static int ext4_mb_good_group(struct ext4_allocation_context *ac,
204 BUG_ON(cr < 0 || cr >= 4);
206 + if (unlikely(EXT4_MB_GRP_BBITMAP_CORRUPT(grp)))
209 /* We only do this if the grp has never been initialized */
210 if (unlikely(EXT4_MB_GRP_NEED_INIT(grp))) {
211 int ret = ext4_mb_init_group(ac->ac_sb, group);
212 @@ -4746,6 +4761,10 @@ do_more:
214 ext4_get_group_no_and_offset(sb, block, &block_group, &bit);
216 + if (unlikely(EXT4_MB_GRP_BBITMAP_CORRUPT(
217 + ext4_get_group_info(sb, block_group))))
221 * Check to see if we are freeing blocks across a group