options: split out option grouping code
[fio.git] / options.c
index e306b28b6c08398c139f162b309523ec6f990c63..a60b6e195c5506844bd3c06489085a04fb87516e 100644 (file)
--- a/options.c
+++ b/options.c
 #include "verify.h"
 #include "parse.h"
 #include "lib/fls.h"
+#include "lib/pattern.h"
 #include "options.h"
+#include "optgroup.h"
 
 #include "crc/crc32c.h"
 
 char client_sockaddr_str[INET6_ADDRSTRLEN] = { 0 };
 
+struct pattern_fmt_desc fmt_desc[] = {
+       {
+               .fmt   = "%o",
+               .len   = FIELD_SIZE(struct io_u *, offset),
+               .paste = paste_blockoff
+       }
+};
+
 /*
  * Check if mmap/mmaphuge has a :/foo/bar/file at the end. If so, return that.
  */
@@ -36,26 +46,6 @@ static char *get_opt_postfix(const char *str)
        return strdup(p);
 }
 
-static int converthexchartoint(char a)
-{
-       int base;
-
-       switch (a) {
-       case '0'...'9':
-               base = '0';
-               break;
-       case 'A'...'F':
-               base = 'A' - 10;
-               break;
-       case 'a'...'f':
-               base = 'a' - 10;
-               break;
-       default:
-               base = 0;
-       }
-       return a - base;
-}
-
 static int bs_cmp(const void *p1, const void *p2)
 {
        const struct bssplit *bsp1 = p1;
@@ -215,7 +205,8 @@ static int str_bssplit_cb(void *data, const char *input)
                        ret = bssplit_ddir(&td->o, DDIR_TRIM, op);
                        free(op);
                }
-               ret = bssplit_ddir(&td->o, DDIR_READ, str);
+               if (!ret)
+                       ret = bssplit_ddir(&td->o, DDIR_READ, str);
        }
 
        free(p);
@@ -362,7 +353,8 @@ static int str_mem_cb(void *data, const char *mem)
 {
        struct thread_data *td = data;
 
-       if (td->o.mem_type == MEM_MMAPHUGE || td->o.mem_type == MEM_MMAP)
+       if (td->o.mem_type == MEM_MMAPHUGE || td->o.mem_type == MEM_MMAP ||
+           td->o.mem_type == MEM_MMAPSHARED)
                td->o.mmapfile = get_opt_postfix(mem);
 
        return 0;
@@ -539,9 +531,25 @@ static int str_verify_cpus_allowed_cb(void *data, const char *input)
 {
        struct thread_data *td = data;
 
+       if (parse_dryrun())
+               return 0;
+
        return set_cpus_allowed(td, &td->o.verify_cpumask, input);
 }
-#endif
+
+#ifdef CONFIG_ZLIB
+static int str_log_cpus_allowed_cb(void *data, const char *input)
+{
+       struct thread_data *td = data;
+
+       if (parse_dryrun())
+               return 0;
+
+       return set_cpus_allowed(td, &td->o.log_gz_cpumask, input);
+}
+#endif /* CONFIG_ZLIB */
+
+#endif /* FIO_HAVE_CPU_AFFINITY */
 
 #ifdef CONFIG_LIBNUMA
 static int str_numa_cpunodes_cb(void *data, char *input)
@@ -914,122 +922,25 @@ static int str_opendir_cb(void *data, const char fio_unused *str)
        return add_dir_files(td, td->o.opendir);
 }
 
