From: Yufen Yu <yuyufen@huawei.com>
To: <jaegeuk@kernel.org>, <chao@kernel.org>
Cc: <linux-kernel@vger.kernel.org>,
<linux-f2fs-devel@lists.sourceforge.net>, <yuyufen@huawei.com>
Subject: [PATCH 2/5] f2fs: use common fault injection frmework
Date: Fri, 1 Apr 2022 15:19:06 +0800 [thread overview]
Message-ID: <20220401071909.505086-3-yuyufen@huawei.com> (raw)
In-Reply-To: <20220401071909.505086-1-yuyufen@huawei.com>
For now, f2fs use mount options 'fault_injection' and 'fault_type'
to enable fault injection. We set inject_type and inject_rate in sysfs
to control fault injection.
In fact, common fault injection framework have provided a systematic
way to support error injection via debugfs, which has more richer
and easier control means than the current one.
For example, we can set 'interval' to specify the interval between
failures, and set 'times' to specify how many times failures may happen
at most. More fault injection usage can be seen in (Documentation/
fault-injection/fault-injection.rst)
Signed-off-by: Yufen Yu <yuyufen@huawei.com>
---
fs/f2fs/Kconfig | 2 +-
fs/f2fs/Makefile | 1 +
fs/f2fs/f2fs.h | 26 ++++++++++++++++
fs/f2fs/fault_inject.c | 67 ++++++++++++++++++++++++++++++++++++++++++
fs/f2fs/super.c | 3 ++
5 files changed, 98 insertions(+), 1 deletion(-)
create mode 100644 fs/f2fs/fault_inject.c
diff --git a/fs/f2fs/Kconfig b/fs/f2fs/Kconfig
index 03ef087537c7..d40a69077383 100644
--- a/fs/f2fs/Kconfig
+++ b/fs/f2fs/Kconfig
@@ -86,7 +86,7 @@ config F2FS_CHECK_FS
config F2FS_FAULT_INJECTION
bool "F2FS fault injection facility"
- depends on F2FS_FS
+ depends on F2FS_FS && FAULT_INJECTION && DEBUG_FS
help
Test F2FS to inject faults such as ENOMEM, ENOSPC, and so on.
diff --git a/fs/f2fs/Makefile b/fs/f2fs/Makefile
index 8a7322d229e4..ff25d7095b95 100644
--- a/fs/f2fs/Makefile
+++ b/fs/f2fs/Makefile
@@ -10,3 +10,4 @@ f2fs-$(CONFIG_F2FS_FS_POSIX_ACL) += acl.o
f2fs-$(CONFIG_FS_VERITY) += verity.o
f2fs-$(CONFIG_F2FS_FS_COMPRESSION) += compress.o
f2fs-$(CONFIG_F2FS_IOSTAT) += iostat.o
+f2fs-$(CONFIG_F2FS_FAULT_INJECTION) += fault_inject.o
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index be3014029a4e..50077b0388d1 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -27,6 +27,7 @@
#include <linux/fscrypt.h>
#include <linux/fsverity.h>
+#include <linux/fault-inject.h>
struct pagevec;
@@ -1592,6 +1593,14 @@ struct decompress_io_ctx {
struct work_struct verity_work; /* work to verify the decompressed pages */
};
+struct f2fs_fault_inject {
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+ struct fault_attr attr;
+ struct dentry *parent;
+ unsigned int inject_type;
+#endif
+};
+
#define NULL_CLUSTER ((unsigned int)(~0))
#define MIN_COMPRESS_LOG_SIZE 2
#define MAX_COMPRESS_LOG_SIZE 8
@@ -1846,6 +1855,8 @@ struct f2fs_sb_info {
spinlock_t iostat_lat_lock;
struct iostat_lat_info *iostat_io_lat;
#endif
+
+ struct f2fs_fault_inject fault_inject;
};
#ifdef CONFIG_F2FS_FAULT_INJECTION
@@ -1879,6 +1890,21 @@ static inline bool time_to_inject(struct f2fs_sb_info *sbi, int type)
}
#endif
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+bool f2fs_should_fail(struct f2fs_sb_info *sbi, unsigned int type);
+void f2fs_fault_inject_init(struct f2fs_sb_info *sbi);
+void f2fs_fault_inject_fini(struct f2fs_sb_info *sbi);
+void f2fs_stop_fault_inject(struct f2fs_sb_info *sbi);
+#else
+static inline bool f2fs_should_fail(struct f2fs_sb_info *sbi, unsigned int type)
+{
+ return false;
+};
+static inline void f2fs_fault_inject_init(struct f2fs_sb_info *sbi) {};
+static inline void f2fs_fault_inject_fini(struct f2fs_sb_info *sbi) {};
+static inline void f2fs_stop_fault_inject(struct f2fs_sb_info *sbi) {};
+#endif
+
/*
* Test if the mounted volume is a multi-device volume.
* - For a single regular disk volume, sbi->s_ndevs is 0.
diff --git a/fs/f2fs/fault_inject.c b/fs/f2fs/fault_inject.c
new file mode 100644
index 000000000000..a62328b38ad6
--- /dev/null
+++ b/fs/f2fs/fault_inject.c
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 Huawei Technologies Co., Ltd.
+ *
+ */
+#include <linux/f2fs_fs.h>
+#include "f2fs.h"
+
+static DECLARE_FAULT_ATTR(fail_default_attr);
+
+void f2fs_fault_inject_init(struct f2fs_sb_info *sbi)
+{
+ struct f2fs_fault_inject *fault_inj = &sbi->fault_inject;
+ struct dentry *dir, *parent;
+ struct fault_attr *attr = &fault_inj->attr;
+ const char *name = sbi->sb->s_id;
+
+ if (!f2fs_debugfs_root) {
+ f2fs_warn(sbi, "root debugfs have not created");
+ return;
+ }
+
+ /* create debugfs directory and attribute */
+ parent = debugfs_create_dir(name, f2fs_debugfs_root);
+ if (!parent) {
+ f2fs_warn(sbi, "%s: failed to create debugfs directory\n", name);
+ return;
+ }
+
+ *attr = fail_default_attr;
+ dir = fault_create_debugfs_attr("fault_inject", parent, attr);
+ if (IS_ERR(dir)) {
+ f2fs_warn(sbi, "%s: failed to create debugfs attr\n", name);
+ debugfs_remove_recursive(parent);
+ return;
+ }
+ fault_inj->parent = parent;
+
+ debugfs_create_x32("inject_type", 0600, dir, &fault_inj->inject_type);
+}
+
+void f2fs_fault_inject_fini(struct f2fs_sb_info *sbi)
+{
+ struct f2fs_fault_inject *fault_inj = &sbi->fault_inject;
+
+ debugfs_remove_recursive(fault_inj->parent);
+}
+
+bool f2fs_should_fail(struct f2fs_sb_info *sbi, unsigned int type)
+{
+ struct f2fs_fault_inject *fault_inj = &sbi->fault_inject;
+
+ if (!(fault_inj->inject_type & (1 << type)))
+ return false;
+
+ if (!should_fail(&fault_inj->attr, 1))
+ return false;
+
+ return true;
+}
+
+void f2fs_stop_fault_inject(struct f2fs_sb_info *sbi)
+{
+ struct f2fs_fault_inject *fault_inj = &sbi->fault_inject;
+
+ fault_inj->inject_type = 0;
+}
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 04e41360303c..4366469aae80 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1600,6 +1600,8 @@ static void f2fs_put_super(struct super_block *sb)
*/
f2fs_destroy_stats(sbi);
+ f2fs_fault_inject_fini(sbi);
+
/* destroy f2fs internal modules */
f2fs_destroy_node_manager(sbi);
f2fs_destroy_segment_manager(sbi);
@@ -4418,6 +4420,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
f2fs_update_time(sbi, CP_TIME);
f2fs_update_time(sbi, REQ_TIME);
clear_sbi_flag(sbi, SBI_CP_DISABLED_QUICK);
+ f2fs_fault_inject_init(sbi);
return 0;
sync_free_meta:
--
2.31.1
next prev parent reply other threads:[~2022-04-01 7:04 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-01 7:19 [PATCH 0/5] f2fs: try to use common fault injection framework Yufen Yu
2022-04-01 7:19 ` [PATCH 1/5] f2fs: extract f2fs root debugfs to init_f2fs_fs Yufen Yu
2022-04-01 7:19 ` Yufen Yu [this message]
2022-04-01 7:19 ` [PATCH 3/5] f2fs: replace function time_to_inject by f2fs_should_fail Yufen Yu
2022-04-01 7:19 ` [PATCH 4/5] f2fs: get rid of stale fault injection code Yufen Yu
2022-04-01 8:28 ` [f2fs-dev] " Chao Yu
2022-04-06 3:01 ` Yufen Yu
2022-04-11 10:04 ` Chao Yu
2022-04-11 21:20 ` Jaegeuk Kim
2022-04-12 11:04 ` Yufen Yu
2022-04-19 2:56 ` Chao Yu
2022-04-01 7:19 ` [PATCH 5/5] f2fs: update doc for f2fs fault injection Yufen Yu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220401071909.505086-3-yuyufen@huawei.com \
--to=yuyufen@huawei.com \
--cc=chao@kernel.org \
--cc=jaegeuk@kernel.org \
--cc=linux-f2fs-devel@lists.sourceforge.net \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®