Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

nvme: prepare for fault injection into admin commands

Currenlty fault injection support for nvme only enables to inject errors
into the commands submitted to I/O queues.

In preparation for fault injection into the admin commands, this makes
the helper functions independent of struct nvme_ns.

Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Reviewed-by: Minwoo Im <minwoo.im.dev@gmail.com>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>

authored by

Akinobu Mita and committed by
Christoph Hellwig
a3646451 a5448fdc

+41 -33
+2 -2
drivers/nvme/host/core.c
··· 3336 3336 device_add_disk(ctrl->device, ns->disk, nvme_ns_id_attr_groups); 3337 3337 3338 3338 nvme_mpath_add_disk(ns, id); 3339 - nvme_fault_inject_init(ns); 3339 + nvme_fault_inject_init(&ns->fault_inject, ns->disk->disk_name); 3340 3340 kfree(id); 3341 3341 3342 3342 return 0; ··· 3361 3361 if (test_and_set_bit(NVME_NS_REMOVING, &ns->flags)) 3362 3362 return; 3363 3363 3364 - nvme_fault_inject_fini(ns); 3364 + nvme_fault_inject_fini(&ns->fault_inject); 3365 3365 3366 3366 mutex_lock(&ns->ctrl->subsys->lock); 3367 3367 list_del_rcu(&ns->siblings);
+20 -16
drivers/nvme/host/fault_inject.c
··· 15 15 static char *fail_request; 16 16 module_param(fail_request, charp, 0000); 17 17 18 - void nvme_fault_inject_init(struct nvme_ns *ns) 18 + void nvme_fault_inject_init(struct nvme_fault_inject *fault_inj, 19 + const char *dev_name) 19 20 { 20 21 struct dentry *dir, *parent; 21 - char *name = ns->disk->disk_name; 22 - struct nvme_fault_inject *fault_inj = &ns->fault_inject; 23 22 struct fault_attr *attr = &fault_inj->attr; 24 23 25 24 /* set default fault injection attribute */ ··· 26 27 setup_fault_attr(&fail_default_attr, fail_request); 27 28 28 29 /* create debugfs directory and attribute */ 29 - parent = debugfs_create_dir(name, NULL); 30 + parent = debugfs_create_dir(dev_name, NULL); 30 31 if (!parent) { 31 - pr_warn("%s: failed to create debugfs directory\n", name); 32 + pr_warn("%s: failed to create debugfs directory\n", dev_name); 32 33 return; 33 34 } 34 35 35 36 *attr = fail_default_attr; 36 37 dir = fault_create_debugfs_attr("fault_inject", parent, attr); 37 38 if (IS_ERR(dir)) { 38 - pr_warn("%s: failed to create debugfs attr\n", name); 39 + pr_warn("%s: failed to create debugfs attr\n", dev_name); 39 40 debugfs_remove_recursive(parent); 40 41 return; 41 42 } 42 - ns->fault_inject.parent = parent; 43 + fault_inj->parent = parent; 43 44 44 45 /* create debugfs for status code and dont_retry */ 45 46 fault_inj->status = NVME_SC_INVALID_OPCODE; ··· 48 49 debugfs_create_bool("dont_retry", 0600, dir, &fault_inj->dont_retry); 49 50 } 50 51 51 - void nvme_fault_inject_fini(struct nvme_ns *ns) 52 + void nvme_fault_inject_fini(struct nvme_fault_inject *fault_inject) 52 53 { 53 54 /* remove debugfs directories */ 54 - debugfs_remove_recursive(ns->fault_inject.parent); 55 + debugfs_remove_recursive(fault_inject->parent); 55 56 } 56 57 57 58 void nvme_should_fail(struct request *req) 58 59 { 59 60 struct gendisk *disk = req->rq_disk; 60 - struct nvme_ns *ns = NULL; 61 + struct nvme_fault_inject *fault_inject = NULL; 61 62 u16 status; 62 63 63 64 /* 64 65 * make sure this request is coming from a valid namespace 65 66 */ 66 - if (!disk) 67 - return; 67 + if (disk) { 68 + struct nvme_ns *ns = disk->private_data; 68 69 69 - ns = disk->private_data; 70 - if (ns && should_fail(&ns->fault_inject.attr, 1)) { 70 + if (ns) 71 + fault_inject = &ns->fault_inject; 72 + else 73 + WARN_ONCE(1, "No namespace found for request\n"); 74 + } 75 + 76 + if (fault_inject && should_fail(&fault_inject->attr, 1)) { 71 77 /* inject status code and DNR bit */ 72 - status = ns->fault_inject.status; 73 - if (ns->fault_inject.dont_retry) 78 + status = fault_inject->status; 79 + if (fault_inject->dont_retry) 74 80 status |= NVME_SC_DNR; 75 81 nvme_req(req)->status = status; 76 82 }
+19 -15
drivers/nvme/host/nvme.h
··· 146 146 NVME_CTRL_DEAD, 147 147 }; 148 148 149 + struct nvme_fault_inject { 150 + #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS 151 + struct fault_attr attr; 152 + struct dentry *parent; 153 + bool dont_retry; /* DNR, do not retry */ 154 + u16 status; /* status code */ 155 + #endif 156 + }; 157 + 149 158 struct nvme_ctrl { 150 159 bool comp_seen; 151 160 enum nvme_ctrl_state state; ··· 322 313 #endif 323 314 }; 324 315 325 - #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS 326 - struct nvme_fault_inject { 327 - struct fault_attr attr; 328 - struct dentry *parent; 329 - bool dont_retry; /* DNR, do not retry */ 330 - u16 status; /* status code */ 331 - }; 332 - #endif 333 - 334 316 struct nvme_ns { 335 317 struct list_head list; 336 318 ··· 349 349 #define NVME_NS_ANA_PENDING 2 350 350 u16 noiob; 351 351 352 - #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS 353 352 struct nvme_fault_inject fault_inject; 354 - #endif 355 353 356 354 }; 357 355 ··· 370 372 }; 371 373 372 374 #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS 373 - void nvme_fault_inject_init(struct nvme_ns *ns); 374 - void nvme_fault_inject_fini(struct nvme_ns *ns); 375 + void nvme_fault_inject_init(struct nvme_fault_inject *fault_inj, 376 + const char *dev_name); 377 + void nvme_fault_inject_fini(struct nvme_fault_inject *fault_inject); 375 378 void nvme_should_fail(struct request *req); 376 379 #else 377 - static inline void nvme_fault_inject_init(struct nvme_ns *ns) {} 378 - static inline void nvme_fault_inject_fini(struct nvme_ns *ns) {} 380 + static inline void nvme_fault_inject_init(struct nvme_fault_inject *fault_inj, 381 + const char *dev_name) 382 + { 383 + } 384 + static inline void nvme_fault_inject_fini(struct nvme_fault_inject *fault_inj) 385 + { 386 + } 379 387 static inline void nvme_should_fail(struct request *req) {} 380 388 #endif 381 389