-static int pattern_cb(char *pattern, unsigned int max_size,
-                     const char *input, unsigned int *pattern_bytes)
-{
-       long off;
-       int i = 0, j = 0, len, k, base = 10;
-       uint32_t pattern_length;
-       char *loc1, *loc2;
-
-       /*
-        * Check if it's a string input
-        */
-       loc1 = strchr(input, '\"');
-       if (loc1) {
-               do {
-                       loc1++;
-                       if (*loc1 == '\0' || *loc1 == '\"')
-                               break;
-
-                       pattern[i] = *loc1;
-                       i++;
-               } while (i < max_size);
-
-               if (!i)
-                       return 1;
-
-               goto fill;
-       }
-
-       /*
-        * No string, find out if it's decimal or hexidecimal
-        */
-       loc1 = strstr(input, "0x");
-       loc2 = strstr(input, "0X");
-       if (loc1 || loc2)
-               base = 16;
-       off = strtol(input, NULL, base);
-       if (off != LONG_MAX || errno != ERANGE) {
-               while (off) {
-                       pattern[i] = off & 0xff;
-                       off >>= 8;
-                       i++;
-               }
-       } else {
-               len = strlen(input);
-               k = len - 1;
-               if (base == 16) {
-                       if (loc1)
-                               j = loc1 - input + 2;
-                       else
-                               j = loc2 - input + 2;
-               } else
-                       return 1;
-               if (len - j < max_size * 2) {
-                       while (k >= j) {
-                               off = converthexchartoint(input[k--]);
-                               if (k >= j)
-                                       off += (converthexchartoint(input[k--])
-                                               * 16);
-                               pattern[i++] = (char) off;
-                       }
-               }
-       }
-
-       /*
-        * Fill the pattern all the way to the end. This greatly reduces
-        * the number of memcpy's we have to do when verifying the IO.
-        */
-fill:
-       pattern_length = i;
-       while (i > 1 && i * 2 <= max_size) {
-               memcpy(&pattern[i], &pattern[0], i);
-               i *= 2;
-       }
-
-       /*
-        * Fill remainder, if the pattern multiple ends up not being
-        * max_size.
-        */
-       while (i > 1 && i < max_size) {
-               unsigned int b = min(pattern_length, max_size - i);
-
-               memcpy(&pattern[i], &pattern[0], b);
-               i += b;
-       }
-
-       if (i == 1) {
-               /*
-                * The code in verify_io_u_pattern assumes a single byte
-                * pattern fills the whole verify pattern buffer.
-                */
-               memset(pattern, pattern[0], max_size);
-       }
-
-       *pattern_bytes = i;
-       return 0;
-}
-
 static int str_buffer_pattern_cb(void *data, const char *input)
 {
        struct thread_data *td = data;
        int ret;
 
-       ret = pattern_cb(td->o.buffer_pattern, MAX_PATTERN_SIZE, input,
-                               &td->o.buffer_pattern_bytes);
+       /* FIXME: for now buffer pattern does not support formats */
+       ret = parse_and_fill_pattern(input, strlen(input), td->o.buffer_pattern,
+                                    MAX_PATTERN_SIZE, NULL, 0, NULL, NULL);
+       if (ret < 0)
+               return 1;
 
-       if (!ret && td->o.buffer_pattern_bytes) {
-               if (!td->o.compress_percentage)
-                       td->o.refill_buffers = 0;
-               td->o.scramble_buffers = 0;
-               td->o.zero_buffers = 0;
-       } else {
-               log_err("fio: failed parsing pattern `%s`\n", input);
-               ret = 1;
-       }
+       assert(ret != 0);
+       td->o.buffer_pattern_bytes = ret;
+       if (!td->o.compress_percentage)
+               td->o.refill_buffers = 0;
+       td->o.scramble_buffers = 0;
+       td->o.zero_buffers = 0;
 
-       return ret;
+       return 0;
 }
 
 static int str_buffer_compress_cb(void *data, unsigned long long *il)
@@ -1056,16 +967,22 @@ static int str_verify_pattern_cb(void *data, const char *input)
        struct thread_data *td = data;
        int ret;
 
-       ret = pattern_cb(td->o.verify_pattern, MAX_PATTERN_SIZE, input,
-                               &td->o.verify_pattern_bytes);
+       td->o.verify_fmt_sz = ARRAY_SIZE(td->o.verify_fmt);
+       ret = parse_and_fill_pattern(input, strlen(input), td->o.verify_pattern,
+                                    MAX_PATTERN_SIZE, fmt_desc, sizeof(fmt_desc),
+                                    td->o.verify_fmt, &td->o.verify_fmt_sz);
+       if (ret < 0)
+               return 1;
 
+       assert(ret != 0);
+       td->o.verify_pattern_bytes = ret;
        /*
-        * VERIFY_META could already be set
+        * VERIFY_* could already be set
         */
