1 // SPDX-License-Identifier: GPL-2.0-only
2 #include <linux/module.h>
4 #include "notifier-error-inject.h"
6 static int debugfs_errno_set(void *data
, u64 val
)
8 *(int *)data
= clamp_t(int, val
, -MAX_ERRNO
, 0);
12 static int debugfs_errno_get(void *data
, u64
*val
)
18 DEFINE_SIMPLE_ATTRIBUTE(fops_errno
, debugfs_errno_get
, debugfs_errno_set
,
21 static struct dentry
*debugfs_create_errno(const char *name
, umode_t mode
,
22 struct dentry
*parent
, int *value
)
24 return debugfs_create_file(name
, mode
, parent
, value
, &fops_errno
);
27 static int notifier_err_inject_callback(struct notifier_block
*nb
,
28 unsigned long val
, void *p
)
31 struct notifier_err_inject
*err_inject
=
32 container_of(nb
, struct notifier_err_inject
, nb
);
33 struct notifier_err_inject_action
*action
;
35 for (action
= err_inject
->actions
; action
->name
; action
++) {
36 if (action
->val
== val
) {
42 pr_info("Injecting error (%d) to %s\n", err
, action
->name
);
44 return notifier_from_errno(err
);
47 struct dentry
*notifier_err_inject_dir
;
48 EXPORT_SYMBOL_GPL(notifier_err_inject_dir
);
50 struct dentry
*notifier_err_inject_init(const char *name
, struct dentry
*parent
,
51 struct notifier_err_inject
*err_inject
, int priority
)
53 struct notifier_err_inject_action
*action
;
54 umode_t mode
= S_IFREG
| S_IRUSR
| S_IWUSR
;
56 struct dentry
*actions_dir
;
58 err_inject
->nb
.notifier_call
= notifier_err_inject_callback
;
59 err_inject
->nb
.priority
= priority
;
61 dir
= debugfs_create_dir(name
, parent
);
63 actions_dir
= debugfs_create_dir("actions", dir
);
65 for (action
= err_inject
->actions
; action
->name
; action
++) {
66 struct dentry
*action_dir
;
68 action_dir
= debugfs_create_dir(action
->name
, actions_dir
);
71 * Create debugfs r/w file containing action->error. If
72 * notifier call chain is called with action->val, it will
73 * fail with the error code
75 debugfs_create_errno("error", mode
, action_dir
, &action
->error
);
79 EXPORT_SYMBOL_GPL(notifier_err_inject_init
);
81 static int __init
err_inject_init(void)
83 notifier_err_inject_dir
=
84 debugfs_create_dir("notifier-error-inject", NULL
);
86 if (!notifier_err_inject_dir
)
92 static void __exit
err_inject_exit(void)
94 debugfs_remove_recursive(notifier_err_inject_dir
);
97 module_init(err_inject_init
);
98 module_exit(err_inject_exit
);
100 MODULE_DESCRIPTION("Notifier error injection module");
101 MODULE_LICENSE("GPL");
102 MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>");