parse: fix min/max val checking for FIO_OPT_INT
authorJens Axboe <axboe@kernel.dk>
Wed, 26 Sep 2018 01:24:36 +0000 (19:24 -0600)
committerJens Axboe <axboe@kernel.dk>
Wed, 26 Sep 2018 01:24:36 +0000 (19:24 -0600)
We compare an unsigned long long to an int max/min value, this
is going to break for negative numbers, for instance.

Fixes a case where flow=-1 doesn't work properly because of that.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
parse.c

diff --git a/parse.c b/parse.c
index 196de1553b8e4992d499c299bc7bb7efa1f5be61..9a20d0c778260bc9ee5b2b3387c4fcb851c4ca0f 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -506,6 +506,36 @@ static const char *opt_type_name(const struct fio_option *o)
        return "OPT_UNKNOWN?";
 }
 
        return "OPT_UNKNOWN?";
 }
 
+static bool val_too_large(const struct fio_option *o, unsigned long long val,
+                         bool is_uint)
+{
+       if (!o->maxval)
+               return false;
+
+       if (is_uint) {
+               unsigned int uint_val = val;
+
+               return uint_val > o->maxval;
+       }
+
+       return val > o->maxval;
+}
+
+static bool val_too_small(const struct fio_option *o, unsigned long long val,
+                         bool is_uint)
+{
+       if (!o->minval)
+               return false;
+
+       if (is_uint) {
+               unsigned int uint_val = val;
+
+               return uint_val < o->minval;
+       }
+
+       return val < o->minval;
+}
+
 static int __handle_option(const struct fio_option *o, const char *ptr,
                           void *data, int first, int more, int curr)
 {
 static int __handle_option(const struct fio_option *o, const char *ptr,
                           void *data, int first, int more, int curr)
 {
@@ -595,12 +625,12 @@ static int __handle_option(const struct fio_option *o, const char *ptr,
                        return 1;
                }
 
                        return 1;
                }
 
-               if (o->maxval && ull > o->maxval) {
+               if (val_too_large(o, ull, o->type == FIO_OPT_INT)) {
                        log_err("%s: max value out of range: %llu"
                                " (%llu max)\n", o->name, ull, o->maxval);
                        return 1;
                }
                        log_err("%s: max value out of range: %llu"
                                " (%llu max)\n", o->name, ull, o->maxval);
                        return 1;
                }
-               if (o->minval && ull < o->minval) {
+               if (val_too_small(o, ull, o->type == FIO_OPT_INT)) {
                        log_err("%s: min value out of range: %lld"
                                " (%d min)\n", o->name, ull, o->minval);
                        return 1;
                        log_err("%s: min value out of range: %lld"
                                " (%d min)\n", o->name, ull, o->minval);
                        return 1;