-       if (!ret && td->o.verify == VERIFY_NONE)
+       if (!fio_option_is_set(&td->o, verify))
                td->o.verify = VERIFY_PATTERN;
 
-       return ret;
+       return 0;
 }
 
 static int str_gtod_reduce_cb(void *data, int *il)
@@ -1126,169 +1043,6 @@ static int gtod_cpu_verify(struct fio_option *o, void *data)
        return 0;
 }
 
-/*
- * Option grouping
- */
-static struct opt_group fio_opt_groups[] = {
-       {
-               .name   = "General",
-               .mask   = FIO_OPT_C_GENERAL,
-       },
-       {
-               .name   = "I/O",
-               .mask   = FIO_OPT_C_IO,
-       },
-       {
-               .name   = "File",
-               .mask   = FIO_OPT_C_FILE,
-       },
-       {
-               .name   = "Statistics",
-               .mask   = FIO_OPT_C_STAT,
-       },
-       {
-               .name   = "Logging",
-               .mask   = FIO_OPT_C_LOG,
-       },
-       {
-               .name   = "Profiles",
-               .mask   = FIO_OPT_C_PROFILE,
-       },
-       {
-               .name   = NULL,
-       },
-};
-
-static struct opt_group *__opt_group_from_mask(struct opt_group *ogs, unsigned int *mask,
-                                              unsigned int inv_mask)
-{
-       struct opt_group *og;
-       int i;
-
-       if (*mask == inv_mask || !*mask)
-               return NULL;
-
-       for (i = 0; ogs[i].name; i++) {
-               og = &ogs[i];
-
-               if (*mask & og->mask) {
-                       *mask &= ~(og->mask);
-                       return og;
-               }
-       }
-
-       return NULL;
-}
-
-struct opt_group *opt_group_from_mask(unsigned int *mask)
-{
-       return __opt_group_from_mask(fio_opt_groups, mask, FIO_OPT_C_INVALID);
-}
-
-static struct opt_group fio_opt_cat_groups[] = {
-       {
-               .name   = "Latency profiling",
-               .mask   = FIO_OPT_G_LATPROF,
-       },
-       {
-               .name   = "Rate",
-               .mask   = FIO_OPT_G_RATE,
-       },
-       {
-               .name   = "Zone",
-               .mask   = FIO_OPT_G_ZONE,
-       },
-       {
-               .name   = "Read/write mix",
-               .mask   = FIO_OPT_G_RWMIX,
-       },
-       {
-               .name   = "Verify",
-               .mask   = FIO_OPT_G_VERIFY,
-       },
-       {
-               .name   = "Trim",
-               .mask   = FIO_OPT_G_TRIM,
-       },
-       {
-               .name   = "I/O Logging",
-               .mask   = FIO_OPT_G_IOLOG,
-       },
-       {
-               .name   = "I/O Depth",
-               .mask   = FIO_OPT_G_IO_DEPTH,
-       },
-       {
-               .name   = "I/O Flow",
-               .mask   = FIO_OPT_G_IO_FLOW,
-       },
-       {
-               .name   = "Description",
-               .mask   = FIO_OPT_G_DESC,
-       },
-       {
-               .name   = "Filename",
-               .mask   = FIO_OPT_G_FILENAME,
-       },
-       {
-               .name   = "General I/O",
-               .mask   = FIO_OPT_G_IO_BASIC,
-       },
-       {
-               .name   = "Cgroups",
-               .mask   = FIO_OPT_G_CGROUP,
-       },
-       {
-               .name   = "Runtime",
-               .mask   = FIO_OPT_G_RUNTIME,
-       },
-       {
-               .name   = "Process",
-               .mask   = FIO_OPT_G_PROCESS,
-       },
-       {
-               .name   = "Job credentials / priority",
-               .mask   = FIO_OPT_G_CRED,
-       },
-       {
-               .name   = "Clock settings",
-               .mask   = FIO_OPT_G_CLOCK,
-       },
-       {
-               .name   = "I/O Type",
-               .mask   = FIO_OPT_G_IO_TYPE,
-       },
-       {
-               .name   = "I/O Thinktime",
-               .mask   = FIO_OPT_G_THINKTIME,
-       },
-       {
-               .name   = "Randomizations",
-               .mask   = FIO_OPT_G_RANDOM,
-       },
-       {
-               .name   = "I/O buffers",
-               .mask   = FIO_OPT_G_IO_BUF,
-       },
-       {
-               .name   = "Tiobench profile",
-               .mask   = FIO_OPT_G_TIOBENCH,
-       },
-       {
-               .name   = "MTD",
-               .mask   = FIO_OPT_G_MTD,
-       },
-
-       {
-               .name   = NULL,
-       }
-};
-
-struct opt_group *opt_group_cat_from_mask(unsigned int *mask)
-{
-       return __opt_group_from_mask(fio_opt_cat_groups, mask, FIO_OPT_G_INVALID);
-}
-
 /*
  * Map of job/command line options
  */
