Skip to content

Commit 94a39d6

Browse files
ChaitanayaKulkarnikeithbusch
authored andcommitted
nvmet: make ctrl-id configurable
This patch adds a new target subsys attribute which allows user to optionally specify target controller IDs which then used in the nvmet_execute_identify_ctrl() to fill up the nvme_id_ctrl structure. For example, when using a cluster setup with two nodes, with a dual ported NVMe drive and exporting the drive from both the nodes, The connection to the host fails due to the same controller ID and results in the following error message:- "nvme nvmeX: Duplicate cntlid XXX with nvmeX, rejecting" With this patch now user can partition the controller IDs for each subsystem by setting up the cntlid_min and cntlid_max. These values will be used at the time of the controller ID creation. By partitioning the ctrl-ids for each subsystem results in the unique ctrl-id space which avoids the collision. When new attribute is not specified target will fall back to original cntlid calculation method. Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: Chaitanya Kulkarni <[email protected]> Signed-off-by: Keith Busch <[email protected]>
1 parent 527123c commit 94a39d6

File tree

3 files changed

+70
-2
lines changed

3 files changed

+70
-2
lines changed

drivers/nvme/target/configfs.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -859,10 +859,72 @@ static ssize_t nvmet_subsys_attr_serial_store(struct config_item *item,
859859
}
860860
CONFIGFS_ATTR(nvmet_subsys_, attr_serial);
861861

862+
static ssize_t nvmet_subsys_attr_cntlid_min_show(struct config_item *item,
863+
char *page)
864+
{
865+
return snprintf(page, PAGE_SIZE, "%u\n", to_subsys(item)->cntlid_min);
866+
}
867+
868+
static ssize_t nvmet_subsys_attr_cntlid_min_store(struct config_item *item,
869+
const char *page, size_t cnt)
870+
{
871+
u16 cntlid_min;
872+
873+
if (sscanf(page, "%hu\n", &cntlid_min) != 1)
874+
return -EINVAL;
875+
876+
if (cntlid_min == 0)
877+
return -EINVAL;
878+
879+
down_write(&nvmet_config_sem);
880+
if (cntlid_min >= to_subsys(item)->cntlid_max)
881+
goto out_unlock;
882+
to_subsys(item)->cntlid_min = cntlid_min;
883+
up_write(&nvmet_config_sem);
884+
return cnt;
885+
886+
out_unlock:
887+
up_write(&nvmet_config_sem);
888+
return -EINVAL;
889+
}
890+
CONFIGFS_ATTR(nvmet_subsys_, attr_cntlid_min);
891+
892+
static ssize_t nvmet_subsys_attr_cntlid_max_show(struct config_item *item,
893+
char *page)
894+
{
895+
return snprintf(page, PAGE_SIZE, "%u\n", to_subsys(item)->cntlid_max);
896+
}
897+
898+
static ssize_t nvmet_subsys_attr_cntlid_max_store(struct config_item *item,
899+
const char *page, size_t cnt)
900+
{
901+
u16 cntlid_max;
902+
903+
if (sscanf(page, "%hu\n", &cntlid_max) != 1)
904+
return -EINVAL;
905+
906+
if (cntlid_max == 0)
907+
return -EINVAL;
908+
909+
down_write(&nvmet_config_sem);
910+
if (cntlid_max <= to_subsys(item)->cntlid_min)
911+
goto out_unlock;
912+
to_subsys(item)->cntlid_max = cntlid_max;
913+
up_write(&nvmet_config_sem);
914+
return cnt;
915+
916+
out_unlock:
917+
up_write(&nvmet_config_sem);
918+
return -EINVAL;
919+
}
920+
CONFIGFS_ATTR(nvmet_subsys_, attr_cntlid_max);
921+
862922
static struct configfs_attribute *nvmet_subsys_attrs[] = {
863923
&nvmet_subsys_attr_attr_allow_any_host,
864924
&nvmet_subsys_attr_attr_version,
865925
&nvmet_subsys_attr_attr_serial,
926+
&nvmet_subsys_attr_attr_cntlid_min,
927+
&nvmet_subsys_attr_attr_cntlid_max,
866928
NULL,
867929
};
868930

drivers/nvme/target/core.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,8 +1289,11 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn,
12891289
if (!ctrl->sqs)
12901290
goto out_free_cqs;
12911291

1292+
if (subsys->cntlid_min > subsys->cntlid_max)
1293+
goto out_free_cqs;
1294+
12921295
ret = ida_simple_get(&cntlid_ida,
1293-
NVME_CNTLID_MIN, NVME_CNTLID_MAX,
1296+
subsys->cntlid_min, subsys->cntlid_max,
12941297
GFP_KERNEL);
12951298
if (ret < 0) {
12961299
status = NVME_SC_CONNECT_CTRL_BUSY | NVME_SC_DNR;
@@ -1438,7 +1441,8 @@ struct nvmet_subsys *nvmet_subsys_alloc(const char *subsysnqn,
14381441
kfree(subsys);
14391442
return ERR_PTR(-ENOMEM);
14401443
}
1441-
1444+
subsys->cntlid_min = NVME_CNTLID_MIN;
1445+
subsys->cntlid_max = NVME_CNTLID_MAX;
14421446
kref_init(&subsys->ref);
14431447

14441448
mutex_init(&subsys->lock);

drivers/nvme/target/nvmet.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,8 @@ struct nvmet_subsys {
211211
struct list_head namespaces;
212212
unsigned int nr_namespaces;
213213
unsigned int max_nsid;
214+
u16 cntlid_min;
215+
u16 cntlid_max;
214216

215217
struct list_head ctrls;
216218

0 commit comments

Comments
 (0)