mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 18:13:41 +02:00
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:
parent
e073e92789
commit
2be96c2147
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user