@@ -1311,6 +1065,15 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_GENERAL,
                .group  = FIO_OPT_G_DESC,
        },
+       {
+               .name   = "wait_for",
+               .lname  = "Waitee name",
+               .type   = FIO_OPT_STR_STORE,
+               .off1   = td_var_offset(wait_for),
+               .help   = "Name of the job this one wants to wait for before starting",
+               .category = FIO_OPT_C_GENERAL,
+               .group  = FIO_OPT_G_DESC,
+       },
        {
                .name   = "filename",
                .lname  = "Filename(s)",
@@ -1606,11 +1369,12 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .group  = FIO_OPT_G_IO_BASIC,
        },
        {
-               .name   = "iodepth_batch_complete",
-               .lname  = "IO Depth batch complete",
+               .name   = "iodepth_batch_complete_min",
+               .lname  = "Min IO depth batch complete",
+               .alias  = "iodepth_batch_complete",
                .type   = FIO_OPT_INT,
-               .off1   = td_var_offset(iodepth_batch_complete),
-               .help   = "Number of IO buffers to retrieve in one go",
+               .off1   = td_var_offset(iodepth_batch_complete_min),
+               .help   = "Min number of IO buffers to retrieve in one go",
                .parent = "iodepth",
                .hide   = 1,
                .minval = 0,
@@ -1619,6 +1383,19 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_IO,
                .group  = FIO_OPT_G_IO_BASIC,
        },
+       {
+               .name   = "iodepth_batch_complete_max",
+               .lname  = "Max IO depth batch complete",
+               .type   = FIO_OPT_INT,
+               .off1   = td_var_offset(iodepth_batch_complete_max),
+               .help   = "Max number of IO buffers to retrieve in one go",
+               .parent = "iodepth",
+               .hide   = 1,
+               .minval = 0,
+               .interval = 1,
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_IO_BASIC,
+       },
        {
                .name   = "iodepth_low",
                .lname  = "IO Depth batch low",
@@ -1897,6 +1674,11 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                            .oval = FIO_RAND_GEN_LFSR,
                            .help = "Variable length LFSR",
                          },
+                         {
+                           .ival = "tausworthe64",
+                           .oval = FIO_RAND_GEN_TAUSWORTHE64,
+                           .help = "64-bit Tausworthe variant",
+                         },
                },
                .category = FIO_OPT_C_IO,
                .group  = FIO_OPT_G_RANDOM,
@@ -2311,6 +2093,10 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                            .oval = MEM_MMAP,
                            .help = "Use mmap(2) (file or anon) for IO buffers",
                          },
+                         { .ival = "mmapshared",
+                           .oval = MEM_MMAPSHARED,
+                           .help = "Like mmap, but use the shared flag",
+                         },
 #ifdef FIO_HAVE_HUGETLB
                          { .ival = "mmaphuge",
                            .oval = MEM_MMAPHUGE,
@@ -2391,9 +2177,17 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                            .oval = VERIFY_XXHASH,
                            .help = "Use xxhash checksums for verification",
                          },
