* [PATCH nvme-7.3 v2 1/4] nvme-fabrics: separate option tokenizer pointer
2026-08-27 12:57 [PATCH nvme-7.3 v2 0/4] nvme-fabrics: localize string option parsing raoxu
@ 2026-08-27 13:03 ` raoxu
2026-08-30 21:16 ` Sagi Grimberg
2026-08-27 13:03 ` [PATCH nvme-7.3 v2 2/4] nvme-fabrics: add helper for owned string options raoxu
` (2 subsequent siblings)
3 siblings, 1 reply; 9+ messages in thread
From: raoxu @ 2026-08-27 13:03 UTC (permalink / raw)
To: raoxu; +Cc: axboe, hch, kbusch, linux-kernel, linux-nvme, sagi
From: Xu Rao <raoxu@uniontech.com>
nvmf_parse_options() currently uses p both for the option returned by
strsep() and for strings allocated by match_strdup(). The former points
into the temporary options buffer while the latter owns a separate
allocation, so the same variable represents two different lifetimes.
Introduce option for the current string token passed to match_token().
Leave p for temporary strings returned by match_strdup(), giving option
tokenization and allocated string storage distinct variables without
changing the parsing logic.
The name option is intentional: options remains the backing buffer for the
full request, option is one comma/newline-delimited entry, and token names
the integer result returned by match_token().
This is a mechanical preparation with no functional change.
Suggested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Xu Rao <raoxu@uniontech.com>
---
drivers/nvme/host/fabrics.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c
index 59f823dfbbcc..1ec6da49167d 100644
--- a/drivers/nvme/host/fabrics.c
+++ b/drivers/nvme/host/fabrics.c
@@ -716,7 +716,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
const char *buf)
{
substring_t args[MAX_OPT_ARGS];
- char *options, *o, *p;
+ char *options, *o, *option, *p;
int token, ret = 0;
size_t nqnlen = 0;
int ctrl_loss_tmo = NVMF_DEF_CTRL_LOSS_TMO, key_id;
@@ -747,11 +747,11 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
uuid_copy(&hostid, &nvmf_default_host->id);
strscpy(hostnqn, nvmf_default_host->nqn, NVMF_NQN_SIZE);
- while ((p = strsep(&o, ",\n")) != NULL) {
- if (!*p)
+ while ((option = strsep(&o, ",\n")) != NULL) {
+ if (!*option)
continue;
- token = match_token(p, opt_tokens, args);
+ token = match_token(option, opt_tokens, args);
opts->mask |= token;
switch (token) {
case NVMF_OPT_TRANSPORT:
@@ -1068,7 +1068,7 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
break;
default:
pr_warn("unknown parameter or missing value '%s' in ctrl creation request\n",
- p);
+ option);
ret = -EINVAL;
goto out;
}
--
2.50.1
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH nvme-7.3 v2 2/4] nvme-fabrics: add helper for owned string options
2026-08-27 12:57 [PATCH nvme-7.3 v2 0/4] nvme-fabrics: localize string option parsing raoxu
2026-08-27 13:03 ` [PATCH nvme-7.3 v2 1/4] nvme-fabrics: separate option tokenizer pointer raoxu
@ 2026-08-27 13:03 ` raoxu
2026-08-30 21:17 ` Sagi Grimberg
2026-08-27 13:03 ` [PATCH nvme-7.3 v2 3/4] nvme-fabrics: reuse string helper for subsystem NQN raoxu
2026-08-27 13:04 ` [PATCH nvme-7.3 v2 4/4] nvme-fabrics: add helper for DH-CHAP secret options raoxu
3 siblings, 1 reply; 9+ messages in thread
From: raoxu @ 2026-08-27 13:03 UTC (permalink / raw)
To: raoxu; +Cc: axboe, hch, kbusch, linux-kernel, linux-nvme, sagi
From: Xu Rao <raoxu@uniontech.com>
Five string options -- transport, traddr, trsvcid, host_traddr and
host_iface -- have exactly the same parsing and ownership rule: duplicate
the matched value, free the previously stored string, and transfer the new
allocation to the corresponding struct nvmf_ctrl_options field.
Add nvmf_parse_string_option() for that common operation. The helper owns
the match_strdup() result until it either fails or stores the new pointer
in the destination field, keeping this simple allocation lifetime in one
scope and removing five copies of the same sequence from
nvmf_parse_options().
The helper is intentionally limited to direct string replacement and does
not absorb option-specific validation, conversion, or sensitive cleanup.
No functional change is intended.
Suggested-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Signed-off-by: Xu Rao <raoxu@uniontech.com>
---
drivers/nvme/host/fabrics.c | 53 ++++++++++++++++---------------------
1 file changed, 23 insertions(+), 30 deletions(-)
diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c
index 1ec6da49167d..aab3fd279d0e 100644
--- a/drivers/nvme/host/fabrics.c
+++ b/drivers/nvme/host/fabrics.c
@@ -712,6 +712,19 @@ static const match_table_t opt_tokens = {
{ NVMF_OPT_ERR, NULL }
};
+static int nvmf_parse_string_option(substring_t *args, char **dst)
+{
+ char *value;
+
+ value = match_strdup(args);
+ if (!value)
+ return -ENOMEM;
+
+ kfree(*dst);
+ *dst = value;
+ return 0;
+}
+
static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
const char *buf)
{
@@ -755,13 +768,9 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
opts->mask |= token;
switch (token) {
case NVMF_OPT_TRANSPORT:
- p = match_strdup(args);
- if (!p) {
- ret = -ENOMEM;
+ ret = nvmf_parse_string_option(args, &opts->transport);
+ if (ret)
goto out;
- }
- kfree(opts->transport);
- opts->transport = p;
break;
case NVMF_OPT_NQN:
p = match_strdup(args);
@@ -783,22 +792,14 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
NVME_DISC_SUBSYS_NAME));
break;
case NVMF_OPT_TRADDR:
- p = match_strdup(args);
- if (!p) {
- ret = -ENOMEM;
+ ret = nvmf_parse_string_option(args, &opts->traddr);
+ if (ret)
goto out;
- }
- kfree(opts->traddr);
- opts->traddr = p;
break;
case NVMF_OPT_TRSVCID:
- p = match_strdup(args);
- if (!p) {
- ret = -ENOMEM;
+ ret = nvmf_parse_string_option(args, &opts->trsvcid);
+ if (ret)
goto out;
- }
- kfree(opts->trsvcid);
- opts->trsvcid = p;
break;
case NVMF_OPT_QUEUE_SIZE:
if (match_int(args, &token)) {
@@ -907,22 +908,14 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
opts->reconnect_delay = token;
break;
case NVMF_OPT_HOST_TRADDR:
- p = match_strdup(args);
- if (!p) {
- ret = -ENOMEM;
+ ret = nvmf_parse_string_option(args, &opts->host_traddr);
+ if (ret)
goto out;
- }
- kfree(opts->host_traddr);
- opts->host_traddr = p;
break;
case NVMF_OPT_HOST_IFACE:
- p = match_strdup(args);
- if (!p) {
- ret = -ENOMEM;
+ ret = nvmf_parse_string_option(args, &opts->host_iface);
+ if (ret)
goto out;
- }
- kfree(opts->host_iface);
- opts->host_iface = p;
break;
case NVMF_OPT_HOST_ID:
p = match_strdup(args);
--
2.50.1
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH nvme-7.3 v2 3/4] nvme-fabrics: reuse string helper for subsystem NQN
2026-08-27 12:57 [PATCH nvme-7.3 v2 0/4] nvme-fabrics: localize string option parsing raoxu
2026-08-27 13:03 ` [PATCH nvme-7.3 v2 1/4] nvme-fabrics: separate option tokenizer pointer raoxu
2026-08-27 13:03 ` [PATCH nvme-7.3 v2 2/4] nvme-fabrics: add helper for owned string options raoxu
@ 2026-08-27 13:03 ` raoxu
2026-08-30 21:18 ` Sagi Grimberg
2026-08-27 13:04 ` [PATCH nvme-7.3 v2 4/4] nvme-fabrics: add helper for DH-CHAP secret options raoxu
3 siblings, 1 reply; 9+ messages in thread
From: raoxu @ 2026-08-27 13:03 UTC (permalink / raw)
To: raoxu; +Cc: axboe, hch, kbusch, linux-kernel, linux-nvme, sagi
From: Xu Rao <raoxu@uniontech.com>
The subsystem NQN starts with the same owned-string replacement sequence
as the direct string options handled by nvmf_parse_string_option():
duplicate the matched value, free the previously stored string, and
transfer ownership of the new allocation.
Reuse nvmf_parse_string_option() for that replacement only. Leave the
existing NQN length validation and discovery-NQN update unchanged. The
hostnqn and hostid parsing paths are also left untouched.
This removes another copy of the match_strdup(), free and
ownership-transfer sequence without introducing a dedicated helper or
changing option-specific logic.
No functional change is intended.
Suggested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Xu Rao <raoxu@uniontech.com>
---
drivers/nvme/host/fabrics.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c
index aab3fd279d0e..24385e777307 100644
--- a/drivers/nvme/host/fabrics.c
+++ b/drivers/nvme/host/fabrics.c
@@ -773,13 +773,9 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
goto out;
break;
case NVMF_OPT_NQN:
- p = match_strdup(args);
- if (!p) {
- ret = -ENOMEM;
+ ret = nvmf_parse_string_option(args, &opts->subsysnqn);
+ if (ret)
goto out;
- }
- kfree(opts->subsysnqn);
- opts->subsysnqn = p;
nqnlen = strlen(opts->subsysnqn);
if (nqnlen >= NVMF_NQN_SIZE) {
pr_err("%s needs to be < %d bytes\n",
--
2.50.1
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH nvme-7.3 v2 4/4] nvme-fabrics: add helper for DH-CHAP secret options
2026-08-27 12:57 [PATCH nvme-7.3 v2 0/4] nvme-fabrics: localize string option parsing raoxu
` (2 preceding siblings ...)
2026-08-27 13:03 ` [PATCH nvme-7.3 v2 3/4] nvme-fabrics: reuse string helper for subsystem NQN raoxu
@ 2026-08-27 13:04 ` raoxu
2026-08-30 21:23 ` Sagi Grimberg
3 siblings, 1 reply; 9+ messages in thread
From: raoxu @ 2026-08-27 13:04 UTC (permalink / raw)
To: raoxu; +Cc: axboe, hch, kbusch, linux-kernel, linux-nvme, sagi
From: Xu Rao <raoxu@uniontech.com>
The dhchap_secret and dhchap_ctrl_secret options have a distinct string
lifetime because their values are authentication material. The temporary
string must be checked for the DHHC-1 representation and discarded with
kfree_sensitive() when validation fails before ownership is transferred.
Add nvmf_parse_dhchap_secret() to keep match_strdup(), DHHC-1 validation,
failure cleanup, replacement of the old value and successful ownership
transfer in one scope. Both secret options use the same helper because
their parsing and ownership rules are identical.
Keep the existing replacement semantics for an already stored valid secret;
this patch only moves the parsing and temporary allocation lifetime into
the helper.
No functional change is intended.
Suggested-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Signed-off-by: Xu Rao <raoxu@uniontech.com>
---
drivers/nvme/host/fabrics.c | 48 ++++++++++++++++++-------------------
1 file changed, 24 insertions(+), 24 deletions(-)
diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c
index 24385e777307..dc8883d85f45 100644
--- a/drivers/nvme/host/fabrics.c
+++ b/drivers/nvme/host/fabrics.c
@@ -725,6 +725,25 @@ static int nvmf_parse_string_option(substring_t *args, char **dst)
return 0;
}
+static int nvmf_parse_dhchap_secret(substring_t *args, char **secret)
+{
+ char *value;
+
+ value = match_strdup(args);
+ if (!value)
+ return -ENOMEM;
+
+ if (strlen(value) < 11 || strncmp(value, "DHHC-1:", 7)) {
+ pr_err("Invalid DH-CHAP secret %s\n", value);
+ kfree_sensitive(value);
+ return -EINVAL;
+ }
+
+ kfree(*secret);
+ *secret = value;
+ return 0;
+}
+
static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
const char *buf)
{
@@ -1010,34 +1029,15 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts,
opts->discovery_nqn = true;
break;
case NVMF_OPT_DHCHAP_SECRET:
- p = match_strdup(args);
- if (!p) {
- ret = -ENOMEM;
- goto out;
- }
- if (strlen(p) < 11 || strncmp(p, "DHHC-1:", 7)) {
- pr_err("Invalid DH-CHAP secret %s\n", p);
- kfree_sensitive(p);
- ret = -EINVAL;
+ ret = nvmf_parse_dhchap_secret(args, &opts->dhchap_secret);
+ if (ret)
goto out;
- }
- kfree(opts->dhchap_secret);
- opts->dhchap_secret = p;
break;
case NVMF_OPT_DHCHAP_CTRL_SECRET:
- p = match_strdup(args);
- if (!p) {
- ret = -ENOMEM;
- goto out;
- }
- if (strlen(p) < 11 || strncmp(p, "DHHC-1:", 7)) {
- pr_err("Invalid DH-CHAP secret %s\n", p);
- kfree_sensitive(p);
- ret = -EINVAL;
+ ret = nvmf_parse_dhchap_secret(args,
+ &opts->dhchap_ctrl_secret);
+ if (ret)
goto out;
- }
- kfree(opts->dhchap_ctrl_secret);
- opts->dhchap_ctrl_secret = p;
break;
case NVMF_OPT_TLS:
if (!IS_ENABLED(CONFIG_NVME_TCP_TLS)) {
--
2.50.1
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH nvme-7.3 v2 4/4] nvme-fabrics: add helper for DH-CHAP secret options
2026-08-27 13:04 ` [PATCH nvme-7.3 v2 4/4] nvme-fabrics: add helper for DH-CHAP secret options raoxu
@ 2026-08-30 21:23 ` Sagi Grimberg
0 siblings, 0 replies; 9+ messages in thread
From: Sagi Grimberg @ 2026-08-30 21:23 UTC (permalink / raw)
To: raoxu; +Cc: axboe, hch, kbusch, linux-kernel, linux-nvme
On 27/08/2026 16:04, raoxu wrote:
> From: Xu Rao <raoxu@uniontech.com>
>
> The dhchap_secret and dhchap_ctrl_secret options have a distinct string
> lifetime because their values are authentication material. The temporary
> string must be checked for the DHHC-1 representation and discarded with
> kfree_sensitive() when validation fails before ownership is transferred.
>
> Add nvmf_parse_dhchap_secret() to keep match_strdup(), DHHC-1 validation,
> failure cleanup, replacement of the old value and successful ownership
> transfer in one scope. Both secret options use the same helper because
> their parsing and ownership rules are identical.
>
> Keep the existing replacement semantics for an already stored valid secret;
> this patch only moves the parsing and temporary allocation lifetime into
> the helper.
>
> No functional change is intended.
>
> Suggested-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
> Signed-off-by: Xu Rao <raoxu@uniontech.com>
> ---
> drivers/nvme/host/fabrics.c | 48 ++++++++++++++++++-------------------
> 1 file changed, 24 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c
> index 24385e777307..dc8883d85f45 100644
> --- a/drivers/nvme/host/fabrics.c
> +++ b/drivers/nvme/host/fabrics.c
> @@ -725,6 +725,25 @@ static int nvmf_parse_string_option(substring_t *args, char **dst)
> return 0;
> }
>
> +static int nvmf_parse_dhchap_secret(substring_t *args, char **secret)
> +{
> + char *value;
> +
> + value = match_strdup(args);
> + if (!value)
> + return -ENOMEM;
> +
> + if (strlen(value) < 11 || strncmp(value, "DHHC-1:", 7)) {
> + pr_err("Invalid DH-CHAP secret %s\n", value);
> + kfree_sensitive(value);
> + return -EINVAL;
> + }
> +
> + kfree(*secret);
> + *secret = value;
> + return 0;
Looks very similar to nvmf_parse_string_option... Would this be better?
-- static int nvmf_parse_dhchap_secret(substring_t *args, char **secret)
{ int ret; ret = nvmf_parse_string_option(args, secret); if (ret) return
ret; if (strlen(*secret) < 11 || strncmp(*secret, "DHHC-1:", 7)) {
pr_err("Invalid DH-CHAP secret %s\n", *secret);
kfree_sensitive(*secret); return -EINVAL; } return 0; } --
^ permalink raw reply [flat|nested] 9+ messages in thread