X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=options.c;h=f4c9bedf377fe0805c787f1bf349e5b91ce0b7e2;hp=6c6dba01403b01627d97994ecf58153d576d2857;hb=d643a1e29d31bf974a613866819dde241c928b6d;hpb=dd97d866c1b9e10b4782c1fc13df505d2f7e13ec diff --git a/options.c b/options.c index 6c6dba01..f4c9bedf 100644 --- a/options.c +++ b/options.c @@ -4,16 +4,12 @@ #include #include #include -#include -#include -#include #include #include #include "fio.h" #include "verify.h" #include "parse.h" -#include "lib/fls.h" #include "lib/pattern.h" #include "options.h" #include "optgroup.h" @@ -56,12 +52,12 @@ static int bs_cmp(const void *p1, const void *p2) struct split { unsigned int nr; - unsigned int val1[ZONESPLIT_MAX]; + unsigned long long val1[ZONESPLIT_MAX]; unsigned long long val2[ZONESPLIT_MAX]; }; static int split_parse_ddir(struct thread_options *o, struct split *split, - enum fio_ddir ddir, char *str, bool absolute) + char *str, bool absolute, unsigned int max_splits) { unsigned long long perc; unsigned int i; @@ -109,8 +105,10 @@ static int split_parse_ddir(struct thread_options *o, struct split *split, split->val1[i] = val; split->val2[i] = perc; i++; - if (i == ZONESPLIT_MAX) + if (i == max_splits) { + log_err("fio: hit max of %d split entries\n", i); break; + } } split->nr = i; @@ -121,12 +119,12 @@ static int bssplit_ddir(struct thread_options *o, enum fio_ddir ddir, char *str, bool data) { unsigned int i, perc, perc_missing; - unsigned int max_bs, min_bs; + unsigned long long max_bs, min_bs; struct split split; memset(&split, 0, sizeof(split)); - if (split_parse_ddir(o, &split, ddir, str, data)) + if (split_parse_ddir(o, &split, str, data, BSSPLIT_MAX)) return 1; if (!split.nr) return 0; @@ -343,6 +341,43 @@ static int ignore_error_type(struct thread_data *td, enum error_type_bit etype, } +static int str_replay_skip_cb(void *data, const char *input) +{ + struct thread_data *td = cb_data_to_td(data); + char *str, *p, *n; + int ret = 0; + + if (parse_dryrun()) + return 0; + + p = str = strdup(input); + + strip_blank_front(&str); + strip_blank_end(str); + + while (p) { + n = strchr(p, ','); + if (n) + *n++ = '\0'; + if (!strcmp(p, "read")) + td->o.replay_skip |= 1u << DDIR_READ; + else if (!strcmp(p, "write")) + td->o.replay_skip |= 1u << DDIR_WRITE; + else if (!strcmp(p, "trim")) + td->o.replay_skip |= 1u << DDIR_TRIM; + else if (!strcmp(p, "sync")) + td->o.replay_skip |= 1u << DDIR_SYNC; + else { + log_err("Unknown skip type: %s\n", p); + ret = 1; + break; + } + p = n; + } + free(str); + return ret; +} + static int str_ignore_error_cb(void *data, const char *input) { struct thread_data *td = cb_data_to_td(data); @@ -447,7 +482,7 @@ static int str_rwmix_write_cb(void *data, unsigned long long *val) static int str_exitall_cb(void) { - exitall_on_terminate = 1; + exitall_on_terminate = true; return 0; } @@ -458,6 +493,9 @@ int fio_cpus_split(os_cpu_mask_t *mask, unsigned int cpu_index) const long max_cpu = cpus_online(); cpus_in_mask = fio_cpu_count(mask); + if (!cpus_in_mask) + return 0; + cpu_index = cpu_index % cpus_in_mask; index = 0; @@ -846,7 +884,7 @@ static int zone_split_ddir(struct thread_options *o, enum fio_ddir ddir, memset(&split, 0, sizeof(split)); - if (split_parse_ddir(o, &split, ddir, str, absolute)) + if (split_parse_ddir(o, &split, str, absolute, ZONESPLIT_MAX)) return 1; if (!split.nr) return 0; @@ -924,48 +962,6 @@ static int zone_split_ddir(struct thread_options *o, enum fio_ddir ddir, return 0; } -static void __td_zone_gen_index(struct thread_data *td, enum fio_ddir ddir) -{ - unsigned int i, j, sprev, aprev; - uint64_t sprev_sz; - - td->zone_state_index[ddir] = malloc(sizeof(struct zone_split_index) * 100); - - sprev_sz = sprev = aprev = 0; - for (i = 0; i < td->o.zone_split_nr[ddir]; i++) { - struct zone_split *zsp = &td->o.zone_split[ddir][i]; - - for (j = aprev; j < aprev + zsp->access_perc; j++) { - struct zone_split_index *zsi = &td->zone_state_index[ddir][j]; - - zsi->size_perc = sprev + zsp->size_perc; - zsi->size_perc_prev = sprev; - - zsi->size = sprev_sz + zsp->size; - zsi->size_prev = sprev_sz; - } - - aprev += zsp->access_perc; - sprev += zsp->size_perc; - sprev_sz += zsp->size; - } -} - -/* - * Generate state table for indexes, so we don't have to do it inline from - * the hot IO path - */ -static void td_zone_gen_index(struct thread_data *td) -{ - int i; - - td->zone_state_index = malloc(DDIR_RWDIR_CNT * - sizeof(struct zone_split_index *)); - - for (i = 0; i < DDIR_RWDIR_CNT; i++) - __td_zone_gen_index(td, i); -} - static int parse_zoned_distribution(struct thread_data *td, const char *input, bool absolute) { @@ -1011,8 +1007,6 @@ static int parse_zoned_distribution(struct thread_data *td, const char *input, } if (parse_dryrun()) { - int i; - for (i = 0; i < DDIR_RWDIR_CNT; i++) { free(td->o.zone_split[i]); td->o.zone_split[i] = NULL; @@ -1022,9 +1016,7 @@ static int parse_zoned_distribution(struct thread_data *td, const char *input, return ret; } - if (!ret) - td_zone_gen_index(td); - else { + if (ret) { for (i = 0; i < DDIR_RWDIR_CNT; i++) td->o.zone_split_nr[i] = 0; } @@ -1127,9 +1119,9 @@ static int str_steadystate_cb(void *data, const char *str) if (parse_dryrun()) return 0; - td->o.ss_state |= __FIO_SS_PCT; + td->o.ss_state |= FIO_SS_PCT; td->o.ss_limit.u.f = val; - } else if (td->o.ss_state & __FIO_SS_IOPS) { + } else if (td->o.ss_state & FIO_SS_IOPS) { if (!str_to_float(nr, &val, 0)) { log_err("fio: steadystate IOPS threshold postfix parsing failed\n"); free(nr); @@ -1166,7 +1158,7 @@ static int str_steadystate_cb(void *data, const char *str) * is escaped with a '\', then that ':' is part of the filename and does not * indicate a new file. */ -static char *get_next_name(char **ptr) +char *get_next_str(char **ptr) { char *str = *ptr; char *p, *start; @@ -1208,14 +1200,14 @@ static char *get_next_name(char **ptr) } -static int get_max_name_idx(char *input) +int get_max_str_idx(char *input) { unsigned int cur_idx; char *str, *p; p = str = strdup(input); for (cur_idx = 0; ; cur_idx++) - if (get_next_name(&str) == NULL) + if (get_next_str(&str) == NULL) break; free(p); @@ -1235,9 +1227,9 @@ int set_name_idx(char *target, size_t tlen, char *input, int index, p = str = strdup(input); - index %= get_max_name_idx(input); + index %= get_max_str_idx(input); for (cur_idx = 0; cur_idx <= index; cur_idx++) - fname = get_next_name(&str); + fname = get_next_str(&str); if (client_sockaddr_str[0] && unique_filename) { len = snprintf(target, tlen, "%s/%s.", fname, @@ -1251,6 +1243,23 @@ int set_name_idx(char *target, size_t tlen, char *input, int index, return len; } +char* get_name_by_idx(char *input, int index) +{ + unsigned int cur_idx; + char *fname, *str, *p; + + p = str = strdup(input); + + index %= get_max_str_idx(input); + for (cur_idx = 0; cur_idx <= index; cur_idx++) + fname = get_next_str(&str); + + fname = strdup(fname); + free(p); + + return fname; +} + static int str_filename_cb(void *data, const char *input) { struct thread_data *td = cb_data_to_td(data); @@ -1267,7 +1276,7 @@ static int str_filename_cb(void *data, const char *input) if (!td->files_index) td->o.nr_files = 0; - while ((fname = get_next_name(&str)) != NULL) { + while ((fname = get_next_str(&str)) != NULL) { if (!strlen(fname)) break; add_file(td, fname, 0, 1); @@ -1288,7 +1297,7 @@ static int str_directory_cb(void *data, const char fio_unused *unused) return 0; p = str = strdup(td->o.directory); - while ((dirname = get_next_name(&str)) != NULL) { + while ((dirname = get_next_str(&str)) != NULL) { if (lstat(dirname, &sb) < 0) { ret = errno; @@ -1518,20 +1527,20 @@ static int str_ioengine_external_cb(void *data, const char *str) return 0; } -static int rw_verify(struct fio_option *o, void *data) +static int rw_verify(const struct fio_option *o, void *data) { struct thread_data *td = cb_data_to_td(data); - if (read_only && td_write(td)) { - log_err("fio: job <%s> has write bit set, but fio is in" - " read-only mode\n", td->o.name); + if (read_only && (td_write(td) || td_trim(td))) { + log_err("fio: job <%s> has write or trim bit set, but" + " fio is in read-only mode\n", td->o.name); return 1; } return 0; } -static int gtod_cpu_verify(struct fio_option *o, void *data) +static int gtod_cpu_verify(const struct fio_option *o, void *data) { #ifndef FIO_HAVE_CPU_AFFINITY struct thread_data *td = cb_data_to_td(data); @@ -1767,6 +1776,11 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .help = "Linux native asynchronous IO", }, #endif +#ifdef ARCH_HAVE_IOURING + { .ival = "io_uring", + .help = "Fast Linux native aio", + }, +#endif #ifdef CONFIG_POSIXAIO { .ival = "posixaio", .help = "POSIX asynchronous IO", @@ -1817,21 +1831,11 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .help = "GUASI IO engine", }, #endif -#ifdef FIO_HAVE_BINJECT - { .ival = "binject", - .help = "binject direct inject block engine", - }, -#endif #ifdef CONFIG_RDMA { .ival = "rdma", .help = "RDMA IO engine", }, #endif -#ifdef CONFIG_FUSION_AW - { .ival = "fusion-aw-sync", - .help = "Fusion-io atomic write engine", - }, -#endif #ifdef CONFIG_LINUX_EXT4_MOVE_EXTENT { .ival = "e4defrag", .help = "ext4 defrag engine", @@ -1857,10 +1861,21 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { #endif #ifdef CONFIG_PMEMBLK { .ival = "pmemblk", - .help = "NVML libpmemblk based IO engine", + .help = "PMDK libpmemblk based IO engine", }, #endif +#ifdef CONFIG_IME + { .ival = "ime_psync", + .help = "DDN's IME synchronous IO engine", + }, + { .ival = "ime_psyncv", + .help = "DDN's IME synchronous IO engine using iovecs", + }, + { .ival = "ime_aio", + .help = "DDN's IME asynchronous IO engine", + }, +#endif #ifdef CONFIG_LINUX_DEVDAX { .ival = "dev-dax", .help = "DAX Device based IO engine", @@ -1876,9 +1891,17 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { }, #ifdef CONFIG_LIBPMEM { .ival = "libpmem", - .help = "NVML libpmem based IO engine", + .help = "PMDK libpmem based IO engine", + }, +#endif +#ifdef CONFIG_HTTP + { .ival = "http", + .help = "HTTP (WebDAV/S3) IO engine", }, #endif + { .ival = "nbd", + .help = "Network Block Device (NBD) IO engine" + }, }, }, { @@ -2084,7 +2107,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .name = "bs", .lname = "Block size", .alias = "blocksize", - .type = FIO_OPT_INT, + .type = FIO_OPT_ULL, .off1 = offsetof(struct thread_options, bs[DDIR_READ]), .off2 = offsetof(struct thread_options, bs[DDIR_WRITE]), .off3 = offsetof(struct thread_options, bs[DDIR_TRIM]), @@ -2101,7 +2124,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .name = "ba", .lname = "Block size align", .alias = "blockalign", - .type = FIO_OPT_INT, + .type = FIO_OPT_ULL, .off1 = offsetof(struct thread_options, ba[DDIR_READ]), .off2 = offsetof(struct thread_options, ba[DDIR_WRITE]), .off3 = offsetof(struct thread_options, ba[DDIR_TRIM]), @@ -2135,7 +2158,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { { .name = "bssplit", .lname = "Block size split", - .type = FIO_OPT_STR, + .type = FIO_OPT_STR_ULL, .cb = str_bssplit_cb, .off1 = offsetof(struct thread_options, bssplit), .help = "Set a specific mix of block sizes", @@ -2190,14 +2213,6 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_IO, .group = FIO_OPT_G_RANDOM, }, - { - .name = "use_os_rand", - .lname = "Use OS random", - .type = FIO_OPT_DEPRECATED, - .off1 = offsetof(struct thread_options, dep_use_os_rand), - .category = FIO_OPT_C_IO, - .group = FIO_OPT_G_RANDOM, - }, { .name = "norandommap", .lname = "No randommap", @@ -2440,7 +2455,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .posval = { { .ival = "0", .oval = F_ADV_NONE, - .help = "Don't issue fadvise", + .help = "Don't issue fadvise/madvise", }, { .ival = "1", .oval = F_ADV_TYPE, @@ -2852,25 +2867,14 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { { .name = "verifysort", .lname = "Verify sort", - .type = FIO_OPT_BOOL, - .off1 = offsetof(struct thread_options, verifysort), - .help = "Sort written verify blocks for read back", - .def = "1", - .parent = "verify", - .hide = 1, + .type = FIO_OPT_SOFT_DEPRECATED, .category = FIO_OPT_C_IO, .group = FIO_OPT_G_VERIFY, }, { .name = "verifysort_nr", .lname = "Verify Sort Nr", - .type = FIO_OPT_INT, - .off1 = offsetof(struct thread_options, verifysort_nr), - .help = "Pre-load and sort verify blocks for a read workload", - .minval = 0, - .maxval = 131072, - .def = "1024", - .parent = "verify", + .type = FIO_OPT_SOFT_DEPRECATED, .category = FIO_OPT_C_IO, .group = FIO_OPT_G_VERIFY, }, @@ -3117,6 +3121,17 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_IO, .group = FIO_OPT_G_IOLOG, }, + { + .name = "read_iolog_chunked", + .lname = "Read I/O log in parts", + .type = FIO_OPT_BOOL, + .off1 = offsetof(struct thread_options, read_iolog_chunked), + .def = "0", + .parent = "read_iolog", + .help = "Parse IO pattern in chunks", + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_IOLOG, + }, { .name = "replay_no_stall", .lname = "Don't stall on replay", @@ -3162,6 +3177,59 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .group = FIO_OPT_G_IOLOG, .pow2 = 1, }, + { + .name = "replay_time_scale", + .lname = "Replay Time Scale", + .type = FIO_OPT_INT, + .off1 = offsetof(struct thread_options, replay_time_scale), + .def = "100", + .minval = 1, + .parent = "read_iolog", + .hide = 1, + .help = "Scale time for replay events", + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_IOLOG, + }, + { + .name = "replay_skip", + .lname = "Replay Skip", + .type = FIO_OPT_STR, + .cb = str_replay_skip_cb, + .off1 = offsetof(struct thread_options, replay_skip), + .parent = "read_iolog", + .help = "Skip certain IO types (read,write,trim,flush)", + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_IOLOG, + }, + { + .name = "merge_blktrace_file", + .lname = "Merged blktrace output filename", + .type = FIO_OPT_STR_STORE, + .off1 = offsetof(struct thread_options, merge_blktrace_file), + .help = "Merged blktrace output filename", + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_IOLOG, + }, + { + .name = "merge_blktrace_scalars", + .lname = "Percentage to scale each trace", + .type = FIO_OPT_FLOAT_LIST, + .off1 = offsetof(struct thread_options, merge_blktrace_scalars), + .maxlen = FIO_IO_U_LIST_MAX_LEN, + .help = "Percentage to scale each trace", + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_IOLOG, + }, + { + .name = "merge_blktrace_iters", + .lname = "Number of iterations to run per trace", + .type = FIO_OPT_FLOAT_LIST, + .off1 = offsetof(struct thread_options, merge_blktrace_iters), + .maxlen = FIO_IO_U_LIST_MAX_LEN, + .help = "Number of iterations to run per trace", + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_IOLOG, + }, { .name = "exec_prerun", .lname = "Pre-execute runnable", @@ -3198,6 +3266,30 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .help = "Your platform does not support IO scheduler switching", }, #endif + { + .name = "zonemode", + .lname = "Zone mode", + .help = "Mode for the zonesize, zonerange and zoneskip parameters", + .type = FIO_OPT_STR, + .off1 = offsetof(struct thread_options, zone_mode), + .def = "none", + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_ZONE, + .posval = { + { .ival = "none", + .oval = ZONE_MODE_NONE, + .help = "no zoning", + }, + { .ival = "strided", + .oval = ZONE_MODE_STRIDED, + .help = "strided mode - random I/O is restricted to a single zone", + }, + { .ival = "zbd", + .oval = ZONE_MODE_ZBD, + .help = "zoned block device mode - random I/O selects one of multiple zones randomly", + }, + }, + }, { .name = "zonesize", .lname = "Zone size", @@ -3231,6 +3323,52 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_IO, .group = FIO_OPT_G_ZONE, }, + { + .name = "read_beyond_wp", + .lname = "Allow reads beyond the zone write pointer", + .type = FIO_OPT_BOOL, + .off1 = offsetof(struct thread_options, read_beyond_wp), + .help = "Allow reads beyond the zone write pointer", + .def = "0", + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_INVALID, + }, + { + .name = "max_open_zones", + .lname = "Maximum number of open zones", + .type = FIO_OPT_INT, + .off1 = offsetof(struct thread_options, max_open_zones), + .maxval = FIO_MAX_OPEN_ZBD_ZONES, + .help = "Limit random writes to SMR drives to the specified" + " number of sequential zones", + .def = "0", + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_INVALID, + }, + { + .name = "zone_reset_threshold", + .lname = "Zone reset threshold", + .help = "Zoned block device reset threshold", + .type = FIO_OPT_FLOAT_LIST, + .maxlen = 1, + .off1 = offsetof(struct thread_options, zrt), + .minfp = 0, + .maxfp = 1, + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_ZONE, + }, + { + .name = "zone_reset_frequency", + .lname = "Zone reset frequency", + .help = "Zoned block device zone reset frequency in HZ", + .type = FIO_OPT_FLOAT_LIST, + .maxlen = 1, + .off1 = offsetof(struct thread_options, zrf), + .minfp = 0, + .maxfp = 1, + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_ZONE, + }, { .name = "lockmem", .lname = "Lock memory", @@ -3456,10 +3594,20 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_IO, .group = FIO_OPT_G_RATE, }, + { + .name = "rate_ignore_thinktime", + .lname = "Rate ignore thinktime", + .type = FIO_OPT_BOOL, + .off1 = offsetof(struct thread_options, rate_ign_think), + .help = "Rated IO ignores thinktime settings", + .parent = "rate", + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_RATE, + }, { .name = "max_latency", .lname = "Max Latency (usec)", - .type = FIO_OPT_INT, + .type = FIO_OPT_STR_VAL_TIME, .off1 = offsetof(struct thread_options, max_latency), .help = "Maximum tolerated IO latency (usec)", .is_time = 1, @@ -4393,7 +4541,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { { .name = "kb_base", .lname = "KB Base", - .type = FIO_OPT_INT, + .type = FIO_OPT_STR, .off1 = offsetof(struct thread_options, kb_base), .prio = 1, .def = "1024", @@ -4414,20 +4562,20 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { { .name = "unit_base", .lname = "Unit for quantities of data (Bits or Bytes)", - .type = FIO_OPT_INT, + .type = FIO_OPT_STR, .off1 = offsetof(struct thread_options, unit_base), .prio = 1, .posval = { { .ival = "0", - .oval = 0, + .oval = N2S_NONE, .help = "Auto-detect", }, { .ival = "8", - .oval = 8, + .oval = N2S_BYTEPERSEC, .help = "Normal (byte based)", }, { .ival = "1", - .oval = 1, + .oval = N2S_BITPERSEC, .help = "Bit based", }, }, @@ -4739,7 +4887,7 @@ static char *bc_calc(char *str) * substitution always occurs, even if VARNAME is empty or the corresponding * environment variable undefined. */ -static char *option_dup_subs(const char *opt) +char *fio_option_dup_subs(const char *opt) { char out[OPT_LEN_MAX+1]; char in[OPT_LEN_MAX+1]; @@ -4844,7 +4992,7 @@ static char **dup_and_sub_options(char **opts, int num_opts) int i; char **opts_copy = malloc(num_opts * sizeof(*opts)); for (i = 0; i < num_opts; i++) { - opts_copy[i] = option_dup_subs(opts[i]); + opts_copy[i] = fio_option_dup_subs(opts[i]); if (!opts_copy[i]) continue; opts_copy[i] = fio_keyword_replace(opts_copy[i]); @@ -4895,7 +5043,7 @@ int fio_options_parse(struct thread_data *td, char **opts, int num_opts) opts_copy = dup_and_sub_options(opts, num_opts); for (ret = 0, i = 0, unknown = 0; i < num_opts; i++) { - struct fio_option *o; + const struct fio_option *o; int newret = parse_option(opts_copy[i], opts[i], fio_options, &o, &td->o, &td->opt_list); @@ -4921,7 +5069,7 @@ int fio_options_parse(struct thread_data *td, char **opts, int num_opts) opts = opts_copy; } for (i = 0; i < num_opts; i++) { - struct fio_option *o = NULL; + const struct fio_option *o = NULL; int newret = 1; if (!opts_copy[i]) @@ -4952,9 +5100,9 @@ int fio_cmd_option_parse(struct thread_data *td, const char *opt, char *val) ret = parse_cmd_option(opt, val, fio_options, &td->o, &td->opt_list); if (!ret) { - struct fio_option *o; + const struct fio_option *o; - o = find_option(fio_options, opt); + o = find_option_c(fio_options, opt); if (o) fio_option_mark_set(&td->o, o); } @@ -5019,7 +5167,7 @@ unsigned int fio_get_kb_base(void *data) return kb_base; } -int add_option(struct fio_option *o) +int add_option(const struct fio_option *o) { struct fio_option *__o; int opt_index = 0; @@ -5108,8 +5256,7 @@ struct fio_option *fio_option_find(const char *name) return find_option(fio_options, name); } -static struct fio_option *find_next_opt(struct thread_options *o, - struct fio_option *from, +static struct fio_option *find_next_opt(struct fio_option *from, unsigned int off1) { struct fio_option *opt; @@ -5146,7 +5293,7 @@ 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) { + while ((opt = find_next_opt(next, off1)) != NULL) { if (opt_is_set(o, opt)) return true; @@ -5156,7 +5303,7 @@ bool __fio_option_is_set(struct thread_options *o, unsigned int off1) return false; } -void fio_option_mark_set(struct thread_options *o, struct fio_option *opt) +void fio_option_mark_set(struct thread_options *o, const struct fio_option *opt) { unsigned int opt_off, index, offset;