+                         /* Meta information was included into verify_header,
+                          * 'meta' verification is implied by default. */
                          { .ival = "meta",
-                           .oval = VERIFY_META,
-                           .help = "Use io information",
+                           .oval = VERIFY_HDR_ONLY,
+                           .help = "Use io information for verification. "
+                                   "Now is implied by default, thus option is obsolete, "
+                                   "don't use it",
+                         },
+                         { .ival = "pattern",
+                           .oval = VERIFY_PATTERN_NO_HDR,
+                           .help = "Verify strict pattern",
                          },
                          {
                            .ival = "null",
@@ -2888,7 +2682,8 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .group  = FIO_OPT_G_RATE,
        },
        {
-               .name   = "ratemin",
+               .name   = "rate_min",
+               .alias  = "ratemin",
                .lname  = "I/O min rate",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(ratemin[DDIR_READ]),
@@ -2926,7 +2721,30 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .group  = FIO_OPT_G_RATE,
        },
        {
-               .name   = "ratecycle",
+               .name   = "rate_process",
+               .lname  = "Rate Process",
+               .type   = FIO_OPT_STR,
+               .off1   = td_var_offset(rate_process),
+               .help   = "What process controls how rated IO is managed",
+               .def    = "linear",
+               .category = FIO_OPT_C_IO,
+               .group  = FIO_OPT_G_RATE,
+               .posval = {
+                         { .ival = "linear",
+                           .oval = RATE_PROCESS_LINEAR,
+                           .help = "Linear rate of IO",
+                         },
+                         {
+                           .ival = "poisson",
+                           .oval = RATE_PROCESS_POISSON,
+                           .help = "Rate follows Poisson process",
+                         },
+               },
+               .parent = "rate",
+       },
+       {
+               .name   = "rate_cycle",
+               .alias  = "ratecycle",
                .lname  = "I/O rate cycle",
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(ratecycle),
@@ -3039,6 +2857,26 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_FILE,
                .def    = "0",
        },
+       {
+               .name   = "allow_file_create",
+               .lname  = "Allow file create",
+               .type   = FIO_OPT_BOOL,
+               .off1   = td_var_offset(allow_create),
+               .help   = "Permit fio to create files, if they don't exist",
+               .def    = "1",
+               .category = FIO_OPT_C_FILE,
+               .group  = FIO_OPT_G_FILENAME,
+       },
+       {
+               .name   = "allow_mounted_write",
+               .lname  = "Allow mounted write",
+               .type   = FIO_OPT_BOOL,
+               .off1   = td_var_offset(allow_mounted_write),
+               .help   = "Allow writes to a mounted partition",
+               .def    = "0",
+               .category = FIO_OPT_C_FILE,
+               .group  = FIO_OPT_G_FILENAME,
+       },
        {
                .name   = "pre_read",
                .lname  = "Pre-read files",
@@ -3151,6 +2989,15 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_GENERAL,
                .group  = FIO_OPT_G_PROCESS,
        },
+       {
+               .name   = "exitall_on_error",
+               .lname  = "Exit-all on terminate in error",
+               .type   = FIO_OPT_BOOL,
+               .off1   = td_var_offset(unlink),
+               .help   = "Terminate all jobs when one exits in error",
+               .category = FIO_OPT_C_GENERAL,
+               .group  = FIO_OPT_G_PROCESS,
+       },
        {
                .name   = "stonewall",
                .lname  = "Wait for previous",
@@ -3183,6 +3030,15 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .category = FIO_OPT_C_GENERAL,
                .group  = FIO_OPT_G_PROCESS,
        },
+       {
+               .name   = "per_job_logs",
+               .type   = FIO_OPT_BOOL,
+               .off1   = td_var_offset(per_job_logs),
+               .help   = "Include job number in generated log files or not",
+               .def    = "1",
+               .category = FIO_OPT_C_LOG,
+               .group  = FIO_OPT_G_INVALID,
+       },
        {
                .name   = "write_bw_log",
                .lname  = "Write bandwidth log",
@@ -3237,11 +3093,24 @@ struct fio_option fio_options[FIO_MAX_OPTS] = {
                .type   = FIO_OPT_INT,
                .off1   = td_var_offset(log_gz),
                .help   = "Log in compressed chunks of this size",
-               .minval = 32 * 1024 * 1024ULL,
+               .minval = 1024ULL,
                .maxval = 512 * 1024 * 1024ULL,
                .category = FIO_OPT_C_LOG,
                .group  = FIO_OPT_G_INVALID,
        },
+#ifdef FIO_HAVE_CPU_AFFINITY
+       {
+               .name   = "log_compression_cpus",
+               .lname  = "Log Compression CPUs",
+               .type   = FIO_OPT_STR,
+               .cb     = str_log_cpus_allowed_cb,
+               .off1   = td_var_offset(log_gz_cpumask),
+               .parent = "log_compression",
+               .help   = "Limit log compression to these CPUs",
+               .category = FIO_OPT_C_LOG,
+               .group  = FIO_OPT_G_INVALID,
+       },
+#endif
        {
                .name   = "log_store_compressed",
                .lname  = "Log store compressed",
@@ -4053,14 +3922,13 @@ static void show_closest_option(const char *opt)
                i++;
        }
 
-       if (best_option != -1)
+       if (best_option != -1 && string_distance_ok(name, best_distance))
                log_err("Did you mean %s?\n", fio_options[best_option].name);
 
        free(name);
 }
 
