From c08795f9526e8904a45ea9a8517f2f3771a41d18 Mon Sep 17 00:00:00 2001 From: Mr NeilBrown Date: Tue, 25 Jul 2023 14:47:27 -0400 Subject: [PATCH] LU-9859 lnet: simplify cfs_parse_nidlist() By duplicating the string being parsed, we can use mutating parsign primitives and simplify the code. Note that the kernel-space cfs_parse_nidlist() is now different from the user-space version. As they are both declared in the same header file, this needs an #ifdef until the headers can be separated. Change some function that return 0 on error to match the kernel convention of 0 on success and -ve on error. Signed-off-by: Mr NeilBrown Change-Id: I1d5155a1cee82f798bec0863d80d75af92399cf1 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/50841 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Chris Horn Reviewed-by: James Simmons Reviewed-by: Oleg Drokin --- lnet/include/uapi/linux/lnet/nidstr.h | 4 ++ lnet/lnet/nidstrings.c | 96 +++++++++++++++++------------------ lustre/obdclass/lprocfs_status.c | 2 +- lustre/obdclass/obd_mount.c | 2 +- lustre/ptlrpc/nrs_tbf.c | 8 ++- 5 files changed, 56 insertions(+), 56 deletions(-) diff --git a/lnet/include/uapi/linux/lnet/nidstr.h b/lnet/include/uapi/linux/lnet/nidstr.h index 17ff37a..bfa17fd 100644 --- a/lnet/include/uapi/linux/lnet/nidstr.h +++ b/lnet/include/uapi/linux/lnet/nidstr.h @@ -103,7 +103,11 @@ int libcfs_str2anynid(lnet_nid_t *nid, const char *str); int libcfs_num_parse(char *str, int len, struct list_head *list); char *libcfs_id2str(struct lnet_process_id id); void cfs_free_nidlist(struct list_head *list); +#ifdef __KERNEL__ +int cfs_parse_nidlist(char *str, struct list_head *list); +#else int cfs_parse_nidlist(char *str, int len, struct list_head *list); +#endif int cfs_print_nidlist(char *buffer, int count, struct list_head *list); int cfs_match_nid(struct lnet_nid *nid, struct list_head *list); int cfs_match_net(__u32 net_id, __u32 net_type, diff --git a/lnet/lnet/nidstrings.c b/lnet/lnet/nidstrings.c index 94224be..ae28f92 100644 --- a/lnet/lnet/nidstrings.c +++ b/lnet/lnet/nidstrings.c @@ -157,11 +157,11 @@ struct addrrange { * \retval -errno otherwise */ static int -parse_addrange(const struct cfs_lstr *src, struct nidrange *nidrange) +parse_addrange(char *str, struct nidrange *nidrange) { struct addrrange *addrrange; - if (src->ls_len == 1 && src->ls_str[0] == '*') { + if (strcmp(str, "*") == 0) { nidrange->nr_all = 1; return 0; } @@ -172,8 +172,7 @@ parse_addrange(const struct cfs_lstr *src, struct nidrange *nidrange) list_add_tail(&addrrange->ar_link, &nidrange->nr_addrranges); INIT_LIST_HEAD(&addrrange->ar_numaddr_ranges); - return nidrange->nr_netstrfns->nf_parse_addrlist(src->ls_str, - src->ls_len, + return nidrange->nr_netstrfns->nf_parse_addrlist(str, strlen(str), &addrrange->ar_numaddr_ranges); } @@ -188,30 +187,26 @@ parse_addrange(const struct cfs_lstr *src, struct nidrange *nidrange) * \retval NULL if \a src does not match any network */ static struct nidrange * -add_nidrange(const struct cfs_lstr *src, - struct list_head *nidlist) +add_nidrange(char *str, struct list_head *nidlist) { struct netstrfns *nf; struct nidrange *nr; - int endlen; - unsigned netnum; + char *end; + unsigned int netnum; - if (src->ls_len >= LNET_NIDSTR_SIZE) - return NULL; - - nf = libcfs_namenum2netstrfns(src->ls_str); + nf = libcfs_namenum2netstrfns(str); if (nf == NULL) return NULL; - endlen = src->ls_len - strlen(nf->nf_name); - if (endlen == 0) + end = str + strlen(nf->nf_name); + if (!*end) { /* network name only, e.g. "elan" or "tcp" */ netnum = 0; - else { + } else { /* e.g. "elan25" or "tcp23", refuse to parse if * network name is not appended with decimal or - * hexadecimal number */ - if (!cfs_str2num_check(src->ls_str + strlen(nf->nf_name), - endlen, &netnum, 0, MAX_NUMERIC_VALUE)) + * hexadecimal number + */ + if (kstrtouint(end, 0, &netnum) != 0) return NULL; } @@ -238,32 +233,34 @@ add_nidrange(const struct cfs_lstr *src, /** * Parses \ token of the syntax. * - * \retval 1 if \a src parses to \ '@' \ - * \retval 0 otherwise + * \retval 0 if \a src parses to \ '@' \ + * \retval -EINVAL otherwise */ static int -parse_nidrange(struct cfs_lstr *src, struct list_head *nidlist) +parse_nidrange(char *str, struct list_head *nidlist) { - struct cfs_lstr addrrange; - struct cfs_lstr net; + char *addrrange; + char *net; struct nidrange *nr; - if (cfs_gettok(src, '@', &addrrange) == 0) + addrrange = strim(strsep(&str, "@")); + if (!str) goto failed; - if (cfs_gettok(src, '@', &net) == 0 || src->ls_str != NULL) + net = strim(str); + if (strchr(net, '@') != NULL || !*net) goto failed; - nr = add_nidrange(&net, nidlist); + nr = add_nidrange(net, nidlist); if (nr == NULL) goto failed; - if (parse_addrange(&addrrange, nr) != 0) + if (parse_addrange(addrrange, nr) != 0) goto failed; - return 1; -failed: return 0; +failed: + return -EINVAL; } /** @@ -321,32 +318,33 @@ EXPORT_SYMBOL(cfs_free_nidlist); * str. * \see cfs_match_nid * - * \retval 1 on success - * \retval 0 otherwise + * \retval 0 on success + * \retval -errno otherwise (-ENOMEM or -EINVAL) */ int -cfs_parse_nidlist(char *str, int len, struct list_head *nidlist) +cfs_parse_nidlist(char *orig, struct list_head *nidlist) { - struct cfs_lstr src; - struct cfs_lstr res; - int rc; + int rc = 0; + char *str; + + orig = kstrdup(orig, GFP_KERNEL); + if (!orig) + return -ENOMEM; - src.ls_str = str; - src.ls_len = len; INIT_LIST_HEAD(nidlist); - while (src.ls_str) { - rc = cfs_gettok(&src, ' ', &res); - if (rc == 0) { - cfs_free_nidlist(nidlist); - return 0; - } - rc = parse_nidrange(&res, nidlist); - if (rc == 0) { - cfs_free_nidlist(nidlist); - return 0; - } + str = orig; + while (rc == 0 && str) { + char *tok = strsep(&str, " "); + + if (*tok) + rc = parse_nidrange(tok, nidlist); } - return 1; + kfree(orig); + if (rc) + cfs_free_nidlist(nidlist); + else if (list_empty(nidlist)) + rc = -EINVAL; + return rc; } EXPORT_SYMBOL(cfs_parse_nidlist); diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c index fa55f70..48151b9 100644 --- a/lustre/obdclass/lprocfs_status.c +++ b/lustre/obdclass/lprocfs_status.c @@ -2349,7 +2349,7 @@ int lprocfs_wr_nosquash_nids(const char __user *buffer, unsigned long count, RETURN(count); } - if (cfs_parse_nidlist(kernbuf, count, &tmp) <= 0) { + if (cfs_parse_nidlist(kernbuf, &tmp) < 0) { errmsg = "can't parse"; GOTO(failed, rc = -EINVAL); } diff --git a/lustre/obdclass/obd_mount.c b/lustre/obdclass/obd_mount.c index a586148..956997f 100644 --- a/lustre/obdclass/obd_mount.c +++ b/lustre/obdclass/obd_mount.c @@ -1305,7 +1305,7 @@ static int lmd_parse_nidlist(char *buf, char **endh) tmp = *endp; *endp = '\0'; - if (cfs_parse_nidlist(buf, strlen(buf), &nidlist) <= 0) + if (cfs_parse_nidlist(buf, &nidlist) < 0) rc = 1; cfs_free_nidlist(&nidlist); diff --git a/lustre/ptlrpc/nrs_tbf.c b/lustre/ptlrpc/nrs_tbf.c index 4ed0a66..13afda2 100644 --- a/lustre/ptlrpc/nrs_tbf.c +++ b/lustre/ptlrpc/nrs_tbf.c @@ -1192,8 +1192,7 @@ static int nrs_tbf_nid_rule_init(struct ptlrpc_nrs_policy *policy, INIT_LIST_HEAD(&rule->tr_nids); if (!list_empty(&start->u.tc_start.ts_nids)) { if (cfs_parse_nidlist(rule->tr_nids_str, - strlen(rule->tr_nids_str), - &rule->tr_nids) <= 0) { + &rule->tr_nids) < 0) { CERROR("nids {%s} illegal\n", rule->tr_nids_str); OBD_FREE(rule->tr_nids_str, @@ -1253,8 +1252,7 @@ static int nrs_tbf_nid_parse(struct nrs_tbf_cmd *cmd, char *id) /* parse NID list */ if (cfs_parse_nidlist(cmd->u.tc_start.ts_nids_str, - strlen(cmd->u.tc_start.ts_nids_str), - &cmd->u.tc_start.ts_nids) <= 0) { + &cmd->u.tc_start.ts_nids) < 0) { nrs_tbf_nid_cmd_fini(cmd); return -EINVAL; } @@ -1854,7 +1852,7 @@ nrs_tbf_expression_parse(char *str, struct list_head *cond_list) len -= 2; if (strcmp(field, "nid") == 0) { - if (cfs_parse_nidlist(str, len, &expr->te_cond) <= 0) + if (cfs_parse_nidlist(str, &expr->te_cond) < 0) GOTO(out, rc = -EINVAL); expr->te_field = NRS_TBF_FIELD_NID; } else if (strcmp(field, "jobid") == 0) { -- 1.8.3.1