f2fs: fix to update injection attrs according to fault_option

When we update inject type via sysfs, it shows wrong rate value as
below, there is a same problem when we update inject rate, fix it.

Before:
F2FS-fs (vdd): build fault injection attr: rate: 0, type: 0xffff
F2FS-fs (vdd): build fault injection attr: rate: 1, type: 0x0

After:
F2FS-fs (vdd): build fault injection type: 0x1
F2FS-fs (vdd): build fault injection rate: 1

Meanwhile, let's avoid turning on all fault types when we enable fault
injection via fault_injection mount option, it will lead to shutdown
filesystem or fail the mount() easily.

mount -o fault_injection=4 /dev/vdd /mnt/f2fs
F2FS-fs (vdd): build fault injection attr: rate: 4, type: 0x7fffff
F2FS-fs (vdd): inject kmalloc in f2fs_kmalloc of f2fs_fill_super+0xbdf/0x27c0

Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
Chao Yu 2025-03-20 10:22:30 +08:00 committed by Jaegeuk Kim
parent e073e92789
commit 2be96c2147
4 changed files with 26 additions and 20 deletions

View File

@ -29,7 +29,7 @@ struct kmem_cache *f2fs_inode_entry_slab;
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io,
unsigned char reason)
{
f2fs_build_fault_attr(sbi, 0, 0);
f2fs_build_fault_attr(sbi, 0, 0, FAULT_ALL);
if (!end_io)
f2fs_flush_merged_writes(sbi);
f2fs_handle_critical_error(sbi, reason);

View File

@ -66,9 +66,14 @@ enum {
FAULT_MAX,
};
#ifdef CONFIG_F2FS_FAULT_INJECTION
#define F2FS_ALL_FAULT_TYPE (GENMASK(FAULT_MAX - 1, 0))
/* indicate which option to update */
enum fault_option {
FAULT_RATE = 1, /* only update fault rate */
FAULT_TYPE = 2, /* only update fault type */
FAULT_ALL = 4, /* reset all fault injection options/stats */
};
#ifdef CONFIG_F2FS_FAULT_INJECTION
struct f2fs_fault_info {
atomic_t inject_ops;
int inject_rate;
@ -4765,10 +4770,11 @@ static inline bool f2fs_need_verity(const struct inode *inode, pgoff_t idx)
#ifdef CONFIG_F2FS_FAULT_INJECTION
extern int f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned long rate,
unsigned long type);
unsigned long type, enum fault_option fo);
#else
static inline int f2fs_build_fault_attr(struct f2fs_sb_info *sbi,
unsigned long rate, unsigned long type)
unsigned long rate, unsigned long type,
enum fault_option fo)
{
return 0;
}

View File

@ -68,29 +68,30 @@ const char *f2fs_fault_name[FAULT_MAX] = {
};
int f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned long rate,
unsigned long type)
unsigned long type, enum fault_option fo)
{
struct f2fs_fault_info *ffi = &F2FS_OPTION(sbi).fault_info;
if (rate) {
if (fo & FAULT_ALL) {
memset(ffi, 0, sizeof(struct f2fs_fault_info));
return 0;
}
if (fo & FAULT_RATE) {
if (rate > INT_MAX)
return -EINVAL;
atomic_set(&ffi->inject_ops, 0);
ffi->inject_rate = (int)rate;
f2fs_info(sbi, "build fault injection rate: %lu", rate);
}
if (type) {
if (fo & FAULT_TYPE) {
if (type >= BIT(FAULT_MAX))
return -EINVAL;
ffi->inject_type = (unsigned int)type;
f2fs_info(sbi, "build fault injection type: 0x%lx", type);
}
if (!rate && !type)
memset(ffi, 0, sizeof(struct f2fs_fault_info));
else
f2fs_info(sbi,
"build fault injection attr: rate: %lu, type: 0x%lx",
rate, type);
return 0;
}
#endif
@ -897,8 +898,7 @@ static int parse_options(struct f2fs_sb_info *sbi, char *options, bool is_remoun
case Opt_fault_injection:
if (args->from && match_int(args, &arg))
return -EINVAL;
if (f2fs_build_fault_attr(sbi, arg,
F2FS_ALL_FAULT_TYPE))
if (f2fs_build_fault_attr(sbi, arg, 0, FAULT_RATE))
return -EINVAL;
set_opt(sbi, FAULT_INJECTION);
break;
@ -906,7 +906,7 @@ static int parse_options(struct f2fs_sb_info *sbi, char *options, bool is_remoun
case Opt_fault_type:
if (args->from && match_int(args, &arg))
return -EINVAL;
if (f2fs_build_fault_attr(sbi, 0, arg))
if (f2fs_build_fault_attr(sbi, 0, arg, FAULT_TYPE))
return -EINVAL;
set_opt(sbi, FAULT_INJECTION);
break;
@ -2209,7 +2209,7 @@ static void default_options(struct f2fs_sb_info *sbi, bool remount)
set_opt(sbi, POSIX_ACL);
#endif
f2fs_build_fault_attr(sbi, 0, 0);
f2fs_build_fault_attr(sbi, 0, 0, FAULT_ALL);
}
#ifdef CONFIG_QUOTA

View File

@ -494,12 +494,12 @@ static ssize_t __sbi_store(struct f2fs_attr *a,
return ret;
#ifdef CONFIG_F2FS_FAULT_INJECTION
if (a->struct_type == FAULT_INFO_TYPE) {
if (f2fs_build_fault_attr(sbi, 0, t))
if (f2fs_build_fault_attr(sbi, 0, t, FAULT_TYPE))
return -EINVAL;
return count;
}
if (a->struct_type == FAULT_INFO_RATE) {
if (f2fs_build_fault_attr(sbi, t, 0))
if (f2fs_build_fault_attr(sbi, t, 0, FAULT_RATE))
return -EINVAL;
return count;
}