diff options
Diffstat (limited to 'drivers/nvme')
-rw-r--r-- | drivers/nvme/target/admin-cmd.c | 6 | ||||
-rw-r--r-- | drivers/nvme/target/configfs.c | 27 | ||||
-rw-r--r-- | drivers/nvme/target/nvmet.h | 1 |
3 files changed, 29 insertions, 5 deletions
diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c index 9c73dbfb8228..5f15c3285a5b 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c @@ -337,6 +337,12 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req) u32 cmd_capsule_size; u16 status = 0; + if (!subsys->subsys_discovered) { + mutex_lock(&subsys->lock); + subsys->subsys_discovered = true; + 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. diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c index 027b28aaf7cd..a13da86fb374 100644 --- a/drivers/nvme/target/configfs.c +++ b/drivers/nvme/target/configfs.c @@ -1044,12 +1044,18 @@ static ssize_t nvmet_subsys_attr_serial_show(struct config_item *item, return snprintf(page, PAGE_SIZE, "%s\n", subsys->serial); } -static ssize_t nvmet_subsys_attr_serial_store(struct config_item *item, - const char *page, size_t count) +static ssize_t +nvmet_subsys_attr_serial_store_locked(struct nvmet_subsys *subsys, + const char *page, size_t count) { - struct nvmet_subsys *subsys = to_subsys(item); int pos, len = strcspn(page, "\n"); + if (subsys->subsys_discovered) { + pr_err("Can't set serial number. %s is already assigned\n", + subsys->serial); + return -EINVAL; + } + if (!len || len > NVMET_SN_MAX_SIZE) { pr_err("Serial Number can not be empty or exceed %d Bytes\n", NVMET_SN_MAX_SIZE); @@ -1063,13 +1069,24 @@ static ssize_t nvmet_subsys_attr_serial_store(struct config_item *item, } } + memcpy_and_pad(subsys->serial, NVMET_SN_MAX_SIZE, page, len, ' '); + + return count; +} + +static ssize_t nvmet_subsys_attr_serial_store(struct config_item *item, + const char *page, size_t count) +{ + struct nvmet_subsys *subsys = to_subsys(item); + ssize_t ret; + down_write(&nvmet_config_sem); mutex_lock(&subsys->lock); - memcpy_and_pad(subsys->serial, NVMET_SN_MAX_SIZE, page, len, ' '); + ret = nvmet_subsys_attr_serial_store_locked(subsys, page, count); mutex_unlock(&subsys->lock); up_write(&nvmet_config_sem); - return count; + return ret; } CONFIGFS_ATTR(nvmet_subsys_, attr_serial); diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index 0ae809ca428c..bd0a0b91d843 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -231,6 +231,7 @@ struct nvmet_subsys { u64 ver; char serial[NVMET_SN_MAX_SIZE]; + bool subsys_discovered; char *subsysnqn; bool pi_support; |