[PATCH nvme-7.3 2/4] nvme-fabrics: add helper for owned string options

From: raoxu

Date: Fri Aug 21 2026 - 02:27:03 EST


From: Xu Rao <raoxu@xxxxxxxxxxxxx>

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. Options
that need validation, conversion, or sensitive cleanup have different
lifetime rules and are handled separately in the following patches.

No functional change is intended.

Suggested-by: Christoph Hellwig <hch@xxxxxx>
Signed-off-by: Xu Rao <raoxu@xxxxxxxxxxxxx>
---
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