From d6136c5df6267712f824db74415cd26b6d8f19ef Mon Sep 17 00:00:00 2001 From: Mr NeilBrown Date: Tue, 24 Nov 2020 17:16:38 +1100 Subject: [PATCH] LU-9859 llite: simplify parsing in pcc_conds_parse() If we duplicate the string to be parsed we can use standard parsing tools like strsep() and strcmp(). Test-Parameters: trivial testlist=sanity-pcc Signed-off-by: Mr NeilBrown Change-Id: Ia0d0fb4fbc8d85f1e47e6085392e0f84b000b8a8 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/50839 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Feng Lei Reviewed-by: James Simmons Reviewed-by: Qian Yingjin Reviewed-by: Oleg Drokin --- lustre/llite/pcc.c | 127 +++++++++++++++++++++++------------------------------ 1 file changed, 54 insertions(+), 73 deletions(-) diff --git a/lustre/llite/pcc.c b/lustre/llite/pcc.c index bbd8d02..25a4820 100644 --- a/lustre/llite/pcc.c +++ b/lustre/llite/pcc.c @@ -205,9 +205,9 @@ static void pcc_cmd_fini(struct pcc_cmd *cmd) } } -#define PCC_DISJUNCTION_DELIM (',') -#define PCC_CONJUNCTION_DELIM ('&') -#define PCC_EXPRESSION_DELIM ('=') +#define PCC_DISJUNCTION_DELIM (",") +#define PCC_CONJUNCTION_DELIM ("&") +#define PCC_EXPRESSION_DELIM ("=") static int pcc_fname_list_add(struct cfs_lstr *id, struct list_head *fname_list) @@ -257,11 +257,9 @@ pcc_fname_list_parse(char *str, int len, struct list_head *fname_list) } static int -pcc_id_list_parse(char *str, int len, struct list_head *id_list, +pcc_id_list_parse(char *str, struct list_head *id_list, enum pcc_field type) { - struct cfs_lstr src; - struct cfs_lstr res; int rc = 0; ENTRY; @@ -270,19 +268,18 @@ pcc_id_list_parse(char *str, int len, struct list_head *id_list, type != PCC_FIELD_PROJID) RETURN(-EINVAL); - src.ls_str = str; - src.ls_len = len; INIT_LIST_HEAD(id_list); - while (src.ls_str) { + while (str) { + char *num; struct pcc_match_id *id; - __u32 id_val; + unsigned long id_val; - if (cfs_gettok(&src, ' ', &res) == 0) - GOTO(out, rc = -EINVAL); - - if (!cfs_str2num_check(res.ls_str, res.ls_len, - &id_val, 0, (u32)~0U)) - GOTO(out, rc = -EINVAL); + num = strsep(&str, " "); + if (!*num) + continue; + rc = kstrtoul(num, 0, &id_val); + if (rc) + GOTO(out, rc); OBD_ALLOC_PTR(id); if (id == NULL) @@ -291,65 +288,60 @@ pcc_id_list_parse(char *str, int len, struct list_head *id_list, id->pmi_id = id_val; list_add_tail(&id->pmi_linkage, id_list); } + if (list_empty(id_list)) + rc = -EINVAL; out: if (rc) pcc_id_list_free(id_list); RETURN(rc); } -static inline bool -pcc_check_field(struct cfs_lstr *field, char *str) -{ - int len = strlen(str); - - return (field->ls_len == len && - strncmp(field->ls_str, str, len) == 0); -} - static int -pcc_expression_parse(struct cfs_lstr *src, struct list_head *cond_list) +pcc_expression_parse(char *str, struct list_head *cond_list) { struct pcc_expression *expr; - struct cfs_lstr field; + char *field; + int len; int rc = 0; OBD_ALLOC_PTR(expr); if (expr == NULL) return -ENOMEM; - rc = cfs_gettok(src, PCC_EXPRESSION_DELIM, &field); - if (rc == 0 || src->ls_len <= 2 || src->ls_str[0] != '{' || - src->ls_str[src->ls_len - 1] != '}') + field = strim(strsep(&str, PCC_EXPRESSION_DELIM)); + if (!*field || !str) + /* No LHS or no '=' */ + GOTO(out, rc = -EINVAL); + str = skip_spaces(str); + len = strlen(str); + if (str[0] != '{' || str[len - 1] != '}') GOTO(out, rc = -EINVAL); /* Skip '{' and '}' */ - src->ls_str++; - src->ls_len -= 2; + str[len - 1] = '\0'; + str += 1; + len -= 2; - if (pcc_check_field(&field, "uid")) { - if (pcc_id_list_parse(src->ls_str, - src->ls_len, + if (strcmp(field, "uid") == 0) { + if (pcc_id_list_parse(str, &expr->pe_cond, PCC_FIELD_UID) < 0) GOTO(out, rc = -EINVAL); expr->pe_field = PCC_FIELD_UID; - } else if (pcc_check_field(&field, "gid")) { - if (pcc_id_list_parse(src->ls_str, - src->ls_len, + } else if (strcmp(field, "gid") == 0) { + if (pcc_id_list_parse(str, &expr->pe_cond, PCC_FIELD_GID) < 0) GOTO(out, rc = -EINVAL); expr->pe_field = PCC_FIELD_GID; - } else if (pcc_check_field(&field, "projid")) { - if (pcc_id_list_parse(src->ls_str, - src->ls_len, + } else if (strcmp(field, "projid") == 0) { + if (pcc_id_list_parse(str, &expr->pe_cond, PCC_FIELD_PROJID) < 0) GOTO(out, rc = -EINVAL); expr->pe_field = PCC_FIELD_PROJID; - } else if (pcc_check_field(&field, "fname")) { - if (pcc_fname_list_parse(src->ls_str, - src->ls_len, + } else if (strcmp(field, "fname") == 0) { + if (pcc_fname_list_parse(str, len, &expr->pe_cond) < 0) GOTO(out, rc = -EINVAL); expr->pe_field = PCC_FIELD_FNAME; @@ -365,10 +357,9 @@ out: } static int -pcc_conjunction_parse(struct cfs_lstr *src, struct list_head *cond_list) +pcc_conjunction_parse(char *str, struct list_head *cond_list) { struct pcc_conjunction *conjunction; - struct cfs_lstr expr; int rc = 0; OBD_ALLOC_PTR(conjunction); @@ -378,39 +369,31 @@ pcc_conjunction_parse(struct cfs_lstr *src, struct list_head *cond_list) INIT_LIST_HEAD(&conjunction->pc_expressions); list_add_tail(&conjunction->pc_linkage, cond_list); - while (src->ls_str) { - rc = cfs_gettok(src, PCC_CONJUNCTION_DELIM, &expr); - if (rc == 0) { - rc = -EINVAL; - break; - } - rc = pcc_expression_parse(&expr, - &conjunction->pc_expressions); - if (rc) - break; + while (rc == 0 && str) { + char *expr = strsep(&str, PCC_CONJUNCTION_DELIM); + + rc = pcc_expression_parse(expr, &conjunction->pc_expressions); } return rc; } -static int pcc_conds_parse(char *str, int len, struct list_head *cond_list) +static int pcc_conds_parse(char *orig, struct list_head *cond_list) { - struct cfs_lstr src; - struct cfs_lstr res; + char *str; int rc = 0; - src.ls_str = str; - src.ls_len = len; + orig = kstrdup(orig, GFP_KERNEL); + if (!orig) + return -ENOMEM; + str = orig; + INIT_LIST_HEAD(cond_list); - while (src.ls_str) { - rc = cfs_gettok(&src, PCC_DISJUNCTION_DELIM, &res); - if (rc == 0) { - rc = -EINVAL; - break; - } - rc = pcc_conjunction_parse(&res, cond_list); - if (rc) - break; + while (rc == 0 && str) { + char *term = strsep(&str, PCC_DISJUNCTION_DELIM); + + rc = pcc_conjunction_parse(term, cond_list); } + kfree(orig); return rc; } @@ -425,7 +408,6 @@ static int pcc_id_parse(struct pcc_cmd *cmd, const char *id) memcpy(cmd->u.pccc_add.pccc_conds_str, id, strlen(id)); rc = pcc_conds_parse(cmd->u.pccc_add.pccc_conds_str, - strlen(cmd->u.pccc_add.pccc_conds_str), &cmd->u.pccc_add.pccc_conds); if (rc) pcc_cmd_fini(cmd); @@ -584,8 +566,7 @@ pcc_dataset_rule_init(struct pcc_match_rule *rule, struct pcc_cmd *cmd) INIT_LIST_HEAD(&rule->pmr_conds); if (!list_empty(&cmd->u.pccc_add.pccc_conds)) rc = pcc_conds_parse(rule->pmr_conds_str, - strlen(rule->pmr_conds_str), - &rule->pmr_conds); + &rule->pmr_conds); if (rc) pcc_dataset_rule_fini(rule); -- 1.8.3.1