2 * fault injection support for nvme.
4 * Copyright (c) 2018, Oracle and/or its affiliates
8 #include <linux/moduleparam.h>
11 static DECLARE_FAULT_ATTR(fail_default_attr
);
12 /* optional fault injection attributes boot time option:
13 * nvme_core.fail_request=<interval>,<probability>,<space>,<times>
15 static char *fail_request
;
16 module_param(fail_request
, charp
, 0000);
18 void nvme_fault_inject_init(struct nvme_ns
*ns
)
20 struct dentry
*dir
, *parent
;
21 char *name
= ns
->disk
->disk_name
;
22 struct nvme_fault_inject
*fault_inj
= &ns
->fault_inject
;
23 struct fault_attr
*attr
= &fault_inj
->attr
;
25 /* set default fault injection attribute */
27 setup_fault_attr(&fail_default_attr
, fail_request
);
29 /* create debugfs directory and attribute */
30 parent
= debugfs_create_dir(name
, NULL
);
32 pr_warn("%s: failed to create debugfs directory\n", name
);
36 *attr
= fail_default_attr
;
37 dir
= fault_create_debugfs_attr("fault_inject", parent
, attr
);
39 pr_warn("%s: failed to create debugfs attr\n", name
);
40 debugfs_remove_recursive(parent
);
43 ns
->fault_inject
.parent
= parent
;
45 /* create debugfs for status code and dont_retry */
46 fault_inj
->status
= NVME_SC_INVALID_OPCODE
;
47 fault_inj
->dont_retry
= true;
48 debugfs_create_x16("status", 0600, dir
, &fault_inj
->status
);
49 debugfs_create_bool("dont_retry", 0600, dir
, &fault_inj
->dont_retry
);
52 void nvme_fault_inject_fini(struct nvme_ns
*ns
)
54 /* remove debugfs directories */
55 debugfs_remove_recursive(ns
->fault_inject
.parent
);
58 void nvme_should_fail(struct request
*req
)
60 struct gendisk
*disk
= req
->rq_disk
;
61 struct nvme_ns
*ns
= NULL
;
65 * make sure this request is coming from a valid namespace
70 ns
= disk
->private_data
;
71 if (ns
&& should_fail(&ns
->fault_inject
.attr
, 1)) {
72 /* inject status code and DNR bit */
73 status
= ns
->fault_inject
.status
;
74 if (ns
->fault_inject
.dont_retry
)
75 status
|= NVME_SC_DNR
;
76 nvme_req(req
)->status
= status
;
79 EXPORT_SYMBOL_GPL(nvme_should_fail
);