Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0ef692e0 authored by Chao Yu's avatar Chao Yu Committed by Jaegeuk Kim
Browse files

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 5d2300d2
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -154,6 +154,26 @@ noinline_data Disable the inline data feature, inline data feature is
                       enabled by default.
data_flush             Enable data flushing before checkpoint in order to
                       persist data of regular and symlink.
fault_injection=%d     Enable fault injection in all supported types with
                       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"
                       and "lfs". In "lfs" mode, there should be no random
                       writes towards main area.
+1 −1
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ struct kmem_cache *f2fs_inode_entry_slab;

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);
	if (!end_io)
		f2fs_flush_merged_writes(sbi);
+5 −2
Original line number Diff line number Diff line
@@ -62,6 +62,8 @@ enum {
	FAULT_MAX,
};

#define F2FS_ALL_FAULT_TYPE		((1 << FAULT_MAX) - 1)

struct f2fs_fault_info {
	atomic_t inject_ops;
	unsigned int inject_rate;
@@ -3464,9 +3466,10 @@ static inline bool f2fs_force_buffered_io(struct inode *inode, int rw)
}

#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
#define f2fs_build_fault_attr(sbi, rate)		do { } while (0)
#define f2fs_build_fault_attr(sbi, rate, type)		do { } while (0)
#endif

#endif
+27 −7
Original line number Diff line number Diff line
@@ -58,17 +58,21 @@ char *f2fs_fault_name[FAULT_MAX] = {
	[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;

	if (rate) {
		atomic_set(&ffi->inject_ops, 0);
		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

@@ -113,6 +117,7 @@ enum {
	Opt_mode,
	Opt_io_size_bits,
	Opt_fault_injection,
	Opt_fault_type,
	Opt_lazytime,
	Opt_nolazytime,
	Opt_quota,
@@ -170,6 +175,7 @@ static match_table_t f2fs_tokens = {
	{Opt_mode, "mode=%s"},
	{Opt_io_size_bits, "io_bits=%u"},
	{Opt_fault_injection, "fault_injection=%u"},
	{Opt_fault_type, "fault_type=%u"},
	{Opt_lazytime, "lazytime"},
	{Opt_nolazytime, "nolazytime"},
	{Opt_quota, "quota"},
@@ -600,7 +606,18 @@ static int parse_options(struct super_block *sb, char *options)
			if (args->from && match_int(args, &arg))
				return -EINVAL;
#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);
#else
			f2fs_msg(sb, KERN_INFO,
@@ -1321,9 +1338,12 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
	if (F2FS_IO_SIZE_BITS(sbi))
		seq_printf(seq, ",io_size=%uKB", F2FS_IO_SIZE_KB(sbi));
#ifdef CONFIG_F2FS_FAULT_INJECTION
	if (test_opt(sbi, FAULT_INJECTION))
	if (test_opt(sbi, FAULT_INJECTION)) {
		seq_printf(seq, ",fault_injection=%u",
				F2FS_OPTION(sbi).fault_info.inject_rate);
		seq_printf(seq, ",fault_type=%u",
				F2FS_OPTION(sbi).fault_info.inject_type);
	}
#endif
#ifdef CONFIG_QUOTA
	if (test_opt(sbi, QUOTA))
@@ -1393,7 +1413,7 @@ static void default_options(struct f2fs_sb_info *sbi)
	set_opt(sbi, POSIX_ACL);
#endif

	f2fs_build_fault_attr(sbi, 0);
	f2fs_build_fault_attr(sbi, 0, 0);
}

#ifdef CONFIG_QUOTA