@@ -21,3 +21,47 @@ const char *rnbd_access_mode_str(enum rnbd_access_mode mode)
return "unknown";
}
}
+
+#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
+static DECLARE_FAULT_ATTR(fail_default_attr);
+
+void rnbd_fault_inject_init(struct rnbd_fault_inject *fj,
+ const char *dir_name,
+ u32 err_status)
+{
+ struct dentry *dir, *parent;
+ struct fault_attr *attr = &fj->attr;
+
+ /* create debugfs directory and attribute */
+ parent = debugfs_create_dir(dir_name, NULL);
+ if (!parent) {
+ pr_warn("%s: failed to create debugfs directory\n", dir_name);
+ return;
+ }
+
+ *attr = fail_default_attr;
+ dir = fault_create_debugfs_attr("fault_inject", parent, attr);
+ if (IS_ERR(dir)) {
+ pr_warn("%s: failed to create debugfs attr\n", dir_name);
+ debugfs_remove_recursive(parent);
+ return;
+ }
+ fj->parent = parent;
+ fj->dir = dir;
+
+ /* create debugfs for status code */
+ fj->status = err_status;
+ debugfs_create_u32("status", 0600, dir, &fj->status);
+}
+
+void rnbd_fault_inject_add(struct dentry *dir, const char *fname, bool *value)
+{
+ debugfs_create_bool(fname, 0600, dir, value);
+}
+
+void rnbd_fault_inject_final(struct rnbd_fault_inject *fj)
+{
+ /* remove debugfs directories */
+ debugfs_remove_recursive(fj->parent);
+}
+#endif
@@ -15,6 +15,7 @@
#include <linux/inet.h>
#include <linux/in.h>
#include <linux/in6.h>
+#include <linux/fault-inject.h>
#include <rdma/ib.h>
#define RNBD_PROTO_VER_MAJOR 2
@@ -305,6 +306,19 @@ static inline u32 rq_to_rnbd_flags(struct request *rq)
return rnbd_opf;
}
+struct rnbd_fault_inject {
+#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
+ struct fault_attr attr;
+ struct dentry *parent;
+ struct dentry *dir;
+ u32 status;
+#endif
+};
+
const char *rnbd_access_mode_str(enum rnbd_access_mode mode);
+void rnbd_fault_inject_init(struct rnbd_fault_inject *fj,
+ const char *dev_name, u32 err_status);
+void rnbd_fault_inject_add(struct dentry *dir, const char *fname, bool *value);
+void rnbd_fault_inject_final(struct rnbd_fault_inject *fj);
#endif /* RNBD_PROTO_H */