]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
avoid casting pointer arguments to argconfig functions
authorJoy Gu <jgu@purestorage.com>
Thu, 24 Aug 2023 20:55:08 +0000 (13:55 -0700)
committerDaniel Wagner <dwagner@suse.de>
Mon, 4 Sep 2023 17:07:37 +0000 (19:07 +0200)
Same issue as 456a24e8daa7e0cccddfef7deaffe7b200358706 ("Don't cast
pointers, cast values."), which was undone in
18de3a6d61a7f090ecea9f6afa52c2d6591d1700 ("Convert to libnvme").

Add some functions to argconfig so that we can directly pass in
__u16/__u32/__u64 arrays without casting to int/long/etc, since an int
isn't always 32 bits, an unsigned long long isn't always 64 bits, etc.

Suggested-by: Randy Jennings <randyj@purestorage.com>
nvme.c
util/argconfig.c
util/argconfig.h

diff --git a/nvme.c b/nvme.c
index 11cb3844eee14fdad7885e459c5ed4c9986a87c0..db2f51e62d99f6f846a3936c9ed7f6e039fdc19d 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -6729,9 +6729,9 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin
        if (err)
                goto ret;
 
-       nc = argconfig_parse_comma_sep_array(cfg.ctx_attrs, (int *)ctx_attrs, ARRAY_SIZE(ctx_attrs));
-       nb = argconfig_parse_comma_sep_array(cfg.blocks, (int *)nlbs, ARRAY_SIZE(nlbs));
-       ns = argconfig_parse_comma_sep_array_long(cfg.slbas, (unsigned long long *)slbas, ARRAY_SIZE(slbas));
+       nc = argconfig_parse_comma_sep_array_u32(cfg.ctx_attrs, ctx_attrs, ARRAY_SIZE(ctx_attrs));
+       nb = argconfig_parse_comma_sep_array_u32(cfg.blocks, nlbs, ARRAY_SIZE(nlbs));
+       ns = argconfig_parse_comma_sep_array_u64(cfg.slbas, slbas, ARRAY_SIZE(slbas));
        nr = max(nc, max(nb, ns));
        if (!nr || nr > 256) {
                nvme_show_error("No range definition provided");
@@ -6798,7 +6798,7 @@ static int copy_cmd(int argc, char **argv, struct command *cmd, struct plugin *p
 
        uint16_t nr, nb, ns, nrts, natms, nats;
        __u16 nlbs[128] = { 0 };
-       unsigned long long slbas[128] = {0,};
+       __u64 slbas[128] = { 0 };
        struct nvme_dev *dev;
        int err;
 
@@ -6880,24 +6880,23 @@ static int copy_cmd(int argc, char **argv, struct command *cmd, struct plugin *p
        if (err)
                goto ret;
 
-       nb = argconfig_parse_comma_sep_array_short(cfg.nlbs, nlbs, ARRAY_SIZE(nlbs));
-       ns = argconfig_parse_comma_sep_array_long(cfg.slbas, slbas, ARRAY_SIZE(slbas));
+       nb = argconfig_parse_comma_sep_array_u16(cfg.nlbs, nlbs, ARRAY_SIZE(nlbs));
+       ns = argconfig_parse_comma_sep_array_u64(cfg.slbas, slbas, ARRAY_SIZE(slbas));
 
        if (cfg.format == 0) {
-               nrts = argconfig_parse_comma_sep_array(cfg.eilbrts, (int *)eilbrts.f0,
-                                                      ARRAY_SIZE(eilbrts.f0));
+               nrts = argconfig_parse_comma_sep_array_u32(cfg.eilbrts, eilbrts.f0,
+                                                          ARRAY_SIZE(eilbrts.f0));
        } else if (cfg.format == 1) {
-               nrts = argconfig_parse_comma_sep_array_long(cfg.eilbrts,
-                                                           (unsigned long long *)eilbrts.f1,
-                                                           ARRAY_SIZE(eilbrts.f1));
+               nrts = argconfig_parse_comma_sep_array_u64(cfg.eilbrts, eilbrts.f1,
+                                                          ARRAY_SIZE(eilbrts.f1));
        } else {
                nvme_show_error("invalid format");
                err = -EINVAL;
                goto close_dev;
        }
 
-       natms = argconfig_parse_comma_sep_array(cfg.elbatms, (int *)elbatms, ARRAY_SIZE(elbatms));
-       nats = argconfig_parse_comma_sep_array(cfg.elbats, (int *)elbats, ARRAY_SIZE(elbats));
+       natms = argconfig_parse_comma_sep_array_u32(cfg.elbatms, elbatms, ARRAY_SIZE(elbatms));
+       nats = argconfig_parse_comma_sep_array_u32(cfg.elbats, elbats, ARRAY_SIZE(elbats));
 
        nr = max(nb, max(ns, max(nrts, max(natms, nats))));
        if (!nr || nr > 128 || (cfg.format == 1 && nr > 101)) {
@@ -6915,11 +6914,9 @@ static int copy_cmd(int argc, char **argv, struct command *cmd, struct plugin *p
        }
 
        if (cfg.format == 0)
-               nvme_init_copy_range(copy.f0, nlbs, (__u64 *)slbas,
-                 eilbrts.f0, elbatms, elbats, nr);
+               nvme_init_copy_range(copy.f0, nlbs, slbas, eilbrts.f0, elbatms, elbats, nr);
        else if (cfg.format == 1)
-               nvme_init_copy_range_f1(copy.f1, nlbs, (__u64 *)slbas,
-                 eilbrts.f1, elbatms, elbats, nr);
+               nvme_init_copy_range_f1(copy.f1, nlbs, slbas, eilbrts.f1, elbatms, elbats, nr);
 
        struct nvme_copy_args args = {
                .args_size      = sizeof(args),
index 91f499813d3a039d2e68b274046e6504b8781e67..251da48c5c7acc1ac3d1f17c823c6215535774cd 100644 (file)
@@ -556,6 +556,58 @@ int argconfig_parse_comma_sep_array_long(char *string, unsigned long long *val,
        }
 }
 
+#define DEFINE_ARGCONFIG_PARSE_COMMA_SEP_ARRAY_UINT_FUNC(size)         \
+int argconfig_parse_comma_sep_array_u##size(char *string,              \
+                                           __u##size *val,             \
+                                           unsigned int max_length)    \
+{                                                                      \
+       int ret = 0;                                                    \
+       uintmax_t v;                                                    \
+       char *tmp;                                                      \
+       char *p;                                                        \
+                                                                       \
+       if (!string || !strlen(string))                         \
+               return 0;                                               \
+                                                                       \
+       tmp = strtok(string, ",");                                      \
+       if (!tmp)                                                       \
+               return 0;                                               \
+                                                                       \
+       v = strtoumax(tmp, &p, 0);                                      \
+       if (*p != 0)                                                    \
+               return -1;                                              \
+       if (v > UINT##size##_MAX) {                                     \
+               fprintf(stderr, "%s out of range\n", tmp);              \
+               return -1;                                              \
+       }                                                               \
+       val[ret] = v;                                                   \
+                                                                       \
+       ret++;                                                          \
+       while (1) {                                                     \
+               tmp = strtok(NULL, ",");                                \
+                                                                       \
+               if (tmp == NULL)                                        \
+                       return ret;                                     \
+                                                                       \
+               if (ret >= max_length)                                  \
+                       return -1;                                      \
+                                                                       \
+               v = strtoumax(tmp, &p, 0);                              \
+               if (*p != 0)                                            \
+                       return -1;                                      \
+               if (v > UINT##size##_MAX) {                             \
+                       fprintf(stderr, "%s out of range\n", tmp);      \
+                       return -1;                                      \
+               }                                                       \
+               val[ret] = v;                                           \
+               ret++;                                                  \
+       }                                                               \
+}
+
+DEFINE_ARGCONFIG_PARSE_COMMA_SEP_ARRAY_UINT_FUNC(16);
+DEFINE_ARGCONFIG_PARSE_COMMA_SEP_ARRAY_UINT_FUNC(32);
+DEFINE_ARGCONFIG_PARSE_COMMA_SEP_ARRAY_UINT_FUNC(64);
+
 bool argconfig_parse_seen(struct argconfig_commandline_options *s,
                          const char *option)
 {
index 58dd698b3079af4bef9f6d3476d7ad772c3be4f2..364cbe7e04892fd1dfe8d7ec752dae3a79b71b76 100644 (file)
@@ -41,6 +41,8 @@
 #include <stdbool.h>
 #include <stdint.h>
 
+#include <linux/types.h>
+
 enum argconfig_types {
        CFG_FLAG,
        CFG_STRING,
@@ -173,6 +175,12 @@ int argconfig_parse_comma_sep_array_short(char *string, unsigned short *ret,
                                          unsigned int max_length);
 int argconfig_parse_comma_sep_array_long(char *string, unsigned long long *ret,
                                         unsigned int max_length);
+int argconfig_parse_comma_sep_array_u16(char *string, __u16 *val,
+                                       unsigned int max_length);
+int argconfig_parse_comma_sep_array_u32(char *string, __u32 *val,
+                                       unsigned int max_length);
+int argconfig_parse_comma_sep_array_u64(char *string, __u64 *val,
+                                       unsigned int max_length);
 int argconfig_parse_byte(const char *opt, const char *str, unsigned char *val);
 
 void print_word_wrapped(const char *s, int indent, int start, FILE *stream);