@@ -26,6 +26,8 @@ int ext4_inode_bitmap_csum_verify(struct super_block *sb, ext4_group_t group,
if (!ext4_has_metadata_csum(sb))
return 1;
+ if (ext4_fault_inode_bitmap_csum(sb, group))
+ return 0;
provided = le16_to_cpu(gdp->bg_inode_bitmap_csum_lo);
calculated = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
@@ -65,6 +67,8 @@ int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group,
if (!ext4_has_metadata_csum(sb))
return 1;
+ if (ext4_fault_block_bitmap_csum(sb, group))
+ return 0;
provided = le16_to_cpu(gdp->bg_block_bitmap_csum_lo);
calculated = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)bh->b_data, sz);
@@ -1509,6 +1509,15 @@ struct ext4_orphan_info {
#define FAULT_NOTSET (U64_MAX)
enum ext4_fault_bits {
+ /* inject checksum error */
+ EXT4_FAULT_GRPDESC_CSUM, /* group descriptor */
+ EXT4_FAULT_IBITMAP_CSUM, /* inode bitmap block */
+ EXT4_FAULT_BBITMAP_CSUM, /* block bitmap block */
+ EXT4_FAULT_INODE_CSUM, /* inode */
+ EXT4_FAULT_EXTENT_CSUM, /* extent block */
+ EXT4_FAULT_DIRBLOCK_CSUM, /* directory block */
+ EXT4_FAULT_DIRIDX_CSUM, /* directory index block */
+ EXT4_FAULT_XATTR_CSUM, /* xattr block */
EXT4_FAULT_MAX
};
@@ -1599,6 +1608,15 @@ static inline int ext4_fault_##name(struct super_block *sb, unsigned long ino, \
#endif /* CONFIG_EXT4_FAULT_INJECTION */
+EXT4_FAULT_GRP_FN(GRPDESC_CSUM, groupdesc_csum, 1)
+EXT4_FAULT_GRP_FN(IBITMAP_CSUM, inode_bitmap_csum, 1)
+EXT4_FAULT_GRP_FN(BBITMAP_CSUM, block_bitmap_csum, 1)
+EXT4_FAULT_INODE_FN(INODE_CSUM, inode_csum, 1)
+EXT4_FAULT_INODE_FN(EXTENT_CSUM, extent_csum, 1)
+EXT4_FAULT_INODE_FN(DIRBLOCK_CSUM, dirblock_csum, 1)
+EXT4_FAULT_INODE_FN(DIRIDX_CSUM, dirindex_csum, 1)
+EXT4_FAULT_INODE_FN(XATTR_CSUM, xattr_csum, 1)
+
/*
* fourth extended-fs super-block data in memory
*/
@@ -65,6 +65,8 @@ static int ext4_extent_block_csum_verify(struct inode *inode,
if (!ext4_has_metadata_csum(inode->i_sb))
return 1;
+ if (ext4_fault_extent_csum(inode->i_sb, inode->i_ino))
+ return 0;
et = find_ext4_extent_tail(eh);
if (et->et_checksum != ext4_extent_block_csum(inode, eh))
@@ -90,6 +90,8 @@ static int ext4_inode_csum_verify(struct inode *inode, struct ext4_inode *raw,
cpu_to_le32(EXT4_OS_LINUX) ||
!ext4_has_metadata_csum(inode->i_sb))
return 1;
+ if (ext4_fault_inode_csum(inode->i_sb, inode->i_ino))
+ return 0;
provided = le16_to_cpu(raw->i_checksum_lo);
calculated = ext4_inode_csum(inode, raw, ei);
@@ -398,6 +398,8 @@ int ext4_dirblock_csum_verify(struct inode *inode, struct buffer_head *bh)
if (!ext4_has_metadata_csum(inode->i_sb))
return 1;
+ if (ext4_fault_dirblock_csum(inode->i_sb, inode->i_ino))
+ return 0;
t = get_dirent_tail(inode, bh);
if (!t) {
@@ -493,6 +495,8 @@ static int ext4_dx_csum_verify(struct inode *inode,
if (!ext4_has_metadata_csum(inode->i_sb))
return 1;
+ if (ext4_fault_dirindex_csum(inode->i_sb, inode->i_ino))
+ return 0;
c = get_dx_countlimit(inode, dirent, &count_offset);
if (!c) {
@@ -3194,11 +3194,12 @@ static __le16 ext4_group_desc_csum(struct super_block *sb, __u32 block_group,
int ext4_group_desc_csum_verify(struct super_block *sb, __u32 block_group,
struct ext4_group_desc *gdp)
{
- if (ext4_has_group_desc_csum(sb) &&
- (gdp->bg_checksum != ext4_group_desc_csum(sb, block_group, gdp)))
+ if (!ext4_has_group_desc_csum(sb))
+ return 1;
+ if (ext4_fault_groupdesc_csum(sb, block_group))
return 0;
- return 1;
+ return gdp->bg_checksum == ext4_group_desc_csum(sb, block_group, gdp);
}
void ext4_group_desc_csum_set(struct super_block *sb, __u32 block_group,
@@ -570,7 +570,14 @@ void ext4_unregister_sysfs(struct super_block *sb)
#ifdef CONFIG_EXT4_FAULT_INJECTION
char *ext4_fault_names[EXT4_FAULT_MAX] = {
- /* empty */
+ "group_desc_checksum", /* EXT4_FAULT_GRPDESC_CSUM */
+ "inode_bitmap_checksum", /* EXT4_FAULT_IBITMAP_CSUM */
+ "block_bitmap_checksum", /* EXT4_FAULT_BBITMAP_CSUM */
+ "inode_checksum", /* EXT4_FAULT_INODE_CSUM */
+ "extent_block_checksum", /* EXT4_FAULT_EXTENT_CSUM */
+ "dir_block_checksum", /* EXT4_FAULT_DIRBLOCK_CSUM */
+ "dir_index_block_checksum", /* EXT4_FAULT_DIRIDX_CSUM */
+ "xattr_block_checksum", /* EXT4_FAULT_XATTR_CSUM */
};
static int ext4_fault_available_show(struct seq_file *m, void *v)
@@ -152,14 +152,17 @@ static int ext4_xattr_block_csum_verify(struct inode *inode,
struct buffer_head *bh)
{
struct ext4_xattr_header *hdr = BHDR(bh);
- int ret = 1;
+ int ret;
+
+ if (!ext4_has_metadata_csum(inode->i_sb))
+ return 1;
+ if (ext4_fault_xattr_csum(inode->i_sb, inode->i_ino))
+ return 0;
- if (ext4_has_metadata_csum(inode->i_sb)) {
- lock_buffer(bh);
- ret = (hdr->h_checksum == ext4_xattr_block_csum(inode,
+ lock_buffer(bh);
+ ret = (hdr->h_checksum == ext4_xattr_block_csum(inode,
bh->b_blocknr, hdr));
- unlock_buffer(bh);
- }
+ unlock_buffer(bh);
return ret;
}
Add 8 checksum fault injections, include group descriptors, inode bitmap, block bitmap, inode, extent block, directory leaf block, directory index block and xattr block. They are visable in "available_faults" debugfs interface, and can be set and enabled in the "inject_faults" interface. Signed-off-by: Zhang Yi <yi.zhang@huawei.com> --- fs/ext4/bitmap.c | 4 ++++ fs/ext4/ext4.h | 18 ++++++++++++++++++ fs/ext4/extents.c | 2 ++ fs/ext4/inode.c | 2 ++ fs/ext4/namei.c | 4 ++++ fs/ext4/super.c | 7 ++++--- fs/ext4/sysfs.c | 9 ++++++++- fs/ext4/xattr.c | 15 +++++++++------ 8 files changed, 51 insertions(+), 10 deletions(-)