|
@@ -42,6 +42,22 @@
|
|
#define DBG_BUGON(...) ((void)0)
|
|
#define DBG_BUGON(...) ((void)0)
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+#ifdef CONFIG_EROFS_FAULT_INJECTION
|
|
|
|
+enum {
|
|
|
|
+ FAULT_KMALLOC,
|
|
|
|
+ FAULT_MAX,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+extern char *erofs_fault_name[FAULT_MAX];
|
|
|
|
+#define IS_FAULT_SET(fi, type) ((fi)->inject_type & (1 << (type)))
|
|
|
|
+
|
|
|
|
+struct erofs_fault_info {
|
|
|
|
+ atomic_t inject_ops;
|
|
|
|
+ unsigned int inject_rate;
|
|
|
|
+ unsigned int inject_type;
|
|
|
|
+};
|
|
|
|
+#endif
|
|
|
|
+
|
|
/* EROFS_SUPER_MAGIC_V1 to represent the whole file system */
|
|
/* EROFS_SUPER_MAGIC_V1 to represent the whole file system */
|
|
#define EROFS_SUPER_MAGIC EROFS_SUPER_MAGIC_V1
|
|
#define EROFS_SUPER_MAGIC EROFS_SUPER_MAGIC_V1
|
|
|
|
|
|
@@ -70,14 +86,55 @@ struct erofs_sb_info {
|
|
char *dev_name;
|
|
char *dev_name;
|
|
|
|
|
|
unsigned int mount_opt;
|
|
unsigned int mount_opt;
|
|
|
|
+
|
|
|
|
+#ifdef CONFIG_EROFS_FAULT_INJECTION
|
|
|
|
+ struct erofs_fault_info fault_info; /* For fault injection */
|
|
|
|
+#endif
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+#ifdef CONFIG_EROFS_FAULT_INJECTION
|
|
|
|
+#define erofs_show_injection_info(type) \
|
|
|
|
+ infoln("inject %s in %s of %pS", erofs_fault_name[type], \
|
|
|
|
+ __func__, __builtin_return_address(0))
|
|
|
|
+
|
|
|
|
+static inline bool time_to_inject(struct erofs_sb_info *sbi, int type)
|
|
|
|
+{
|
|
|
|
+ struct erofs_fault_info *ffi = &sbi->fault_info;
|
|
|
|
+
|
|
|
|
+ if (!ffi->inject_rate)
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ if (!IS_FAULT_SET(ffi, type))
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ atomic_inc(&ffi->inject_ops);
|
|
|
|
+ if (atomic_read(&ffi->inject_ops) >= ffi->inject_rate) {
|
|
|
|
+ atomic_set(&ffi->inject_ops, 0);
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+static inline void *erofs_kmalloc(struct erofs_sb_info *sbi,
|
|
|
|
+ size_t size, gfp_t flags)
|
|
|
|
+{
|
|
|
|
+#ifdef CONFIG_EROFS_FAULT_INJECTION
|
|
|
|
+ if (time_to_inject(sbi, FAULT_KMALLOC)) {
|
|
|
|
+ erofs_show_injection_info(FAULT_KMALLOC);
|
|
|
|
+ return NULL;
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+ return kmalloc(size, flags);
|
|
|
|
+}
|
|
|
|
+
|
|
#define EROFS_SB(sb) ((struct erofs_sb_info *)(sb)->s_fs_info)
|
|
#define EROFS_SB(sb) ((struct erofs_sb_info *)(sb)->s_fs_info)
|
|
#define EROFS_I_SB(inode) ((struct erofs_sb_info *)(inode)->i_sb->s_fs_info)
|
|
#define EROFS_I_SB(inode) ((struct erofs_sb_info *)(inode)->i_sb->s_fs_info)
|
|
|
|
|
|
/* Mount flags set via mount options or defaults */
|
|
/* Mount flags set via mount options or defaults */
|
|
#define EROFS_MOUNT_XATTR_USER 0x00000010
|
|
#define EROFS_MOUNT_XATTR_USER 0x00000010
|
|
#define EROFS_MOUNT_POSIX_ACL 0x00000020
|
|
#define EROFS_MOUNT_POSIX_ACL 0x00000020
|
|
|
|
+#define EROFS_MOUNT_FAULT_INJECTION 0x00000040
|
|
|
|
|
|
#define clear_opt(sbi, option) ((sbi)->mount_opt &= ~EROFS_MOUNT_##option)
|
|
#define clear_opt(sbi, option) ((sbi)->mount_opt &= ~EROFS_MOUNT_##option)
|
|
#define set_opt(sbi, option) ((sbi)->mount_opt |= EROFS_MOUNT_##option)
|
|
#define set_opt(sbi, option) ((sbi)->mount_opt |= EROFS_MOUNT_##option)
|