-int fio_options_parse(struct thread_data *td, char **opts, int num_opts,
-                       int dump_cmdline)
+int fio_options_parse(struct thread_data *td, char **opts, int num_opts)
 {
        int i, ret, unknown;
        char **opts_copy;
@@ -4071,7 +3939,7 @@ int fio_options_parse(struct thread_data *td, char **opts, int num_opts,
        for (ret = 0, i = 0, unknown = 0; i < num_opts; i++) {
                struct fio_option *o;
                int newret = parse_option(opts_copy[i], opts[i], fio_options,
-                                               &o, td, dump_cmdline);
+                                               &o, td, &td->opt_list);
 
                if (!newret && o)
                        fio_option_mark_set(&td->o, o);
@@ -4104,7 +3972,7 @@ int fio_options_parse(struct thread_data *td, char **opts, int num_opts,
                        if (td->eo)
                                newret = parse_option(opts_copy[i], opts[i],
                                                      td->io_ops->options, &o,
-                                                     td->eo, dump_cmdline);
+                                                     td->eo, &td->opt_list);
 
                        ret |= newret;
                        if (!o) {
@@ -4124,7 +3992,7 @@ int fio_cmd_option_parse(struct thread_data *td, const char *opt, char *val)
 {
        int ret;
 
-       ret = parse_cmd_option(opt, val, fio_options, td);
+       ret = parse_cmd_option(opt, val, fio_options, td, &td->opt_list);
        if (!ret) {
                struct fio_option *o;
 
@@ -4139,7 +4007,8 @@ int fio_cmd_option_parse(struct thread_data *td, const char *opt, char *val)
 int fio_cmd_ioengine_option_parse(struct thread_data *td, const char *opt,
                                char *val)
 {
-       return parse_cmd_option(opt, val, td->io_ops->options, td->eo);
+       return parse_cmd_option(opt, val, td->io_ops->options, td->eo,
+                                       &td->opt_list);
 }
 
 void fio_fill_default_options(struct thread_data *td)
@@ -4325,22 +4194,22 @@ static int opt_is_set(struct thread_options *o, struct fio_option *opt)
        opt_off = opt - &fio_options[0];
        index = opt_off / (8 * sizeof(uint64_t));
        offset = opt_off & ((8 * sizeof(uint64_t)) - 1);
-       return (o->set_options[index] & (1UL << offset)) != 0;
+       return (o->set_options[index] & ((uint64_t)1 << offset)) != 0;
 }
 
-int __fio_option_is_set(struct thread_options *o, unsigned int off1)
+bool __fio_option_is_set(struct thread_options *o, unsigned int off1)
 {
        struct fio_option *opt, *next;
 
        next = NULL;
        while ((opt = find_next_opt(o, next, off1)) != NULL) {
                if (opt_is_set(o, opt))
-                       return 1;
+                       return true;
 
                next = opt;
        }
 
-       return 0;
+       return false;
 }
 
 void fio_option_mark_set(struct thread_options *o, struct fio_option *opt)
@@ -4350,5 +4219,5 @@ void fio_option_mark_set(struct thread_options *o, struct fio_option *opt)
        opt_off = opt - &fio_options[0];
        index = opt_off / (8 * sizeof(uint64_t));
        offset = opt_off & ((8 * sizeof(uint64_t)) - 1);
-       o->set_options[index] |= 1UL << offset;
+       o->set_options[index] |= (uint64_t)1 << offset;
 }