1 #include <linux/module.h>
3 #include "notifier-error-inject.h"
5 static int debugfs_errno_set(void *data
, u64 val
)
7 *(int *)data
= clamp_t(int, val
, -MAX_ERRNO
, 0);
11 static int debugfs_errno_get(void *data
, u64
*val
)
17 DEFINE_SIMPLE_ATTRIBUTE(fops_errno
, debugfs_errno_get
, debugfs_errno_set
,
20 static struct dentry
*debugfs_create_errno(const char *name
, umode_t mode
,
21 struct dentry
*parent
, int *value
)
23 return debugfs_create_file(name
, mode
, parent
, value
, &fops_errno
);
26 static int notifier_err_inject_callback(struct notifier_block
*nb
,
27 unsigned long val
, void *p
)
30 struct notifier_err_inject
*err_inject
=
31 container_of(nb
, struct notifier_err_inject
, nb
);
32 struct notifier_err_inject_action
*action
;
34 for (action
= err_inject
->actions
; action
->name
; action
++) {
35 if (action
->val
== val
) {
41 pr_info("Injecting error (%d) to %s\n", err
, action
->name
);
43 return notifier_from_errno(err
);
46 struct dentry
*notifier_err_inject_dir
;
47 EXPORT_SYMBOL_GPL(notifier_err_inject_dir
);
49 struct dentry
*notifier_err_inject_init(const char *name
, struct dentry
*parent
,
50 struct notifier_err_inject
*err_inject
, int priority
)
52 struct notifier_err_inject_action
*action
;
53 umode_t mode
= S_IFREG
| S_IRUSR
| S_IWUSR
;
55 struct dentry
*actions_dir
;
57 err_inject
->nb
.notifier_call
= notifier_err_inject_callback
;
58 err_inject
->nb
.priority
= priority
;
60 dir
= debugfs_create_dir(name
, parent
);
62 return ERR_PTR(-ENOMEM
);
64 actions_dir
= debugfs_create_dir("actions", dir
);
68 for (action
= err_inject
->actions
; action
->name
; action
++) {
69 struct dentry
*action_dir
;
71 action_dir
= debugfs_create_dir(action
->name
, actions_dir
);
76 * Create debugfs r/w file containing action->error. If
77 * notifier call chain is called with action->val, it will
78 * fail with the error code
80 if (!debugfs_create_errno("error", mode
, action_dir
,
86 debugfs_remove_recursive(dir
);
87 return ERR_PTR(-ENOMEM
);
89 EXPORT_SYMBOL_GPL(notifier_err_inject_init
);
91 static int __init
err_inject_init(void)
93 notifier_err_inject_dir
=
94 debugfs_create_dir("notifier-error-inject", NULL
);
96 if (!notifier_err_inject_dir
)
102 static void __exit
err_inject_exit(void)
104 debugfs_remove_recursive(notifier_err_inject_dir
);
107 module_init(err_inject_init
);
108 module_exit(err_inject_exit
);
110 MODULE_DESCRIPTION("Notifier error injection module");
111 MODULE_LICENSE("GPL");
112 MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>");