aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChao Yu <yuchao0@huawei.com>2018-08-08 05:36:41 -0400
committerJaegeuk Kim <jaegeuk@kernel.org>2018-08-13 13:48:17 -0400
commitd494500a70434223bc35f862fab0679b13bea23d (patch)
treee1b31c567401d6c0486aaadf37332a26d6bf36c1
parent3f16ecd950e56d60a574f73af9538f6e24030f9a (diff)
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: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r--Documentation/filesystems/f2fs.txt18
-rw-r--r--fs/f2fs/checkpoint.c2
-rw-r--r--fs/f2fs/f2fs.h7
-rw-r--r--fs/f2fs/super.c34
4 files changed, 51 insertions, 10 deletions
diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt
index 69f8de995739..e5edd29687b5 100644
--- a/Documentation/filesystems/f2fs.txt
+++ b/Documentation/filesystems/f2fs.txt
@@ -157,6 +157,24 @@ data_flush Enable data flushing before checkpoint in order to
157 persist data of regular and symlink. 157 persist data of regular and symlink.
158fault_injection=%d Enable fault injection in all supported types with 158fault_injection=%d Enable fault injection in all supported types with
159 specified injection rate. 159 specified injection rate.
160fault_type=%d Support configuring fault injection type, should be
161 enabled with fault_injection option, fault type value
162 is shown below, it supports single or combined type.
163 Type_Name Type_Value
164 FAULT_KMALLOC 0x000000001
165 FAULT_KVMALLOC 0x000000002
166 FAULT_PAGE_ALLOC 0x000000004
167 FAULT_PAGE_GET 0x000000008
168 FAULT_ALLOC_BIO 0x000000010
169 FAULT_ALLOC_NID 0x000000020
170 FAULT_ORPHAN 0x000000040
171 FAULT_BLOCK 0x000000080
172 FAULT_DIR_DEPTH 0x000000100
173 FAULT_EVICT_INODE 0x000000200
174 FAULT_TRUNCATE 0x000000400
175 FAULT_IO 0x000000800
176 FAULT_CHECKPOINT 0x000001000
177 FAULT_DISCARD 0x000002000
160mode=%s Control block allocation mode which supports "adaptive" 178mode=%s Control block allocation mode which supports "adaptive"
161 and "lfs". In "lfs" mode, there should be no random 179 and "lfs". In "lfs" mode, there should be no random
162 writes towards main area. 180 writes towards main area.
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 31561026ac9a..3ab7a00c0641 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -28,7 +28,7 @@ struct kmem_cache *f2fs_inode_entry_slab;
28 28
29void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io) 29void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io)
30{ 30{
31 f2fs_build_fault_attr(sbi, 0); 31 f2fs_build_fault_attr(sbi, 0, 0);
32 set_ckpt_flags(sbi, CP_ERROR_FLAG); 32 set_ckpt_flags(sbi, CP_ERROR_FLAG);
33 if (!end_io) 33 if (!end_io)
34 f2fs_flush_merged_writes(sbi); 34 f2fs_flush_merged_writes(sbi);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 95244e75dfc4..375aa9f30cfa 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -60,6 +60,8 @@ enum {
60 FAULT_MAX, 60 FAULT_MAX,
61}; 61};
62 62
63#define F2FS_ALL_FAULT_TYPE ((1 << FAULT_MAX) - 1)
64
63struct f2fs_fault_info { 65struct f2fs_fault_info {
64 atomic_t inject_ops; 66 atomic_t inject_ops;
65 unsigned int inject_rate; 67 unsigned int inject_rate;
@@ -3435,9 +3437,10 @@ static inline bool f2fs_force_buffered_io(struct inode *inode, int rw)
3435} 3437}
3436 3438
3437#ifdef CONFIG_F2FS_FAULT_INJECTION 3439#ifdef CONFIG_F2FS_FAULT_INJECTION
3438extern void f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned int rate); 3440extern void f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned int rate,
3441 unsigned int type);
3439#else 3442#else
3440#define f2fs_build_fault_attr(sbi, rate) do { } while (0) 3443#define f2fs_build_fault_attr(sbi, rate, type) do { } while (0)
3441#endif 3444#endif
3442 3445
3443#endif 3446#endif
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 30bd9138f39d..be41dbd7b261 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -58,17 +58,21 @@ char *f2fs_fault_name[FAULT_MAX] = {
58 [FAULT_DISCARD] = "discard error", 58 [FAULT_DISCARD] = "discard error",
59}; 59};
60 60
61void f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned int rate) 61void f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned int rate,
62 unsigned int type)
62{ 63{
63 struct f2fs_fault_info *ffi = &F2FS_OPTION(sbi).fault_info; 64 struct f2fs_fault_info *ffi = &F2FS_OPTION(sbi).fault_info;
64 65
65 if (rate) { 66 if (rate) {
66 atomic_set(&ffi->inject_ops, 0); 67 atomic_set(&ffi->inject_ops, 0);
67 ffi->inject_rate = rate; 68 ffi->inject_rate = rate;
68 ffi->inject_type = (1 << FAULT_MAX) - 1;
69 } else {
70 memset(ffi, 0, sizeof(struct f2fs_fault_info));
71 } 69 }
70
71 if (type)
72 ffi->inject_type = type;
73
74 if (!rate && !type)
75 memset(ffi, 0, sizeof(struct f2fs_fault_info));
72} 76}
73#endif 77#endif
74 78
@@ -113,6 +117,7 @@ enum {
113 Opt_mode, 117 Opt_mode,
114 Opt_io_size_bits, 118 Opt_io_size_bits,
115 Opt_fault_injection, 119 Opt_fault_injection,
120 Opt_fault_type,
116 Opt_lazytime, 121 Opt_lazytime,
117 Opt_nolazytime, 122 Opt_nolazytime,
118 Opt_quota, 123 Opt_quota,
@@ -170,6 +175,7 @@ static match_table_t f2fs_tokens = {
170 {Opt_mode, "mode=%s"}, 175 {Opt_mode, "mode=%s"},
171 {Opt_io_size_bits, "io_bits=%u"}, 176 {Opt_io_size_bits, "io_bits=%u"},
172 {Opt_fault_injection, "fault_injection=%u"}, 177 {Opt_fault_injection, "fault_injection=%u"},
178 {Opt_fault_type, "fault_type=%u"},
173 {Opt_lazytime, "lazytime"}, 179 {Opt_lazytime, "lazytime"},
174 {Opt_nolazytime, "nolazytime"}, 180 {Opt_nolazytime, "nolazytime"},
175 {Opt_quota, "quota"}, 181 {Opt_quota, "quota"},
@@ -600,7 +606,18 @@ static int parse_options(struct super_block *sb, char *options)
600 if (args->from && match_int(args, &arg)) 606 if (args->from && match_int(args, &arg))
601 return -EINVAL; 607 return -EINVAL;
602#ifdef CONFIG_F2FS_FAULT_INJECTION 608#ifdef CONFIG_F2FS_FAULT_INJECTION
603 f2fs_build_fault_attr(sbi, arg); 609 f2fs_build_fault_attr(sbi, arg, F2FS_ALL_FAULT_TYPE);
610 set_opt(sbi, FAULT_INJECTION);
611#else
612 f2fs_msg(sb, KERN_INFO,
613 "FAULT_INJECTION was not selected");
614#endif
615 break;
616 case Opt_fault_type:
617 if (args->from && match_int(args, &arg))
618 return -EINVAL;
619#ifdef CONFIG_F2FS_FAULT_INJECTION
620 f2fs_build_fault_attr(sbi, 0, arg);
604 set_opt(sbi, FAULT_INJECTION); 621 set_opt(sbi, FAULT_INJECTION);
605#else 622#else
606 f2fs_msg(sb, KERN_INFO, 623 f2fs_msg(sb, KERN_INFO,
@@ -1321,9 +1338,12 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
1321 if (F2FS_IO_SIZE_BITS(sbi)) 1338 if (F2FS_IO_SIZE_BITS(sbi))
1322 seq_printf(seq, ",io_size=%uKB", F2FS_IO_SIZE_KB(sbi)); 1339 seq_printf(seq, ",io_size=%uKB", F2FS_IO_SIZE_KB(sbi));
1323#ifdef CONFIG_F2FS_FAULT_INJECTION 1340#ifdef CONFIG_F2FS_FAULT_INJECTION
1324 if (test_opt(sbi, FAULT_INJECTION)) 1341 if (test_opt(sbi, FAULT_INJECTION)) {
1325 seq_printf(seq, ",fault_injection=%u", 1342 seq_printf(seq, ",fault_injection=%u",
1326 F2FS_OPTION(sbi).fault_info.inject_rate); 1343 F2FS_OPTION(sbi).fault_info.inject_rate);
1344 seq_printf(seq, ",fault_type=%u",
1345 F2FS_OPTION(sbi).fault_info.inject_type);
1346 }
1327#endif 1347#endif
1328#ifdef CONFIG_QUOTA 1348#ifdef CONFIG_QUOTA
1329 if (test_opt(sbi, QUOTA)) 1349 if (test_opt(sbi, QUOTA))
@@ -1393,7 +1413,7 @@ static void default_options(struct f2fs_sb_info *sbi)
1393 set_opt(sbi, POSIX_ACL); 1413 set_opt(sbi, POSIX_ACL);
1394#endif 1414#endif
1395 1415
1396 f2fs_build_fault_attr(sbi, 0); 1416 f2fs_build_fault_attr(sbi, 0, 0);
1397} 1417}
1398 1418
1399#ifdef CONFIG_QUOTA 1419#ifdef CONFIG_QUOTA