lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20220401071909.505086-3-yuyufen@huawei.com>
Date:   Fri, 1 Apr 2022 15:19:06 +0800
From:   Yufen Yu <yuyufen@...wei.com>
To:     <jaegeuk@...nel.org>, <chao@...nel.org>
CC:     <linux-kernel@...r.kernel.org>,
        <linux-f2fs-devel@...ts.sourceforge.net>, <yuyufen@...wei.com>
Subject: [PATCH 2/5] f2fs: use common fault injection frmework

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@...wei.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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