|
@@ -82,12 +82,17 @@ static unsigned ext4_init_inode_bitmap(struct super_block *sb,
|
|
|
ext4_free_inodes_set(sb, gdp, 0);
|
|
|
ext4_itable_unused_set(sb, gdp, 0);
|
|
|
memset(bh->b_data, 0xff, sb->s_blocksize);
|
|
|
+ ext4_inode_bitmap_csum_set(sb, block_group, gdp, bh,
|
|
|
+ EXT4_INODES_PER_GROUP(sb) / 8);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8);
|
|
|
ext4_mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), sb->s_blocksize * 8,
|
|
|
bh->b_data);
|
|
|
+ ext4_inode_bitmap_csum_set(sb, block_group, gdp, bh,
|
|
|
+ EXT4_INODES_PER_GROUP(sb) / 8);
|
|
|
+ gdp->bg_checksum = ext4_group_desc_csum(sbi, block_group, gdp);
|
|
|
|
|
|
return EXT4_INODES_PER_GROUP(sb);
|
|
|
}
|
|
@@ -128,12 +133,12 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
|
|
|
return NULL;
|
|
|
}
|
|
|
if (bitmap_uptodate(bh))
|
|
|
- return bh;
|
|
|
+ goto verify;
|
|
|
|
|
|
lock_buffer(bh);
|
|
|
if (bitmap_uptodate(bh)) {
|
|
|
unlock_buffer(bh);
|
|
|
- return bh;
|
|
|
+ goto verify;
|
|
|
}
|
|
|
|
|
|
ext4_lock_group(sb, block_group);
|
|
@@ -141,6 +146,7 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
|
|
|
ext4_init_inode_bitmap(sb, bh, block_group, desc);
|
|
|
set_bitmap_uptodate(bh);
|
|
|
set_buffer_uptodate(bh);
|
|
|
+ set_buffer_verified(bh);
|
|
|
ext4_unlock_group(sb, block_group);
|
|
|
unlock_buffer(bh);
|
|
|
return bh;
|
|
@@ -154,7 +160,7 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
|
|
|
*/
|
|
|
set_bitmap_uptodate(bh);
|
|
|
unlock_buffer(bh);
|
|
|
- return bh;
|
|
|
+ goto verify;
|
|
|
}
|
|
|
/*
|
|
|
* submit the buffer_head for reading
|
|
@@ -171,6 +177,20 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
|
|
|
block_group, bitmap_blk);
|
|
|
return NULL;
|
|
|
}
|
|
|
+
|
|
|
+verify:
|
|
|
+ ext4_lock_group(sb, block_group);
|
|
|
+ if (!buffer_verified(bh) &&
|
|
|
+ !ext4_inode_bitmap_csum_verify(sb, block_group, desc, bh,
|
|
|
+ EXT4_INODES_PER_GROUP(sb) / 8)) {
|
|
|
+ ext4_unlock_group(sb, block_group);
|
|
|
+ put_bh(bh);
|
|
|
+ ext4_error(sb, "Corrupt inode bitmap - block_group = %u, "
|
|
|
+ "inode_bitmap = %llu", block_group, bitmap_blk);
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ ext4_unlock_group(sb, block_group);
|
|
|
+ set_buffer_verified(bh);
|
|
|
return bh;
|
|
|
}
|
|
|
|
|
@@ -276,6 +296,8 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
|
|
|
ext4_used_dirs_set(sb, gdp, count);
|
|
|
percpu_counter_dec(&sbi->s_dirs_counter);
|
|
|
}
|
|
|
+ ext4_inode_bitmap_csum_set(sb, block_group, gdp, bitmap_bh,
|
|
|
+ EXT4_INODES_PER_GROUP(sb) / 8);
|
|
|
gdp->bg_checksum = ext4_group_desc_csum(sbi, block_group, gdp);
|
|
|
ext4_unlock_group(sb, block_group);
|
|
|
|
|
@@ -751,7 +773,7 @@ got:
|
|
|
goto fail;
|
|
|
|
|
|
/* Update the relevant bg descriptor fields */
|
|
|
- if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
|
|
|
+ if (ext4_has_group_desc_csum(sb)) {
|
|
|
int free;
|
|
|
struct ext4_group_info *grp = ext4_get_group_info(sb, group);
|
|
|
|
|
@@ -782,7 +804,9 @@ got:
|
|
|
atomic_inc(&sbi->s_flex_groups[f].used_dirs);
|
|
|
}
|
|
|
}
|
|
|
- if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
|
|
|
+ if (ext4_has_group_desc_csum(sb)) {
|
|
|
+ ext4_inode_bitmap_csum_set(sb, group, gdp, inode_bitmap_bh,
|
|
|
+ EXT4_INODES_PER_GROUP(sb) / 8);
|
|
|
gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp);
|
|
|
ext4_unlock_group(sb, group);
|
|
|
}
|