Whamcloud - gitweb
LU-9859 llite: simplify parsing in pcc_conds_parse() 39/50839/6
authorMr NeilBrown <neilb@suse.de>
Tue, 24 Nov 2020 06:16:38 +0000 (17:16 +1100)
committerOleg Drokin <green@whamcloud.com>
Wed, 19 Jul 2023 16:43:50 +0000 (16:43 +0000)
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 <neilb@suse.de>
Change-Id: Ia0d0fb4fbc8d85f1e47e6085392e0f84b000b8a8
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/50839
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Feng Lei <flei@whamcloud.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Qian Yingjin <qian@ddn.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/llite/pcc.c

index bbd8d02..25a4820 100644 (file)
@@ -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);