From: Jian Yu <jian.yu@xxxxxxxxx> The lmd_parse() function parses mount options with comma as delimiter without considering commas in expr_list as follows is a valid LNET nid range syntax: <expr_list> :== '[' <range_expr> [ ',' <range_expr>] ']' This patch fixes the above issue by using cfs_parse_nidlist() to parse nid range list instead of using class_parse_nid_quiet() to parse only one nid. Signed-off-by: Jian Yu <jian.yu@xxxxxxxxx> Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5690 Reviewed-on: http://review.whamcloud.com/17036 Reviewed-by: Niu Yawei <yawei.niu@xxxxxxxxx> Reviewed-by: Bob Glossman <bob.glossman@xxxxxxxxx> Reviewed-by: Oleg Drokin <oleg.drokin@xxxxxxxxx> Signed-off-by: James Simmons <jsimmons@xxxxxxxxxxxxx> --- drivers/staging/lustre/lustre/obdclass/obd_mount.c | 91 ++++++++++++++++++-- 1 files changed, 85 insertions(+), 6 deletions(-) diff --git a/drivers/staging/lustre/lustre/obdclass/obd_mount.c b/drivers/staging/lustre/lustre/obdclass/obd_mount.c index 2283e92..1eb8e71 100644 --- a/drivers/staging/lustre/lustre/obdclass/obd_mount.c +++ b/drivers/staging/lustre/lustre/obdclass/obd_mount.c @@ -871,6 +871,87 @@ static int lmd_parse_mgs(struct lustre_mount_data *lmd, char **ptr) return 0; } +/** + * Find the first comma delimiter from the specified \a buf and make \a *endh + * point to the string starting with the comma. The commas in expression list + * [...] will be skipped. + * + * \param[in] buf a comma-separated string + * \param[in] endh a pointer to a pointer that will point to the string + * starting with the comma + * + * \retval 0 if comma delimiter is found + * \retval 1 if comma delimiter is not found + */ +static int lmd_find_comma(char *buf, char **endh) +{ + char *c = buf; + int skip = 0; + + if (!buf) + return 1; + + while (*c != '\0') { + if (*c == '[') + skip++; + else if (*c == ']') + skip--; + + if (*c == ',' && !skip) { + if (endh) + *endh = c; + return 0; + } + c++; + } + return 1; +} + +/** + * Find the first valid string delimited by comma from the specified \a buf + # and parse it to see whether it's a valid nid list. If yes, \a *endh will + * point to the next string starting with the comma. + * + * \param[in] buf a comma-separated string + * \param[in] endh a pointer to a pointer that will point to the string + * starting with the comma + * + * \retval 0 if the string is a valid nid list + * \retval 1 if the string is not a valid nid list + */ +static int lmd_parse_nidlist(char *buf, char **endh) +{ + struct list_head nidlist; + char *endp = buf; + int rc = 0; + char tmp; + + if (!buf) + return 1; + while (*buf == ',' || *buf == ':') + buf++; + if (*buf == ' ' || *buf == '/' || *buf == '\0') + return 1; + + if (lmd_find_comma(buf, &endp)) + endp = buf + strlen(buf); + + tmp = *endp; + *endp = '\0'; + + INIT_LIST_HEAD(&nidlist); + if (cfs_parse_nidlist(buf, strlen(buf), &nidlist) <= 0) + rc = 1; + cfs_free_nidlist(&nidlist); + + *endp = tmp; + if (rc) + return rc; + if (endh) + *endh = endp; + return 0; +} + /** Parse mount line options * e.g. mount -v -t lustre -o abort_recov uml1:uml2:/lustre-client /mnt/lustre * dev is passed as device=uml1:/lustre by mount.lustre @@ -987,19 +1068,17 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd) clear++; } else if (strncmp(s1, "param=", 6) == 0) { size_t length, params_length; - char *tail = strchr(s1 + 6, ','); + char *tail = s1; - if (!tail) { + if (lmd_find_comma(s1 + 6, &tail)) { length = strlen(s1); } else { - lnet_nid_t nid; char *param_str = tail + 1; int supplementary = 1; - while (!class_parse_nid_quiet(param_str, &nid, - ¶m_str)) { + while (!lmd_parse_nidlist(param_str, + ¶m_str)) supplementary = 0; - } length = param_str - s1 - supplementary; } length -= 6; -- 1.7.1 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel