1 // SPDX-License-Identifier: GPL-2.0
3 * fault injection support for nvme.
5 * 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_fault_inject
*fault_inj
,
21 struct dentry
*dir
, *parent
;
22 struct fault_attr
*attr
= &fault_inj
->attr
;
24 /* set default fault injection attribute */
26 setup_fault_attr(&fail_default_attr
, fail_request
);
28 /* create debugfs directory and attribute */
29 parent
= debugfs_create_dir(dev_name
, NULL
);
31 pr_warn("%s: failed to create debugfs directory\n", dev_name
);
35 *attr
= fail_default_attr
;
36 dir
= fault_create_debugfs_attr("fault_inject", parent
, attr
);
38 pr_warn("%s: failed to create debugfs attr\n", dev_name
);
39 debugfs_remove_recursive(parent
);
42 fault_inj
->parent
= parent
;
44 /* create debugfs for status code and dont_retry */
45 fault_inj
->status
= NVME_SC_INVALID_OPCODE
;
46 fault_inj
->dont_retry
= true;
47 debugfs_create_x16("status", 0600, dir
, &fault_inj
->status
);
48 debugfs_create_bool("dont_retry", 0600, dir
, &fault_inj
->dont_retry
);
51 void nvme_fault_inject_fini(struct nvme_fault_inject
*fault_inject
)
53 /* remove debugfs directories */
54 debugfs_remove_recursive(fault_inject
->parent
);
57 void nvme_should_fail(struct request
*req
)
59 struct gendisk
*disk
= req
->rq_disk
;
60 struct nvme_fault_inject
*fault_inject
= NULL
;
64 struct nvme_ns
*ns
= disk
->private_data
;
67 fault_inject
= &ns
->fault_inject
;
69 WARN_ONCE(1, "No namespace found for request\n");
71 fault_inject
= &nvme_req(req
)->ctrl
->fault_inject
;
74 if (fault_inject
&& should_fail(&fault_inject
->attr
, 1)) {
75 /* inject status code and DNR bit */
76 status
= fault_inject
->status
;
77 if (fault_inject
->dont_retry
)
78 status
|= NVME_SC_DNR
;
79 nvme_req(req
)->status
= status
;
82 EXPORT_SYMBOL_GPL(nvme_should_fail
);