aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Busch <keith.busch@intel.com>2018-04-26 16:22:41 -0400
committerJens Axboe <axboe@kernel.dk>2018-05-03 11:37:50 -0400
commita785dbccd95c37606c720580714f5a7a8b3255f1 (patch)
tree7c361bfe2431b66646e50570137098ecfae0f36f
parent5cadde8019a6a80550fdde92d5a3327565974eab (diff)
nvme/multipath: Fix multipath disabled naming collisions
When CONFIG_NVME_MULTIPATH is set, but we're not using nvme to multipath, namespaces with multiple paths were not creating unique names due to reusing the same instance number from the namespace's head. This patch fixes this by falling back to the non-multipath naming method when the parameter disabled using multipath. Reported-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Keith Busch <keith.busch@intel.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--drivers/nvme/host/core.c26
-rw-r--r--drivers/nvme/host/multipath.c22
-rw-r--r--drivers/nvme/host/nvme.h12
3 files changed, 35 insertions, 25 deletions
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 127a9cbf3314..a3771c5729f5 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -2998,31 +2998,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
2998 if (nvme_init_ns_head(ns, nsid, id)) 2998 if (nvme_init_ns_head(ns, nsid, id))
2999 goto out_free_id; 2999 goto out_free_id;
3000 nvme_setup_streams_ns(ctrl, ns); 3000 nvme_setup_streams_ns(ctrl, ns);
3001 3001 nvme_set_disk_name(disk_name, ns, ctrl, &flags);
3002#ifdef CONFIG_NVME_MULTIPATH
3003 /*
3004 * If multipathing is enabled we need to always use the subsystem
3005 * instance number for numbering our devices to avoid conflicts
3006 * between subsystems that have multiple controllers and thus use
3007 * the multipath-aware subsystem node and those that have a single
3008 * controller and use the controller node directly.
3009 */
3010 if (ns->head->disk) {
3011 sprintf(disk_name, "nvme%dc%dn%d", ctrl->subsys->instance,
3012 ctrl->cntlid, ns->head->instance);
3013 flags = GENHD_FL_HIDDEN;
3014 } else {
3015 sprintf(disk_name, "nvme%dn%d", ctrl->subsys->instance,
3016 ns->head->instance);
3017 }
3018#else
3019 /*
3020 * But without the multipath code enabled, multiple controller per
3021 * subsystems are visible as devices and thus we cannot use the
3022 * subsystem instance.
3023 */
3024 sprintf(disk_name, "nvme%dn%d", ctrl->instance, ns->head->instance);
3025#endif
3026 3002
3027 if ((ctrl->quirks & NVME_QUIRK_LIGHTNVM) && id->vs[0] == 0x1) { 3003 if ((ctrl->quirks & NVME_QUIRK_LIGHTNVM) && id->vs[0] == 0x1) {
3028 if (nvme_nvm_register(ns, disk_name, node)) { 3004 if (nvme_nvm_register(ns, disk_name, node)) {
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index 3ded009e7631..d7b664ae5923 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -19,6 +19,28 @@ module_param(multipath, bool, 0444);
19MODULE_PARM_DESC(multipath, 19MODULE_PARM_DESC(multipath,
20 "turn on native support for multiple controllers per subsystem"); 20 "turn on native support for multiple controllers per subsystem");
21 21
22/*
23 * If multipathing is enabled we need to always use the subsystem instance
24 * number for numbering our devices to avoid conflicts between subsystems that
25 * have multiple controllers and thus use the multipath-aware subsystem node
26 * and those that have a single controller and use the controller node
27 * directly.
28 */
29void nvme_set_disk_name(char *disk_name, struct nvme_ns *ns,
30 struct nvme_ctrl *ctrl, int *flags)
31{
32 if (!multipath) {
33 sprintf(disk_name, "nvme%dn%d", ctrl->instance, ns->head->instance);
34 } else if (ns->head->disk) {
35 sprintf(disk_name, "nvme%dc%dn%d", ctrl->subsys->instance,
36 ctrl->cntlid, ns->head->instance);
37 *flags = GENHD_FL_HIDDEN;
38 } else {
39 sprintf(disk_name, "nvme%dn%d", ctrl->subsys->instance,
40 ns->head->instance);
41 }
42}
43
22void nvme_failover_req(struct request *req) 44void nvme_failover_req(struct request *req)
23{ 45{
24 struct nvme_ns *ns = req->q->queuedata; 46 struct nvme_ns *ns = req->q->queuedata;
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 061fecfd44f5..7ded7a51c430 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -436,6 +436,8 @@ extern const struct attribute_group nvme_ns_id_attr_group;
436extern const struct block_device_operations nvme_ns_head_ops; 436extern const struct block_device_operations nvme_ns_head_ops;
437 437
438#ifdef CONFIG_NVME_MULTIPATH 438#ifdef CONFIG_NVME_MULTIPATH
439void nvme_set_disk_name(char *disk_name, struct nvme_ns *ns,
440 struct nvme_ctrl *ctrl, int *flags);
439void nvme_failover_req(struct request *req); 441void nvme_failover_req(struct request *req);
440bool nvme_req_needs_failover(struct request *req, blk_status_t error); 442bool nvme_req_needs_failover(struct request *req, blk_status_t error);
441void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl); 443void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl);
@@ -461,6 +463,16 @@ static inline void nvme_mpath_check_last_path(struct nvme_ns *ns)
461} 463}
462 464
463#else 465#else
466/*
467 * Without the multipath code enabled, multiple controller per subsystems are
468 * visible as devices and thus we cannot use the subsystem instance.
469 */
470static inline void nvme_set_disk_name(char *disk_name, struct nvme_ns *ns,
471 struct nvme_ctrl *ctrl, int *flags)
472{
473 sprintf(disk_name, "nvme%dn%d", ctrl->instance, ns->head->instance);
474}
475
464static inline void nvme_failover_req(struct request *req) 476static inline void nvme_failover_req(struct request *req)
465{ 477{
466} 478}