* [PATCH] nvmet: make ctrl model configurable @ 2019-10-30 19:48 Chaitanya Kulkarni 2019-10-30 20:08 ` Mark Ruijter 0 siblings, 1 reply; 10+ messages in thread From: Chaitanya Kulkarni @ 2019-10-30 19:48 UTC (permalink / raw) To: linux-nvme; +Cc: Chaitanya Kulkarni This patch adds a new target subsys attribute which allows user to optionally specify model name which then used in the nvmet_execute_identify_ctrl() to fill up the nvme_id_ctrl structure. Default value for the model is set to "Linux". Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com> --- drivers/nvme/target/admin-cmd.c | 4 ++-- drivers/nvme/target/configfs.c | 29 +++++++++++++++++++++++++++++ drivers/nvme/target/core.c | 6 ++++++ drivers/nvme/target/nvmet.h | 2 ++ 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c index 56c21b501185..917d8f3fded7 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c @@ -315,9 +315,9 @@ static void nvmet_execute_get_log_page(struct nvmet_req *req) static void nvmet_execute_identify_ctrl(struct nvmet_req *req) { struct nvmet_ctrl *ctrl = req->sq->ctrl; + const char *model = ctrl->subsys->model; struct nvme_id_ctrl *id; u16 status = 0; - const char model[] = "Linux"; id = kzalloc(sizeof(*id), GFP_KERNEL); if (!id) { @@ -332,7 +332,7 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req) memset(id->sn, ' ', sizeof(id->sn)); bin2hex(id->sn, &ctrl->subsys->serial, min(sizeof(ctrl->subsys->serial), sizeof(id->sn) / 2)); - memcpy_and_pad(id->mn, sizeof(id->mn), model, sizeof(model) - 1, ' '); + memcpy_and_pad(id->mn, sizeof(id->mn), model, strlen(model), ' '); memcpy_and_pad(id->fr, sizeof(id->fr), UTS_RELEASE, strlen(UTS_RELEASE), ' '); diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c index 98613a45bd3b..e91ebe74c938 100644 --- a/drivers/nvme/target/configfs.c +++ b/drivers/nvme/target/configfs.c @@ -862,10 +862,39 @@ static ssize_t nvmet_subsys_attr_serial_store(struct config_item *item, } CONFIGFS_ATTR(nvmet_subsys_, attr_serial); +static ssize_t nvmet_subsys_attr_model_show(struct config_item *item, + char *page) +{ + struct nvmet_subsys *subsys = to_subsys(item); + + return snprintf(page, PAGE_SIZE, "%s\n", subsys->model); +} + +static ssize_t nvmet_subsys_attr_model_store(struct config_item *item, + const char *page, size_t count) +{ + struct nvmet_subsys *subsys = to_subsys(item); + int ret = 0; + + down_write(&nvmet_config_sem); + kfree(subsys->model); + subsys->model = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (!subsys->model) + ret = -ENOMEM; + else + sscanf(page, "%s\n", subsys->model); + up_write(&nvmet_config_sem); + + return ret ? ret : count; +} + +CONFIGFS_ATTR(nvmet_subsys_, attr_model); + static struct configfs_attribute *nvmet_subsys_attrs[] = { &nvmet_subsys_attr_attr_allow_any_host, &nvmet_subsys_attr_attr_version, &nvmet_subsys_attr_attr_serial, + &nvmet_subsys_attr_attr_model, NULL, }; diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 28438b833c1b..d3e2a1f58a93 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -1394,6 +1394,11 @@ struct nvmet_subsys *nvmet_subsys_alloc(const char *subsysnqn, return ERR_PTR(-ENOMEM); subsys->ver = NVME_VS(1, 3, 0); /* NVMe 1.3.0 */ + + subsys->model = kstrdup(NVMET_DEFAULT_CTRL_MODEL, GFP_KERNEL); + if (!subsys->model) + return ERR_PTR(-ENOMEM); + /* generate a random serial number as our controllers are ephemeral: */ get_random_bytes(&subsys->serial, sizeof(subsys->serial)); @@ -1435,6 +1440,7 @@ static void nvmet_subsys_free(struct kref *ref) WARN_ON_ONCE(!list_empty(&subsys->namespaces)); kfree(subsys->subsysnqn); + kfree(subsys->model); kfree(subsys); } diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index 46df45e837c9..d5fcfd09658e 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -23,6 +23,7 @@ #define NVMET_ASYNC_EVENTS 4 #define NVMET_ERROR_LOG_SLOTS 128 #define NVMET_NO_ERROR_LOC ((u16)-1) +#define NVMET_DEFAULT_CTRL_MODEL "Linux" /* * Supported optional AENs: @@ -227,6 +228,7 @@ struct nvmet_subsys { struct config_group namespaces_group; struct config_group allowed_hosts_group; + char *model; }; static inline struct nvmet_subsys *to_subsys(struct config_item *item) -- 2.22.1 _______________________________________________ Linux-nvme mailing list Linux-nvme@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-nvme ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH] nvmet: make ctrl model configurable 2019-10-30 19:48 [PATCH] nvmet: make ctrl model configurable Chaitanya Kulkarni @ 2019-10-30 20:08 ` Mark Ruijter 2019-10-30 20:09 ` Chaitanya Kulkarni 2019-10-30 21:43 ` Chaitanya Kulkarni 0 siblings, 2 replies; 10+ messages in thread From: Mark Ruijter @ 2019-10-30 20:08 UTC (permalink / raw) To: Chaitanya Kulkarni, linux-nvme Hi Chaitanya, I assume that this change is based on the patch that I send earlier today. You seem to have changed the code that accepts the attr_model input and replaced the input validation with sscanf. What happens when you write a string containing a TAB into the model attribute? The NVM-Express 1.4 document states this on page 13: "Some parameters are defined as an ASCII string. ASCII strings shall contain only code values 20h through 7Eh." As far as I know a TAB is 9h and sscanf(page, "%s\n", subsys->model) allows the TAB. This seems wrong to me? Thanks, Mark Ruijter Op 30-10-19 20:49 heeft Linux-nvme namens Chaitanya Kulkarni <linux-nvme-bounces@lists.infradead.org namens chaitanya.kulkarni@wdc.com> geschreven: This patch adds a new target subsys attribute which allows user to optionally specify model name which then used in the nvmet_execute_identify_ctrl() to fill up the nvme_id_ctrl structure. Default value for the model is set to "Linux". Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com> --- drivers/nvme/target/admin-cmd.c | 4 ++-- drivers/nvme/target/configfs.c | 29 +++++++++++++++++++++++++++++ drivers/nvme/target/core.c | 6 ++++++ drivers/nvme/target/nvmet.h | 2 ++ 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c index 56c21b501185..917d8f3fded7 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c @@ -315,9 +315,9 @@ static void nvmet_execute_get_log_page(struct nvmet_req *req) static void nvmet_execute_identify_ctrl(struct nvmet_req *req) { struct nvmet_ctrl *ctrl = req->sq->ctrl; + const char *model = ctrl->subsys->model; struct nvme_id_ctrl *id; u16 status = 0; - const char model[] = "Linux"; id = kzalloc(sizeof(*id), GFP_KERNEL); if (!id) { @@ -332,7 +332,7 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req) memset(id->sn, ' ', sizeof(id->sn)); bin2hex(id->sn, &ctrl->subsys->serial, min(sizeof(ctrl->subsys->serial), sizeof(id->sn) / 2)); - memcpy_and_pad(id->mn, sizeof(id->mn), model, sizeof(model) - 1, ' '); + memcpy_and_pad(id->mn, sizeof(id->mn), model, strlen(model), ' '); memcpy_and_pad(id->fr, sizeof(id->fr), UTS_RELEASE, strlen(UTS_RELEASE), ' '); diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c index 98613a45bd3b..e91ebe74c938 100644 --- a/drivers/nvme/target/configfs.c +++ b/drivers/nvme/target/configfs.c @@ -862,10 +862,39 @@ static ssize_t nvmet_subsys_attr_serial_store(struct config_item *item, } CONFIGFS_ATTR(nvmet_subsys_, attr_serial); +static ssize_t nvmet_subsys_attr_model_show(struct config_item *item, + char *page) +{ + struct nvmet_subsys *subsys = to_subsys(item); + + return snprintf(page, PAGE_SIZE, "%s\n", subsys->model); +} + +static ssize_t nvmet_subsys_attr_model_store(struct config_item *item, + const char *page, size_t count) +{ + struct nvmet_subsys *subsys = to_subsys(item); + int ret = 0; + + down_write(&nvmet_config_sem); + kfree(subsys->model); + subsys->model = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (!subsys->model) + ret = -ENOMEM; + else + sscanf(page, "%s\n", subsys->model); + up_write(&nvmet_config_sem); + + return ret ? ret : count; +} + +CONFIGFS_ATTR(nvmet_subsys_, attr_model); + static struct configfs_attribute *nvmet_subsys_attrs[] = { &nvmet_subsys_attr_attr_allow_any_host, &nvmet_subsys_attr_attr_version, &nvmet_subsys_attr_attr_serial, + &nvmet_subsys_attr_attr_model, NULL, }; diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 28438b833c1b..d3e2a1f58a93 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -1394,6 +1394,11 @@ struct nvmet_subsys *nvmet_subsys_alloc(const char *subsysnqn, return ERR_PTR(-ENOMEM); subsys->ver = NVME_VS(1, 3, 0); /* NVMe 1.3.0 */ + + subsys->model = kstrdup(NVMET_DEFAULT_CTRL_MODEL, GFP_KERNEL); + if (!subsys->model) + return ERR_PTR(-ENOMEM); + /* generate a random serial number as our controllers are ephemeral: */ get_random_bytes(&subsys->serial, sizeof(subsys->serial)); @@ -1435,6 +1440,7 @@ static void nvmet_subsys_free(struct kref *ref) WARN_ON_ONCE(!list_empty(&subsys->namespaces)); kfree(subsys->subsysnqn); + kfree(subsys->model); kfree(subsys); } diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index 46df45e837c9..d5fcfd09658e 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -23,6 +23,7 @@ #define NVMET_ASYNC_EVENTS 4 #define NVMET_ERROR_LOG_SLOTS 128 #define NVMET_NO_ERROR_LOC ((u16)-1) +#define NVMET_DEFAULT_CTRL_MODEL "Linux" /* * Supported optional AENs: @@ -227,6 +228,7 @@ struct nvmet_subsys { struct config_group namespaces_group; struct config_group allowed_hosts_group; + char *model; }; static inline struct nvmet_subsys *to_subsys(struct config_item *item) -- 2.22.1 _______________________________________________ Linux-nvme mailing list Linux-nvme@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-nvme _______________________________________________ Linux-nvme mailing list Linux-nvme@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-nvme ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] nvmet: make ctrl model configurable 2019-10-30 20:08 ` Mark Ruijter @ 2019-10-30 20:09 ` Chaitanya Kulkarni 2019-10-30 21:43 ` Chaitanya Kulkarni 1 sibling, 0 replies; 10+ messages in thread From: Chaitanya Kulkarni @ 2019-10-30 20:09 UTC (permalink / raw) To: Mark Ruijter, linux-nvme Didn't see your patch, until now. Since you have posted, lets go with yours. Meanwhile posted tests for blktests have a look. On 10/30/2019 01:08 PM, Mark Ruijter wrote: > Hi Chaitanya, > > I assume that this change is based on the patch that I send earlier today. > You seem to have changed the code that accepts the attr_model input and replaced the input validation with sscanf. > What happens when you write a string containing a TAB into the model attribute? > > The NVM-Express 1.4 document states this on page 13: > "Some parameters are defined as an ASCII string. ASCII strings shall contain only code values 20h through 7Eh." > > As far as I know a TAB is 9h and sscanf(page, "%s\n", subsys->model) allows the TAB. > This seems wrong to me? > > Thanks, > > Mark Ruijter _______________________________________________ Linux-nvme mailing list Linux-nvme@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-nvme ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] nvmet: make ctrl model configurable 2019-10-30 20:08 ` Mark Ruijter 2019-10-30 20:09 ` Chaitanya Kulkarni @ 2019-10-30 21:43 ` Chaitanya Kulkarni 1 sibling, 0 replies; 10+ messages in thread From: Chaitanya Kulkarni @ 2019-10-30 21:43 UTC (permalink / raw) To: Mark Ruijter, linux-nvme I'll merge these two patches and send a new one. _______________________________________________ Linux-nvme mailing list Linux-nvme@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-nvme ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH] nvmet: make ctrl model configurable @ 2019-11-01 8:08 Chaitanya Kulkarni 2019-11-11 10:34 ` Christoph Hellwig 2019-11-11 11:09 ` Mark Ruijter 0 siblings, 2 replies; 10+ messages in thread From: Chaitanya Kulkarni @ 2019-11-01 8:08 UTC (permalink / raw) To: linux-nvme; +Cc: hch, Chaitanya Kulkarni, sagi From: Mark Ruijter <MRuijter@onestopsystems.com> This patch adds a new target subsys attribute which allows user to optionally specify model name which then used in the nvmet_execute_identify_ctrl() to fill up the nvme_id_ctrl structure. The default value for the model is set to "Linux" for backward compatibility. Signed-off-by: Mark Ruijter <MRuijter@onestopsystems.com> Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com> --- Hi, This patch is originally posted by Mark and later same day by me with the same concept. I've merged changes from both patch into one and cleaned the code to fit the kernel coding standards. -Regards, Chaitanya --- drivers/nvme/target/admin-cmd.c | 4 +-- drivers/nvme/target/configfs.c | 45 +++++++++++++++++++++++++++++++++ drivers/nvme/target/core.c | 7 +++++ drivers/nvme/target/nvmet.h | 2 ++ 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c index 56c21b501185..917d8f3fded7 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c @@ -315,9 +315,9 @@ static void nvmet_execute_get_log_page(struct nvmet_req *req) static void nvmet_execute_identify_ctrl(struct nvmet_req *req) { struct nvmet_ctrl *ctrl = req->sq->ctrl; + const char *model = ctrl->subsys->model; struct nvme_id_ctrl *id; u16 status = 0; - const char model[] = "Linux"; id = kzalloc(sizeof(*id), GFP_KERNEL); if (!id) { @@ -332,7 +332,7 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req) memset(id->sn, ' ', sizeof(id->sn)); bin2hex(id->sn, &ctrl->subsys->serial, min(sizeof(ctrl->subsys->serial), sizeof(id->sn) / 2)); - memcpy_and_pad(id->mn, sizeof(id->mn), model, sizeof(model) - 1, ' '); + memcpy_and_pad(id->mn, sizeof(id->mn), model, strlen(model), ' '); memcpy_and_pad(id->fr, sizeof(id->fr), UTS_RELEASE, strlen(UTS_RELEASE), ' '); diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c index 98613a45bd3b..faf34b15b975 100644 --- a/drivers/nvme/target/configfs.c +++ b/drivers/nvme/target/configfs.c @@ -862,10 +862,54 @@ static ssize_t nvmet_subsys_attr_serial_store(struct config_item *item, } CONFIGFS_ATTR(nvmet_subsys_, attr_serial); +static ssize_t nvmet_subsys_attr_model_show(struct config_item *item, + char *page) +{ + struct nvmet_subsys *subsys = to_subsys(item); + + return snprintf(page, PAGE_SIZE, "%s\n", subsys->model); +} + +static ssize_t nvmet_subsys_attr_model_store(struct config_item *item, + const char *page, size_t count) +{ + struct nvmet_subsys *subsys = to_subsys(item); + int ret = -EINVAL, pos, len; + char c; + + down_write(&nvmet_config_sem); + len = strcspn(page, "\n"); + if (!len) { + ret = -EINVAL; + goto out_unlock; + } + + /* Only 20h (space) until 7eh (~) is allowed */ + for (pos = 0; pos < len; pos++) { + c = page[pos]; + if (c < 0x20 || c > 0x7e) { + ret = -EINVAL; + goto out_unlock; + } + } + + kfree(subsys->model); + subsys->model = kstrndup(page, len, GFP_KERNEL); + if (!subsys->model) + ret = -ENOMEM; + +out_unlock: + up_write(&nvmet_config_sem); + return ret ? ret : count; +} + +CONFIGFS_ATTR(nvmet_subsys_, attr_model); + static struct configfs_attribute *nvmet_subsys_attrs[] = { &nvmet_subsys_attr_attr_allow_any_host, &nvmet_subsys_attr_attr_version, &nvmet_subsys_attr_attr_serial, + &nvmet_subsys_attr_attr_model, NULL, }; @@ -901,6 +945,7 @@ static struct config_group *nvmet_subsys_make(struct config_group *group, } subsys = nvmet_subsys_alloc(name, NVME_NQN_NVME); + subsys->model = kstrdup(NVMET_DEFAULT_CTRL_MODEL, GFP_KERNEL); if (IS_ERR(subsys)) return ERR_CAST(subsys); diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 28438b833c1b..adc1eb667601 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -1416,6 +1416,12 @@ struct nvmet_subsys *nvmet_subsys_alloc(const char *subsysnqn, kfree(subsys); return ERR_PTR(-ENOMEM); } + subsys->model = kstrdup(NVMET_DEFAULT_CTRL_MODEL, GFP_KERNEL); + if (!subsys->model) { + kfree(subsys->subsysnqn); + kfree(subsys); + return ERR_PTR(-ENOMEM); + } kref_init(&subsys->ref); @@ -1435,6 +1441,7 @@ static void nvmet_subsys_free(struct kref *ref) WARN_ON_ONCE(!list_empty(&subsys->namespaces)); kfree(subsys->subsysnqn); + kfree(subsys->model); kfree(subsys); } diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index 46df45e837c9..afb6116de892 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -23,6 +23,7 @@ #define NVMET_ASYNC_EVENTS 4 #define NVMET_ERROR_LOG_SLOTS 128 #define NVMET_NO_ERROR_LOC ((u16)-1) +#define NVMET_DEFAULT_CTRL_MODEL "Linux" /* * Supported optional AENs: @@ -222,6 +223,7 @@ struct nvmet_subsys { u64 ver; u64 serial; char *subsysnqn; + char *model; struct config_group group; -- 2.22.1 _______________________________________________ Linux-nvme mailing list Linux-nvme@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-nvme ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH] nvmet: make ctrl model configurable 2019-11-01 8:08 Chaitanya Kulkarni @ 2019-11-11 10:34 ` Christoph Hellwig 2019-11-11 13:31 ` Mark Ruijter 2019-11-12 7:06 ` Chaitanya Kulkarni 2019-11-11 11:09 ` Mark Ruijter 1 sibling, 2 replies; 10+ messages in thread From: Christoph Hellwig @ 2019-11-11 10:34 UTC (permalink / raw) To: Chaitanya Kulkarni; +Cc: hch, linux-nvme, sagi > + const char *model = ctrl->subsys->model; Can we have a little nvme_controller_mode() helper that uses subsystem->model if it is set, and otherwise the default? That saves memory by not duplicating the default name for every subsystem. > + kfree(subsys->model); > + subsys->model = kstrndup(page, len, GFP_KERNEL); > + if (!subsys->model) > + ret = -ENOMEM; I don't think we should free the old model until the new one is allocated. Otherwise this looks good to me, but can someone also prepare a nvmetcli patch as well? _______________________________________________ Linux-nvme mailing list Linux-nvme@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-nvme ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] nvmet: make ctrl model configurable 2019-11-11 10:34 ` Christoph Hellwig @ 2019-11-11 13:31 ` Mark Ruijter 2019-11-12 7:07 ` Chaitanya Kulkarni 2019-11-12 7:06 ` Chaitanya Kulkarni 1 sibling, 1 reply; 10+ messages in thread From: Mark Ruijter @ 2019-11-11 13:31 UTC (permalink / raw) To: Christoph Hellwig, Chaitanya Kulkarni; +Cc: hch, linux-nvme, sagi [-- Attachment #1: Type: text/plain, Size: 3539 bytes --] Hi Chaitanya & Christoph, I changed the patch I posted this morning and added the changes suggested. I also wrote a patch for nvmetcli and verified that nvmetcli can set and save the model description: dev:/usr/src/nvmetcli # ./nvmetcli save /tmp/test.json dev:/usr/src/nvmetcli # cat /sys/kernel/config/nvmet/subsystems/loop/attr_model mark dev:/usr/src/nvmetcli # grep model /tmp/test.json "model": "mark", dev:/usr/src/nvmetcli # ./nvmetcli /subsystems/loop> ls o- loop ............................................................ [version=1.3, allow_any=1, serial=198f07c757eb114d, model=mark] o- allowed_hosts ........................................................................................................... [...] o- namespaces .............................................................................................................. [...] o- 1 ............................................ [path=/dev/loop0, uuid=d808c1db-3507-40cf-8ade-aa4b1a3b290b, grpid=1, enabled] /subsystems/loop> set attr model=coolmodel Parameter model is now 'coolmodel'. /subsystems/loop> ls o- loop ....................................................... [version=1.3, allow_any=1, serial=198f07c757eb114d, model=coolmodel] o- allowed_hosts ........................................................................................................... [...] o- namespaces .............................................................................................................. [...] o- 1 ............................................ [path=/dev/loop0, uuid=d808c1db-3507-40cf-8ade-aa4b1a3b290b, grpid=1, enabled] /subsystems/loop> exit dev:/usr/src/nvmetcli # ./nvmetcli save /tmp/testcool.jsonl dev:/usr/src/nvmetcli # grep model /tmp/testcool.json "model": "coolmodel", dev:/usr/src/nvmetcli # I also verified that writing illegal characters in the model fails and that the initiator sees the model description that was set: echo -e "\t failit" > attr_model -bash: echo: write error: Invalid argument echo this~works > attr_model # nvme list Node SN Model Namespace Usage Format FW Rev ---------------- -------------------- ---------------------------------------- --------- -------------------------- ---------------- -------- /dev/nvme0n1 4d11eb57c7078f19 this~works 1 104,86 MB / 104,86 MB 512 B + 0 B 5.3.5 Thanks, Mark Ruijter Op 11-11-19 11:35 heeft Linux-nvme namens Christoph Hellwig <linux-nvme-bounces@lists.infradead.org namens hch@infradead.org> geschreven: > + const char *model = ctrl->subsys->model; Can we have a little nvme_controller_mode() helper that uses subsystem->model if it is set, and otherwise the default? That saves memory by not duplicating the default name for every subsystem. > + kfree(subsys->model); > + subsys->model = kstrndup(page, len, GFP_KERNEL); > + if (!subsys->model) > + ret = -ENOMEM; I don't think we should free the old model until the new one is allocated. Otherwise this looks good to me, but can someone also prepare a nvmetcli patch as well? _______________________________________________ Linux-nvme mailing list Linux-nvme@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-nvme [-- Attachment #2: model_patch_patched2.diff --] [-- Type: application/octet-stream, Size: 4022 bytes --] diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c index 51800a9..8f9366e 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c @@ -284,12 +284,19 @@ out: nvmet_req_complete(req, status); } +const char *nvme_controller_model(char *model) +{ + if (!model) + return NVMET_DEFAULT_CTRL_MODEL; + return model; +} + static void nvmet_execute_identify_ctrl(struct nvmet_req *req) { struct nvmet_ctrl *ctrl = req->sq->ctrl; + const char *model = nvme_controller_model(ctrl->subsys->model); struct nvme_id_ctrl *id; u16 status = 0; - const char model[] = "Linux"; id = kzalloc(sizeof(*id), GFP_KERNEL); if (!id) { @@ -304,7 +311,7 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req) memset(id->sn, ' ', sizeof(id->sn)); bin2hex(id->sn, &ctrl->subsys->serial, min(sizeof(ctrl->subsys->serial), sizeof(id->sn) / 2)); - memcpy_and_pad(id->mn, sizeof(id->mn), model, sizeof(model) - 1, ' '); + memcpy_and_pad(id->mn, sizeof(id->mn), model, strlen(model), ' '); memcpy_and_pad(id->fr, sizeof(id->fr), UTS_RELEASE, strlen(UTS_RELEASE), ' '); diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c index 98613a4..18a3f4d 100644 --- a/drivers/nvme/target/configfs.c +++ b/drivers/nvme/target/configfs.c @@ -862,10 +862,57 @@ static ssize_t nvmet_subsys_attr_serial_store(struct config_item *item, } CONFIGFS_ATTR(nvmet_subsys_, attr_serial); +static ssize_t nvmet_subsys_attr_model_show(struct config_item *item, + char *page) +{ + struct nvmet_subsys *subsys = to_subsys(item); + + return snprintf(page, PAGE_SIZE, "%s\n", subsys->model); +} + +static ssize_t nvmet_subsys_attr_model_store(struct config_item *item, + const char *page, size_t count) +{ + struct nvmet_subsys *subsys = to_subsys(item); + char *tmp; + int ret = -EINVAL, pos, len; + char c; + + down_write(&nvmet_config_sem); + len = strcspn(page, "\n"); + if (!len) + goto out_unlock; + + /* Only 20h (space) until 7eh (~) is allowed */ + for (pos = 0; pos < len; pos++) { + c = page[pos]; + if (c < 0x20 || c > 0x7e) + goto out_unlock; + } + + tmp = kstrndup(page, len, GFP_KERNEL); + if (!tmp) { + ret = -ENOMEM; + goto out_unlock; + } + + ret = count; + if (subsys->model) + kfree(subsys->model); + subsys->model = tmp; + +out_unlock: + up_write(&nvmet_config_sem); + return ret; +} + +CONFIGFS_ATTR(nvmet_subsys_, attr_model); + static struct configfs_attribute *nvmet_subsys_attrs[] = { &nvmet_subsys_attr_attr_allow_any_host, &nvmet_subsys_attr_attr_version, &nvmet_subsys_attr_attr_serial, + &nvmet_subsys_attr_attr_model, NULL, }; @@ -901,6 +948,7 @@ static struct config_group *nvmet_subsys_make(struct config_group *group, } subsys = nvmet_subsys_alloc(name, NVME_NQN_NVME); + subsys->model = kstrdup(NVMET_DEFAULT_CTRL_MODEL, GFP_KERNEL); if (IS_ERR(subsys)) return ERR_CAST(subsys); diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 3a67e24..25ca3cd 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -1418,6 +1418,7 @@ struct nvmet_subsys *nvmet_subsys_alloc(const char *subsysnqn, kfree(subsys); return ERR_PTR(-ENOMEM); } + subsys->model = 0; kref_init(&subsys->ref); @@ -1437,6 +1438,8 @@ static void nvmet_subsys_free(struct kref *ref) WARN_ON_ONCE(!list_empty(&subsys->namespaces)); kfree(subsys->subsysnqn); + if (subsys->model) + kfree(subsys->model); kfree(subsys); } diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index c51f8dd..fd0d89a 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -23,6 +23,7 @@ #define NVMET_ASYNC_EVENTS 4 #define NVMET_ERROR_LOG_SLOTS 128 #define NVMET_NO_ERROR_LOC ((u16)-1) +#define NVMET_DEFAULT_CTRL_MODEL "Linux" /* * Supported optional AENs: @@ -222,6 +223,7 @@ struct nvmet_subsys { u64 ver; u64 serial; char *subsysnqn; + char *model; struct config_group group; [-- Attachment #3: nvmetcli.patch --] [-- Type: application/octet-stream, Size: 785 bytes --] diff --git a/nvmetcli b/nvmetcli index 3d8c16e..7347fbb 100755 --- a/nvmetcli +++ b/nvmetcli @@ -155,6 +155,7 @@ class UISubsystemNode(UINode): ui_desc_attr = { 'allow_any_host': ('string', 'Allow access by any host if set to 1'), 'serial': ('string', 'Export serial number to hosts'), + 'model': ('string', 'Set a model description'), 'version': ('string', 'Export version number to hosts'), } @@ -172,6 +173,7 @@ class UISubsystemNode(UINode): info.append("allow_any=" + self.cfnode.get_attr("attr", "allow_any_host")) info.append("serial=" + self.cfnode.get_attr("attr", "serial")) + info.append("model=" + self.cfnode.get_attr("attr", "model")) return (", ".join(info), True) [-- Attachment #4: Type: text/plain, Size: 158 bytes --] _______________________________________________ Linux-nvme mailing list Linux-nvme@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-nvme ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH] nvmet: make ctrl model configurable 2019-11-11 13:31 ` Mark Ruijter @ 2019-11-12 7:07 ` Chaitanya Kulkarni 0 siblings, 0 replies; 10+ messages in thread From: Chaitanya Kulkarni @ 2019-11-12 7:07 UTC (permalink / raw) To: Mark Ruijter, Christoph Hellwig; +Cc: hch, linux-nvme, sagi On 11/11/2019 05:31 AM, Mark Ruijter wrote: > Hi Chaitanya & Christoph, > > I changed the patch I posted this morning and added the changes suggested. Thanks for the patches, let me test both and send out with proper change log. _______________________________________________ Linux-nvme mailing list Linux-nvme@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-nvme ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] nvmet: make ctrl model configurable 2019-11-11 10:34 ` Christoph Hellwig 2019-11-11 13:31 ` Mark Ruijter @ 2019-11-12 7:06 ` Chaitanya Kulkarni 1 sibling, 0 replies; 10+ messages in thread From: Chaitanya Kulkarni @ 2019-11-12 7:06 UTC (permalink / raw) To: Christoph Hellwig; +Cc: hch, linux-nvme, sagi On 11/11/2019 02:34 AM, Christoph Hellwig wrote: >> + const char *model = ctrl->subsys->model; > > Can we have a little nvme_controller_mode() helper that uses > subsystem->model if it is set, and otherwise the default? That saves > memory by not duplicating the default name for every subsystem. > Okay. >> + kfree(subsys->model); >> + subsys->model = kstrndup(page, len, GFP_KERNEL); >> + if (!subsys->model) >> + ret = -ENOMEM; > > I don't think we should free the old model until the new one > is allocated. > Sounds good. > Otherwise this looks good to me, but can someone also prepare a > nvmetcli patch as well? > Mark has sent out 2 patches, I'll test and send out in the mailing list format. _______________________________________________ Linux-nvme mailing list Linux-nvme@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-nvme ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] nvmet: make ctrl model configurable 2019-11-01 8:08 Chaitanya Kulkarni 2019-11-11 10:34 ` Christoph Hellwig @ 2019-11-11 11:09 ` Mark Ruijter 1 sibling, 0 replies; 10+ messages in thread From: Mark Ruijter @ 2019-11-11 11:09 UTC (permalink / raw) To: Chaitanya Kulkarni, linux-nvme; +Cc: hch, sagi [-- Attachment #1: Type: text/plain, Size: 8815 bytes --] Hi Chaitanya, I just removed my original patch from my test system that I use and replaced it with the patch that you submitted a while ago. When trying to use it I noticed it is flawed. Any attempt to change the model will return 'invalid argument'. The ret variable is initialized as '-EINVAL' by default and never set to 0 when the input was valid. The minimum change required to solve the problem would be : diff -u configfs.c configfs.c-orig --- configfs.c 2019-11-11 10:16:14.970374663 +0100 +++ configfs.c-orig 2019-11-11 10:05:27.754635151 +0100 @@ -874,7 +874,7 @@ const char *page, size_t count) { struct nvmet_subsys *subsys = to_subsys(item); - int ret = 0, pos, len; + int ret = -EINVAL, pos, len; char c; down_write(&nvmet_config_sem); Looking at this code once more I would probably simplify it like this: diff --git a/configfs.c-orig b/configfs.c index 1d64059..d2e7935 100644 --- a/configfs.c-orig +++ b/configfs.c @@ -879,28 +879,26 @@ static ssize_t nvmet_subsys_attr_model_store(struct config_item *item, down_write(&nvmet_config_sem); len = strcspn(page, "\n"); - if (!len) { - ret = -EINVAL; + if (!len) goto out_unlock; - } /* Only 20h (space) until 7eh (~) is allowed */ for (pos = 0; pos < len; pos++) { c = page[pos]; - if (c < 0x20 || c > 0x7e) { - ret = -EINVAL; + if (c < 0x20 || c > 0x7e) goto out_unlock; - } } kfree(subsys->model); subsys->model = kstrndup(page, len, GFP_KERNEL); if (!subsys->model) ret = -ENOMEM; + else + ret = count; out_unlock: up_write(&nvmet_config_sem); - return ret ? ret : count; + return ret; } CONFIGFS_ATTR(nvmet_subsys_, attr_model); --- This shortens the routine with 2 lines. I tested both changes and they work: dev:/sys/kernel/config/nvmet/subsystems/loop # echo -e "\t model" > attr_model -bash: echo: write error: Invalid argument dev:/sys/kernel/config/nvmet/subsystems/loop # echo -e "newmodel" > attr_model I have attached the tested patch with the shortened routine to this email. Thanks, Mark This email message is for the sole use of the intended recipient(s) and contains confidential information. Any unauthorized use, disclosure or distribution is prohibited. If you are not an intended recipient, please contact the sender by reply email and destroy all copies of the original message. Op 01-11-19 09:09 heeft Linux-nvme namens Chaitanya Kulkarni <linux-nvme-bounces@lists.infradead.org namens chaitanya.kulkarni@wdc.com> geschreven: From: Mark Ruijter <MRuijter@onestopsystems.com> This patch adds a new target subsys attribute which allows user to optionally specify model name which then used in the nvmet_execute_identify_ctrl() to fill up the nvme_id_ctrl structure. The default value for the model is set to "Linux" for backward compatibility. Signed-off-by: Mark Ruijter <MRuijter@onestopsystems.com> Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com> --- Hi, This patch is originally posted by Mark and later same day by me with the same concept. I've merged changes from both patch into one and cleaned the code to fit the kernel coding standards. -Regards, Chaitanya --- drivers/nvme/target/admin-cmd.c | 4 +-- drivers/nvme/target/configfs.c | 45 +++++++++++++++++++++++++++++++++ drivers/nvme/target/core.c | 7 +++++ drivers/nvme/target/nvmet.h | 2 ++ 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c index 56c21b501185..917d8f3fded7 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c @@ -315,9 +315,9 @@ static void nvmet_execute_get_log_page(struct nvmet_req *req) static void nvmet_execute_identify_ctrl(struct nvmet_req *req) { struct nvmet_ctrl *ctrl = req->sq->ctrl; + const char *model = ctrl->subsys->model; struct nvme_id_ctrl *id; u16 status = 0; - const char model[] = "Linux"; id = kzalloc(sizeof(*id), GFP_KERNEL); if (!id) { @@ -332,7 +332,7 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req) memset(id->sn, ' ', sizeof(id->sn)); bin2hex(id->sn, &ctrl->subsys->serial, min(sizeof(ctrl->subsys->serial), sizeof(id->sn) / 2)); - memcpy_and_pad(id->mn, sizeof(id->mn), model, sizeof(model) - 1, ' '); + memcpy_and_pad(id->mn, sizeof(id->mn), model, strlen(model), ' '); memcpy_and_pad(id->fr, sizeof(id->fr), UTS_RELEASE, strlen(UTS_RELEASE), ' '); diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c index 98613a45bd3b..faf34b15b975 100644 --- a/drivers/nvme/target/configfs.c +++ b/drivers/nvme/target/configfs.c @@ -862,10 +862,54 @@ static ssize_t nvmet_subsys_attr_serial_store(struct config_item *item, } CONFIGFS_ATTR(nvmet_subsys_, attr_serial); +static ssize_t nvmet_subsys_attr_model_show(struct config_item *item, + char *page) +{ + struct nvmet_subsys *subsys = to_subsys(item); + + return snprintf(page, PAGE_SIZE, "%s\n", subsys->model); +} + +static ssize_t nvmet_subsys_attr_model_store(struct config_item *item, + const char *page, size_t count) +{ + struct nvmet_subsys *subsys = to_subsys(item); + int ret = -EINVAL, pos, len; + char c; + + down_write(&nvmet_config_sem); + len = strcspn(page, "\n"); + if (!len) { + ret = -EINVAL; + goto out_unlock; + } + + /* Only 20h (space) until 7eh (~) is allowed */ + for (pos = 0; pos < len; pos++) { + c = page[pos]; + if (c < 0x20 || c > 0x7e) { + ret = -EINVAL; + goto out_unlock; + } + } + + kfree(subsys->model); + subsys->model = kstrndup(page, len, GFP_KERNEL); + if (!subsys->model) + ret = -ENOMEM; + +out_unlock: + up_write(&nvmet_config_sem); + return ret ? ret : count; +} + +CONFIGFS_ATTR(nvmet_subsys_, attr_model); + static struct configfs_attribute *nvmet_subsys_attrs[] = { &nvmet_subsys_attr_attr_allow_any_host, &nvmet_subsys_attr_attr_version, &nvmet_subsys_attr_attr_serial, + &nvmet_subsys_attr_attr_model, NULL, }; @@ -901,6 +945,7 @@ static struct config_group *nvmet_subsys_make(struct config_group *group, } subsys = nvmet_subsys_alloc(name, NVME_NQN_NVME); + subsys->model = kstrdup(NVMET_DEFAULT_CTRL_MODEL, GFP_KERNEL); if (IS_ERR(subsys)) return ERR_CAST(subsys); diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 28438b833c1b..adc1eb667601 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -1416,6 +1416,12 @@ struct nvmet_subsys *nvmet_subsys_alloc(const char *subsysnqn, kfree(subsys); return ERR_PTR(-ENOMEM); } + subsys->model = kstrdup(NVMET_DEFAULT_CTRL_MODEL, GFP_KERNEL); + if (!subsys->model) { + kfree(subsys->subsysnqn); + kfree(subsys); + return ERR_PTR(-ENOMEM); + } kref_init(&subsys->ref); @@ -1435,6 +1441,7 @@ static void nvmet_subsys_free(struct kref *ref) WARN_ON_ONCE(!list_empty(&subsys->namespaces)); kfree(subsys->subsysnqn); + kfree(subsys->model); kfree(subsys); } diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index 46df45e837c9..afb6116de892 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -23,6 +23,7 @@ #define NVMET_ASYNC_EVENTS 4 #define NVMET_ERROR_LOG_SLOTS 128 #define NVMET_NO_ERROR_LOC ((u16)-1) +#define NVMET_DEFAULT_CTRL_MODEL "Linux" /* * Supported optional AENs: @@ -222,6 +223,7 @@ struct nvmet_subsys { u64 ver; u64 serial; char *subsysnqn; + char *model; struct config_group group; -- 2.22.1 _______________________________________________ Linux-nvme mailing list Linux-nvme@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-nvme [-- Attachment #2: model_patch_patched.diff --] [-- Type: application/octet-stream, Size: 3903 bytes --] diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c index 51800a9..1f6f7d9 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c @@ -287,9 +287,9 @@ out: static void nvmet_execute_identify_ctrl(struct nvmet_req *req) { struct nvmet_ctrl *ctrl = req->sq->ctrl; + const char *model = ctrl->subsys->model; struct nvme_id_ctrl *id; u16 status = 0; - const char model[] = "Linux"; id = kzalloc(sizeof(*id), GFP_KERNEL); if (!id) { @@ -304,7 +304,7 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req) memset(id->sn, ' ', sizeof(id->sn)); bin2hex(id->sn, &ctrl->subsys->serial, min(sizeof(ctrl->subsys->serial), sizeof(id->sn) / 2)); - memcpy_and_pad(id->mn, sizeof(id->mn), model, sizeof(model) - 1, ' '); + memcpy_and_pad(id->mn, sizeof(id->mn), model, strlen(model), ' '); memcpy_and_pad(id->fr, sizeof(id->fr), UTS_RELEASE, strlen(UTS_RELEASE), ' '); diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c index 98613a4..ef62853 100644 --- a/drivers/nvme/target/configfs.c +++ b/drivers/nvme/target/configfs.c @@ -862,10 +862,52 @@ static ssize_t nvmet_subsys_attr_serial_store(struct config_item *item, } CONFIGFS_ATTR(nvmet_subsys_, attr_serial); +static ssize_t nvmet_subsys_attr_model_show(struct config_item *item, + char *page) +{ + struct nvmet_subsys *subsys = to_subsys(item); + + return snprintf(page, PAGE_SIZE, "%s\n", subsys->model); +} + +static ssize_t nvmet_subsys_attr_model_store(struct config_item *item, + const char *page, size_t count) +{ + struct nvmet_subsys *subsys = to_subsys(item); + int ret = -EINVAL, pos, len; + char c; + + down_write(&nvmet_config_sem); + len = strcspn(page, "\n"); + if (!len) + goto out_unlock; + + /* Only 20h (space) until 7eh (~) is allowed */ + for (pos = 0; pos < len; pos++) { + c = page[pos]; + if (c < 0x20 || c > 0x7e) + goto out_unlock; + } + + kfree(subsys->model); + subsys->model = kstrndup(page, len, GFP_KERNEL); + if (!subsys->model) + ret = -ENOMEM; + else + ret = count; + +out_unlock: + up_write(&nvmet_config_sem); + return ret; +} + +CONFIGFS_ATTR(nvmet_subsys_, attr_model); + static struct configfs_attribute *nvmet_subsys_attrs[] = { &nvmet_subsys_attr_attr_allow_any_host, &nvmet_subsys_attr_attr_version, &nvmet_subsys_attr_attr_serial, + &nvmet_subsys_attr_attr_model, NULL, }; @@ -901,6 +943,7 @@ static struct config_group *nvmet_subsys_make(struct config_group *group, } subsys = nvmet_subsys_alloc(name, NVME_NQN_NVME); + subsys->model = kstrdup(NVMET_DEFAULT_CTRL_MODEL, GFP_KERNEL); if (IS_ERR(subsys)) return ERR_CAST(subsys); diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 3a67e24..5dc90ba 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -1418,6 +1418,12 @@ struct nvmet_subsys *nvmet_subsys_alloc(const char *subsysnqn, kfree(subsys); return ERR_PTR(-ENOMEM); } + subsys->model = kstrdup(NVMET_DEFAULT_CTRL_MODEL, GFP_KERNEL); + if (!subsys->model) { + kfree(subsys->subsysnqn); + kfree(subsys); + return ERR_PTR(-ENOMEM); + } kref_init(&subsys->ref); @@ -1437,6 +1443,7 @@ static void nvmet_subsys_free(struct kref *ref) WARN_ON_ONCE(!list_empty(&subsys->namespaces)); kfree(subsys->subsysnqn); + kfree(subsys->model); kfree(subsys); } diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index c51f8dd..fd0d89a 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -23,6 +23,7 @@ #define NVMET_ASYNC_EVENTS 4 #define NVMET_ERROR_LOG_SLOTS 128 #define NVMET_NO_ERROR_LOC ((u16)-1) +#define NVMET_DEFAULT_CTRL_MODEL "Linux" /* * Supported optional AENs: @@ -222,6 +223,7 @@ struct nvmet_subsys { u64 ver; u64 serial; char *subsysnqn; + char *model; struct config_group group; [-- Attachment #3: Type: text/plain, Size: 158 bytes --] _______________________________________________ Linux-nvme mailing list Linux-nvme@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-nvme ^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2019-11-12 7:07 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2019-10-30 19:48 [PATCH] nvmet: make ctrl model configurable Chaitanya Kulkarni 2019-10-30 20:08 ` Mark Ruijter 2019-10-30 20:09 ` Chaitanya Kulkarni 2019-10-30 21:43 ` Chaitanya Kulkarni 2019-11-01 8:08 Chaitanya Kulkarni 2019-11-11 10:34 ` Christoph Hellwig 2019-11-11 13:31 ` Mark Ruijter 2019-11-12 7:07 ` Chaitanya Kulkarni 2019-11-12 7:06 ` Chaitanya Kulkarni 2019-11-11 11:09 ` Mark Ruijter
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).