Commit d494500a authored by Chao Yu's avatar Chao Yu Committed by Jaegeuk Kim

f2fs: support fault_type mount option

Previously, once fault injection is on, by default, all kind of faults
will be injected to f2fs, if we want to trigger single or specified
combined type during the test, we need to configure sysfs entry, it will
be a little inconvenient to integrate sysfs configuring into testsuit,
such as xfstest.

So this patch introduces a new mount option 'fault_type' to assist old
option 'fault_injection', with these two mount options, we can specify
any fault rate/type at mount-time.
Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 3f16ecd9
...@@ -157,6 +157,24 @@ data_flush Enable data flushing before checkpoint in order to ...@@ -157,6 +157,24 @@ data_flush Enable data flushing before checkpoint in order to
persist data of regular and symlink. persist data of regular and symlink.
fault_injection=%d Enable fault injection in all supported types with fault_injection=%d Enable fault injection in all supported types with
specified injection rate. specified injection rate.
fault_type=%d Support configuring fault injection type, should be
enabled with fault_injection option, fault type value
is shown below, it supports single or combined type.
Type_Name Type_Value
FAULT_KMALLOC 0x000000001
FAULT_KVMALLOC 0x000000002
FAULT_PAGE_ALLOC 0x000000004
FAULT_PAGE_GET 0x000000008
FAULT_ALLOC_BIO 0x000000010
FAULT_ALLOC_NID 0x000000020
FAULT_ORPHAN 0x000000040
FAULT_BLOCK 0x000000080
FAULT_DIR_DEPTH 0x000000100
FAULT_EVICT_INODE 0x000000200
FAULT_TRUNCATE 0x000000400
FAULT_IO 0x000000800
FAULT_CHECKPOINT 0x000001000
FAULT_DISCARD 0x000002000
mode=%s Control block allocation mode which supports "adaptive" mode=%s Control block allocation mode which supports "adaptive"
and "lfs". In "lfs" mode, there should be no random and "lfs". In "lfs" mode, there should be no random
writes towards main area. writes towards main area.
......
...@@ -28,7 +28,7 @@ struct kmem_cache *f2fs_inode_entry_slab; ...@@ -28,7 +28,7 @@ struct kmem_cache *f2fs_inode_entry_slab;
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io) void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io)
{ {
f2fs_build_fault_attr(sbi, 0); f2fs_build_fault_attr(sbi, 0, 0);
set_ckpt_flags(sbi, CP_ERROR_FLAG); set_ckpt_flags(sbi, CP_ERROR_FLAG);
if (!end_io) if (!end_io)
f2fs_flush_merged_writes(sbi); f2fs_flush_merged_writes(sbi);
......
...@@ -60,6 +60,8 @@ enum { ...@@ -60,6 +60,8 @@ enum {
FAULT_MAX, FAULT_MAX,
}; };
#define F2FS_ALL_FAULT_TYPE ((1 << FAULT_MAX) - 1)
struct f2fs_fault_info { struct f2fs_fault_info {
atomic_t inject_ops; atomic_t inject_ops;
unsigned int inject_rate; unsigned int inject_rate;
...@@ -3435,9 +3437,10 @@ static inline bool f2fs_force_buffered_io(struct inode *inode, int rw) ...@@ -3435,9 +3437,10 @@ static inline bool f2fs_force_buffered_io(struct inode *inode, int rw)
} }
#ifdef CONFIG_F2FS_FAULT_INJECTION #ifdef CONFIG_F2FS_FAULT_INJECTION
extern void f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned int rate); extern void f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned int rate,
unsigned int type);
#else #else
#define f2fs_build_fault_attr(sbi, rate) do { } while (0) #define f2fs_build_fault_attr(sbi, rate, type) do { } while (0)
#endif #endif
#endif #endif
...@@ -58,17 +58,21 @@ char *f2fs_fault_name[FAULT_MAX] = { ...@@ -58,17 +58,21 @@ char *f2fs_fault_name[FAULT_MAX] = {
[FAULT_DISCARD] = "discard error", [FAULT_DISCARD] = "discard error",
}; };
void f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned int rate) void f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned int rate,
unsigned int type)
{ {
struct f2fs_fault_info *ffi = &F2FS_OPTION(sbi).fault_info; struct f2fs_fault_info *ffi = &F2FS_OPTION(sbi).fault_info;
if (rate) { if (rate) {
atomic_set(&ffi->inject_ops, 0); atomic_set(&ffi->inject_ops, 0);
ffi->inject_rate = rate; ffi->inject_rate = rate;
ffi->inject_type = (1 << FAULT_MAX) - 1;
} else {
memset(ffi, 0, sizeof(struct f2fs_fault_info));
} }
if (type)
ffi->inject_type = type;
if (!rate && !type)
memset(ffi, 0, sizeof(struct f2fs_fault_info));
} }
#endif #endif
...@@ -113,6 +117,7 @@ enum { ...@@ -113,6 +117,7 @@ enum {
Opt_mode, Opt_mode,
Opt_io_size_bits, Opt_io_size_bits,
Opt_fault_injection, Opt_fault_injection,
Opt_fault_type,
Opt_lazytime, Opt_lazytime,
Opt_nolazytime, Opt_nolazytime,
Opt_quota, Opt_quota,
...@@ -170,6 +175,7 @@ static match_table_t f2fs_tokens = { ...@@ -170,6 +175,7 @@ static match_table_t f2fs_tokens = {
{Opt_mode, "mode=%s"}, {Opt_mode, "mode=%s"},
{Opt_io_size_bits, "io_bits=%u"}, {Opt_io_size_bits, "io_bits=%u"},
{Opt_fault_injection, "fault_injection=%u"}, {Opt_fault_injection, "fault_injection=%u"},
{Opt_fault_type, "fault_type=%u"},
{Opt_lazytime, "lazytime"}, {Opt_lazytime, "lazytime"},
{Opt_nolazytime, "nolazytime"}, {Opt_nolazytime, "nolazytime"},
{Opt_quota, "quota"}, {Opt_quota, "quota"},
...@@ -600,7 +606,18 @@ static int parse_options(struct super_block *sb, char *options) ...@@ -600,7 +606,18 @@ static int parse_options(struct super_block *sb, char *options)
if (args->from && match_int(args, &arg)) if (args->from && match_int(args, &arg))
return -EINVAL; return -EINVAL;
#ifdef CONFIG_F2FS_FAULT_INJECTION #ifdef CONFIG_F2FS_FAULT_INJECTION
f2fs_build_fault_attr(sbi, arg); f2fs_build_fault_attr(sbi, arg, F2FS_ALL_FAULT_TYPE);
set_opt(sbi, FAULT_INJECTION);
#else
f2fs_msg(sb, KERN_INFO,
"FAULT_INJECTION was not selected");
#endif
break;
case Opt_fault_type:
if (args->from && match_int(args, &arg))
return -EINVAL;
#ifdef CONFIG_F2FS_FAULT_INJECTION
f2fs_build_fault_attr(sbi, 0, arg);
set_opt(sbi, FAULT_INJECTION); set_opt(sbi, FAULT_INJECTION);
#else #else
f2fs_msg(sb, KERN_INFO, f2fs_msg(sb, KERN_INFO,
...@@ -1321,9 +1338,12 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) ...@@ -1321,9 +1338,12 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
if (F2FS_IO_SIZE_BITS(sbi)) if (F2FS_IO_SIZE_BITS(sbi))
seq_printf(seq, ",io_size=%uKB", F2FS_IO_SIZE_KB(sbi)); seq_printf(seq, ",io_size=%uKB", F2FS_IO_SIZE_KB(sbi));
#ifdef CONFIG_F2FS_FAULT_INJECTION #ifdef CONFIG_F2FS_FAULT_INJECTION
if (test_opt(sbi, FAULT_INJECTION)) if (test_opt(sbi, FAULT_INJECTION)) {
seq_printf(seq, ",fault_injection=%u", seq_printf(seq, ",fault_injection=%u",
F2FS_OPTION(sbi).fault_info.inject_rate); F2FS_OPTION(sbi).fault_info.inject_rate);
seq_printf(seq, ",fault_type=%u",
F2FS_OPTION(sbi).fault_info.inject_type);
}
#endif #endif
#ifdef CONFIG_QUOTA #ifdef CONFIG_QUOTA
if (test_opt(sbi, QUOTA)) if (test_opt(sbi, QUOTA))
...@@ -1393,7 +1413,7 @@ static void default_options(struct f2fs_sb_info *sbi) ...@@ -1393,7 +1413,7 @@ static void default_options(struct f2fs_sb_info *sbi)
set_opt(sbi, POSIX_ACL); set_opt(sbi, POSIX_ACL);
#endif #endif
f2fs_build_fault_attr(sbi, 0); f2fs_build_fault_attr(sbi, 0, 0);
} }
#ifdef CONFIG_QUOTA #ifdef CONFIG_QUOTA
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment