Skip to content

Commit

Permalink
nvmet: allow mn change if subsys not discovered
Browse files Browse the repository at this point in the history
Currently, once the subsystem's model_number is set for the first time
there is no way to change it. However, as long as no connection was
established to nvmf target, there is no reason for such restriction and
we should allow to change the subsystem's model_number as many times as
needed.

In addition, in order to simplfy the changes and make the model number
flow more similar to the rest of the attributes in the Identify
Controller data structure, we set a default value for the model number
at the initiation of the subsystem.

Reviewed-by: Max Gurtovoy <mgurtovoy@nvidia.com>
Signed-off-by: Noam Gottlieb <ngottlieb@nvidia.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
  • Loading branch information
Noam Gottlieb authored and Christoph Hellwig committed Jun 17, 2021
1 parent 7ae023c commit 0d148ef
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 40 deletions.
26 changes: 0 additions & 26 deletions drivers/nvme/target/admin-cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,22 +313,6 @@ static void nvmet_execute_get_log_page(struct nvmet_req *req)
nvmet_req_complete(req, NVME_SC_INVALID_FIELD | NVME_SC_DNR);
}

static u16 nvmet_set_model_number(struct nvmet_subsys *subsys)
{
u16 status = 0;

mutex_lock(&subsys->lock);
if (!subsys->model_number) {
subsys->model_number =
kstrdup(NVMET_DEFAULT_CTRL_MODEL, GFP_KERNEL);
if (!subsys->model_number)
status = NVME_SC_INTERNAL;
}
mutex_unlock(&subsys->lock);

return status;
}

static void nvmet_execute_identify_ctrl(struct nvmet_req *req)
{
struct nvmet_ctrl *ctrl = req->sq->ctrl;
Expand All @@ -343,16 +327,6 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req)
mutex_unlock(&subsys->lock);
}

/*
* If there is no model number yet, set it now. It will then remain
* stable for the life time of the subsystem.
*/
if (!subsys->model_number) {
status = nvmet_set_model_number(subsys);
if (status)
goto out;
}

id = kzalloc(sizeof(*id), GFP_KERNEL);
if (!id) {
status = NVME_SC_INTERNAL;
Expand Down
10 changes: 2 additions & 8 deletions drivers/nvme/target/configfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1154,22 +1154,16 @@ static ssize_t nvmet_subsys_attr_model_show(struct config_item *item,
char *page)
{
struct nvmet_subsys *subsys = to_subsys(item);
int ret;

mutex_lock(&subsys->lock);
ret = snprintf(page, PAGE_SIZE, "%s\n", subsys->model_number ?
subsys->model_number : NVMET_DEFAULT_CTRL_MODEL);
mutex_unlock(&subsys->lock);

return ret;
return snprintf(page, PAGE_SIZE, "%s\n", subsys->model_number);
}

static ssize_t nvmet_subsys_attr_model_store_locked(struct nvmet_subsys *subsys,
const char *page, size_t count)
{
int pos = 0, len;

if (subsys->model_number) {
if (subsys->subsys_discovered) {
pr_err("Can't set model number. %s is already assigned\n",
subsys->model_number);
return -EINVAL;
Expand Down
21 changes: 17 additions & 4 deletions drivers/nvme/target/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1494,6 +1494,7 @@ struct nvmet_subsys *nvmet_subsys_alloc(const char *subsysnqn,
{
struct nvmet_subsys *subsys;
char serial[NVMET_SN_MAX_SIZE / 2];
int ret;

subsys = kzalloc(sizeof(*subsys), GFP_KERNEL);
if (!subsys)
Expand All @@ -1504,6 +1505,12 @@ struct nvmet_subsys *nvmet_subsys_alloc(const char *subsysnqn,
get_random_bytes(&serial, sizeof(serial));
bin2hex(subsys->serial, &serial, sizeof(serial));

subsys->model_number = kstrdup(NVMET_DEFAULT_CTRL_MODEL, GFP_KERNEL);
if (!subsys->model_number) {
ret = -ENOMEM;
goto free_subsys;
}

switch (type) {
case NVME_NQN_NVME:
subsys->max_qid = NVMET_NR_QUEUES;
Expand All @@ -1513,15 +1520,15 @@ struct nvmet_subsys *nvmet_subsys_alloc(const char *subsysnqn,
break;
default:
pr_err("%s: Unknown Subsystem type - %d\n", __func__, type);
kfree(subsys);
return ERR_PTR(-EINVAL);
ret = -EINVAL;
goto free_mn;
}
subsys->type = type;
subsys->subsysnqn = kstrndup(subsysnqn, NVMF_NQN_SIZE,
GFP_KERNEL);
if (!subsys->subsysnqn) {
kfree(subsys);
return ERR_PTR(-ENOMEM);
ret = -ENOMEM;
goto free_mn;
}
subsys->cntlid_min = NVME_CNTLID_MIN;
subsys->cntlid_max = NVME_CNTLID_MAX;
Expand All @@ -1533,6 +1540,12 @@ struct nvmet_subsys *nvmet_subsys_alloc(const char *subsysnqn,
INIT_LIST_HEAD(&subsys->hosts);

return subsys;

free_mn:
kfree(subsys->model_number);
free_subsys:
kfree(subsys);
return ERR_PTR(ret);
}

static void nvmet_subsys_free(struct kref *ref)
Expand Down
4 changes: 2 additions & 2 deletions drivers/nvme/target/discovery.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,6 @@ static void nvmet_execute_disc_identify(struct nvmet_req *req)
{
struct nvmet_ctrl *ctrl = req->sq->ctrl;
struct nvme_id_ctrl *id;
const char model[] = "Linux";
u16 status = 0;

if (!nvmet_check_transfer_len(req, NVME_IDENTIFY_DATA_SIZE))
Expand All @@ -264,7 +263,8 @@ static void nvmet_execute_disc_identify(struct nvmet_req *req)

memcpy(id->sn, ctrl->subsys->serial, NVMET_SN_MAX_SIZE);
memset(id->fr, ' ', sizeof(id->fr));
memcpy_and_pad(id->mn, sizeof(id->mn), model, sizeof(model) - 1, ' ');
memcpy_and_pad(id->mn, sizeof(id->mn), ctrl->subsys->model_number,
strlen(ctrl->subsys->model_number), ' ');
memcpy_and_pad(id->fr, sizeof(id->fr),
UTS_RELEASE, strlen(UTS_RELEASE), ' ');

Expand Down

0 comments on commit 0d148ef

Please sign in to comment.