X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=options.c;h=445f3d453e88baa1c9a9c4737b16b34fd1aaef38;hp=a8fdde448bdaa4ded1d022a28a0d517d19217ae5;hb=517c9c729416db413826a034a3cffd7463e4be9c;hpb=ae8e559e8a442f72cfe2751e93471aed75f5c74e diff --git a/options.c b/options.c index a8fdde44..445f3d45 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,14 +52,15 @@ static int bs_cmp(const void *p1, const void *p2) struct split { unsigned int nr; - unsigned int val1[100]; - unsigned int val2[100]; + unsigned int 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) + char *str, bool absolute, unsigned int max_splits) { - unsigned int i, perc; + unsigned long long perc; + unsigned int i; long long val; char *fname; @@ -80,31 +77,46 @@ static int split_parse_ddir(struct thread_options *o, struct split *split, if (perc_str) { *perc_str = '\0'; perc_str++; - perc = atoi(perc_str); - if (perc > 100) - perc = 100; - else if (!perc) + if (absolute) { + if (str_to_decimal(perc_str, &val, 1, o, 0, 0)) { + log_err("fio: split conversion failed\n"); + return 1; + } + perc = val; + } else { + perc = atoi(perc_str); + if (perc > 100) + perc = 100; + else if (!perc) + perc = -1U; + } + } else { + if (absolute) + perc = 0; + else perc = -1U; - } else - perc = -1U; + } if (str_to_decimal(fname, &val, 1, o, 0, 0)) { - log_err("fio: bssplit conversion failed\n"); + log_err("fio: split conversion failed\n"); return 1; } split->val1[i] = val; split->val2[i] = perc; i++; - if (i == 100) + if (i == max_splits) { + log_err("fio: hit max of %d split entries\n", i); break; + } } split->nr = i; return 0; } -static int bssplit_ddir(struct thread_options *o, enum fio_ddir ddir, char *str) +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; @@ -112,7 +124,7 @@ static int bssplit_ddir(struct thread_options *o, enum fio_ddir ddir, char *str) memset(&split, 0, sizeof(split)); - if (split_parse_ddir(o, &split, ddir, str)) + if (split_parse_ddir(o, &split, str, data, BSSPLIT_MAX)) return 1; if (!split.nr) return 0; @@ -176,9 +188,10 @@ static int bssplit_ddir(struct thread_options *o, enum fio_ddir ddir, char *str) return 0; } -typedef int (split_parse_fn)(struct thread_options *, enum fio_ddir, char *); +typedef int (split_parse_fn)(struct thread_options *, enum fio_ddir, char *, bool); -static int str_split_parse(struct thread_data *td, char *str, split_parse_fn *fn) +static int str_split_parse(struct thread_data *td, char *str, + split_parse_fn *fn, bool data) { char *odir, *ddir; int ret = 0; @@ -187,37 +200,37 @@ static int str_split_parse(struct thread_data *td, char *str, split_parse_fn *fn if (odir) { ddir = strchr(odir + 1, ','); if (ddir) { - ret = fn(&td->o, DDIR_TRIM, ddir + 1); + ret = fn(&td->o, DDIR_TRIM, ddir + 1, data); if (!ret) *ddir = '\0'; } else { char *op; op = strdup(odir + 1); - ret = fn(&td->o, DDIR_TRIM, op); + ret = fn(&td->o, DDIR_TRIM, op, data); free(op); } if (!ret) - ret = fn(&td->o, DDIR_WRITE, odir + 1); + ret = fn(&td->o, DDIR_WRITE, odir + 1, data); if (!ret) { *odir = '\0'; - ret = fn(&td->o, DDIR_READ, str); + ret = fn(&td->o, DDIR_READ, str, data); } } else { char *op; op = strdup(str); - ret = fn(&td->o, DDIR_WRITE, op); + ret = fn(&td->o, DDIR_WRITE, op, data); free(op); if (!ret) { op = strdup(str); - ret = fn(&td->o, DDIR_TRIM, op); + ret = fn(&td->o, DDIR_TRIM, op, data); free(op); } if (!ret) - ret = fn(&td->o, DDIR_READ, str); + ret = fn(&td->o, DDIR_READ, str, data); } return ret; @@ -234,7 +247,7 @@ static int str_bssplit_cb(void *data, const char *input) strip_blank_front(&str); strip_blank_end(str); - ret = str_split_parse(td, str, bssplit_ddir); + ret = str_split_parse(td, str, bssplit_ddir, false); if (parse_dryrun()) { int i; @@ -328,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); @@ -823,23 +873,15 @@ static int str_sfr_cb(void *data, const char *str) } #endif -static int zone_cmp(const void *p1, const void *p2) -{ - const struct zone_split *zsp1 = p1; - const struct zone_split *zsp2 = p2; - - return (int) zsp2->access_perc - (int) zsp1->access_perc; -} - static int zone_split_ddir(struct thread_options *o, enum fio_ddir ddir, - char *str) + char *str, bool absolute) { unsigned int i, perc, perc_missing, sperc, sperc_missing; struct split split; memset(&split, 0, sizeof(split)); - if (split_parse_ddir(o, &split, ddir, str)) + if (split_parse_ddir(o, &split, str, absolute, ZONESPLIT_MAX)) return 1; if (!split.nr) return 0; @@ -848,7 +890,10 @@ static int zone_split_ddir(struct thread_options *o, enum fio_ddir ddir, o->zone_split_nr[ddir] = split.nr; for (i = 0; i < split.nr; i++) { o->zone_split[ddir][i].access_perc = split.val1[i]; - o->zone_split[ddir][i].size_perc = split.val2[i]; + if (absolute) + o->zone_split[ddir][i].size = split.val2[i]; + else + o->zone_split[ddir][i].size_perc = split.val2[i]; } /* @@ -864,11 +909,12 @@ static int zone_split_ddir(struct thread_options *o, enum fio_ddir ddir, else perc += zsp->access_perc; - if (zsp->size_perc == (uint8_t) -1U) - sperc_missing++; - else - sperc += zsp->size_perc; - + if (!absolute) { + if (zsp->size_perc == (uint8_t) -1U) + sperc_missing++; + else + sperc += zsp->size_perc; + } } if (perc > 100 || sperc > 100) { @@ -910,20 +956,17 @@ static int zone_split_ddir(struct thread_options *o, enum fio_ddir ddir, } } - /* - * now sort based on percentages, for ease of lookup - */ - qsort(o->zone_split[ddir], o->zone_split_nr[ddir], sizeof(struct zone_split), zone_cmp); 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 = aprev = 0; + 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]; @@ -932,10 +975,14 @@ static void __td_zone_gen_index(struct thread_data *td, enum fio_ddir ddir) 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; } } @@ -954,8 +1001,10 @@ static void td_zone_gen_index(struct thread_data *td) __td_zone_gen_index(td, i); } -static int parse_zoned_distribution(struct thread_data *td, const char *input) +static int parse_zoned_distribution(struct thread_data *td, const char *input, + bool absolute) { + const char *pre = absolute ? "zoned_abs:" : "zoned:"; char *str, *p; int i, ret = 0; @@ -965,14 +1014,14 @@ static int parse_zoned_distribution(struct thread_data *td, const char *input) strip_blank_end(str); /* We expect it to start like that, bail if not */ - if (strncmp(str, "zoned:", 6)) { + if (strncmp(str, pre, strlen(pre))) { log_err("fio: mismatch in zoned input <%s>\n", str); free(p); return 1; } - str += strlen("zoned:"); + str += strlen(pre); - ret = str_split_parse(td, str, zone_split_ddir); + ret = str_split_parse(td, str, zone_split_ddir, absolute); free(p); @@ -984,8 +1033,15 @@ static int parse_zoned_distribution(struct thread_data *td, const char *input) for (j = 0; j < td->o.zone_split_nr[i]; j++) { struct zone_split *zsp = &td->o.zone_split[i][j]; - dprint(FD_PARSE, "\t%d: %u/%u\n", j, zsp->access_perc, - zsp->size_perc); + if (absolute) { + dprint(FD_PARSE, "\t%d: %u/%llu\n", j, + zsp->access_perc, + (unsigned long long) zsp->size); + } else { + dprint(FD_PARSE, "\t%d: %u/%u\n", j, + zsp->access_perc, + zsp->size_perc); + } } } @@ -1024,7 +1080,9 @@ static int str_random_distribution_cb(void *data, const char *str) else if (td->o.random_distribution == FIO_RAND_DIST_GAUSS) val = 0.0; else if (td->o.random_distribution == FIO_RAND_DIST_ZONED) - return parse_zoned_distribution(td, str); + return parse_zoned_distribution(td, str, false); + else if (td->o.random_distribution == FIO_RAND_DIST_ZONED_ABS) + return parse_zoned_distribution(td, str, true); else return 0; @@ -1104,9 +1162,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); @@ -1381,7 +1439,7 @@ static int str_gtod_reduce_cb(void *data, int *il) td->o.disable_bw = !!val; td->o.clat_percentiles = !val; if (val) - td->tv_cache_mask = 63; + td->ts_cache_mask = 63; return 0; } @@ -1410,6 +1468,8 @@ static int str_size_cb(void *data, unsigned long long *__val) if (parse_is_percent(v)) { td->o.size = 0; td->o.size_percent = -1ULL - v; + dprint(FD_PARSE, "SET size_percent %d\n", + td->o.size_percent); } else td->o.size = v; @@ -1460,7 +1520,40 @@ static int str_write_hist_log_cb(void *data, const char *str) return 0; } -static int rw_verify(struct fio_option *o, void *data) +/* + * str is supposed to be a substring of the strdup'd original string, + * and is valid only if it's a regular file path. + * This function keeps the pointer to the path as needed later. + * + * "external:/path/to/so\0" <- original pointer updated with strdup'd + * "external\0" <- above pointer after parsed, i.e. ->ioengine + * "/path/to/so\0" <- str argument, i.e. ->ioengine_so_path + */ +static int str_ioengine_external_cb(void *data, const char *str) +{ + struct thread_data *td = cb_data_to_td(data); + struct stat sb; + char *p; + + if (!str) { + log_err("fio: null external ioengine path\n"); + return 1; + } + + p = (char *)str; /* str is mutable */ + strip_blank_front(&p); + strip_blank_end(p); + + if (stat(p, &sb) || !S_ISREG(sb.st_mode)) { + log_err("fio: invalid external ioengine path \"%s\"\n", p); + return 1; + } + + td->o.ioengine_so_path = p; + return 0; +} + +static int rw_verify(const struct fio_option *o, void *data) { struct thread_data *td = cb_data_to_td(data); @@ -1473,7 +1566,7 @@ static int rw_verify(struct fio_option *o, void *data) 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); @@ -1759,11 +1852,6 @@ 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", @@ -1799,7 +1887,7 @@ 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 @@ -1808,9 +1896,19 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .help = "DAX Device based IO engine", }, #endif + { + .ival = "filecreate", + .help = "File creation engine", + }, { .ival = "external", .help = "Load external engine (append name)", + .cb = str_ioengine_external_cb, + }, +#ifdef CONFIG_LIBPMEM + { .ival = "libpmem", + .help = "PMDK libpmem based IO engine", }, +#endif }, }, { @@ -1879,6 +1977,17 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_IO, .group = FIO_OPT_G_IO_BASIC, }, + { + .name = "serialize_overlap", + .lname = "Serialize overlap", + .off1 = offsetof(struct thread_options, serialize_overlap), + .type = FIO_OPT_BOOL, + .help = "Wait for in-flight IOs that collide to complete", + .parent = "iodepth", + .def = "0", + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_IO_BASIC, + }, { .name = "io_submit_mode", .lname = "IO submit mode", @@ -1967,6 +2076,17 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_IO, .group = FIO_OPT_G_INVALID, }, + { + .name = "offset_align", + .lname = "IO offset alignment", + .type = FIO_OPT_INT, + .off1 = offsetof(struct thread_options, start_offset_align), + .help = "Start IO from this offset alignment", + .def = "0", + .interval = 512, + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_INVALID, + }, { .name = "offset_increment", .lname = "IO offset increment", @@ -2186,7 +2306,10 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .oval = FIO_RAND_DIST_ZONED, .help = "Zoned random distribution", }, - + { .ival = "zoned_abs", + .oval = FIO_RAND_DIST_ZONED_ABS, + .help = "Zoned absolute random distribution", + }, }, .category = FIO_OPT_C_IO, .group = FIO_OPT_G_RANDOM, @@ -2267,9 +2390,13 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .oval = FIO_FSERVICE_PARETO, .help = "Pareto randomized", }, + { .ival = "normal", + .oval = FIO_FSERVICE_GAUSS, + .help = "Normal (Gaussian) randomized", + }, { .ival = "gauss", .oval = FIO_FSERVICE_GAUSS, - .help = "Normal (Gaussian) distribution", + .help = "Alias for normal", }, { .ival = "roundrobin", .oval = FIO_FSERVICE_RR, @@ -2283,14 +2410,14 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .parent = "nrfiles", .hide = 1, }, -#ifdef CONFIG_POSIX_FALLOCATE +#ifdef FIO_HAVE_ANY_FALLOCATE { .name = "fallocate", .lname = "Fallocate", .type = FIO_OPT_STR, .off1 = offsetof(struct thread_options, fallocate_mode), .help = "Whether pre-allocation is performed when laying out files", - .def = "posix", + .def = "native", .category = FIO_OPT_C_FILE, .group = FIO_OPT_G_INVALID, .posval = { @@ -2298,10 +2425,16 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .oval = FIO_FALLOCATE_NONE, .help = "Do not pre-allocate space", }, + { .ival = "native", + .oval = FIO_FALLOCATE_NATIVE, + .help = "Use native pre-allocation if possible", + }, +#ifdef CONFIG_POSIX_FALLOCATE { .ival = "posix", .oval = FIO_FALLOCATE_POSIX, .help = "Use posix_fallocate()", }, +#endif #ifdef CONFIG_LINUX_FALLOCATE { .ival = "keep", .oval = FIO_FALLOCATE_KEEP_SIZE, @@ -2313,20 +2446,22 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .oval = FIO_FALLOCATE_NONE, .help = "Alias for 'none'", }, +#ifdef CONFIG_POSIX_FALLOCATE { .ival = "1", .oval = FIO_FALLOCATE_POSIX, .help = "Alias for 'posix'", }, +#endif }, }, -#else /* CONFIG_POSIX_FALLOCATE */ +#else /* FIO_HAVE_ANY_FALLOCATE */ { .name = "fallocate", .lname = "Fallocate", .type = FIO_OPT_UNSUPPORTED, .help = "Your platform does not support fallocate", }, -#endif /* CONFIG_POSIX_FALLOCATE */ +#endif /* FIO_HAVE_ANY_FALLOCATE */ { .name = "fadvise_hint", .lname = "Fadvise hint", @@ -2335,7 +2470,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, @@ -2747,25 +2882,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, }, @@ -3057,6 +3181,30 @@ 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 = "exec_prerun", .lname = "Pre-execute runnable", @@ -3178,8 +3326,8 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .type = FIO_OPT_INT, .off1 = offsetof(struct thread_options, nice), .help = "Set job CPU nice value", - .minval = -19, - .maxval = 20, + .minval = -20, + .maxval = 19, .def = "0", .interval = 1, .category = FIO_OPT_C_GENERAL, @@ -3351,10 +3499,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", - .type = FIO_OPT_INT, + .lname = "Max Latency (usec)", + .type = FIO_OPT_STR_VAL_TIME, .off1 = offsetof(struct thread_options, max_latency), .help = "Maximum tolerated IO latency (usec)", .is_time = 1, @@ -3993,6 +4151,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .parent = "buffer_compress_percentage", .hide = 1, .help = "Size of compressible region in buffer", + .def = "512", .interval = 256, .category = FIO_OPT_C_IO, .group = FIO_OPT_G_IO_BUF, @@ -4017,6 +4176,18 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .off1 = offsetof(struct thread_options, clat_percentiles), .help = "Enable the reporting of completion latency percentiles", .def = "1", + .inverse = "lat_percentiles", + .category = FIO_OPT_C_STAT, + .group = FIO_OPT_G_INVALID, + }, + { + .name = "lat_percentiles", + .lname = "IO latency percentiles", + .type = FIO_OPT_BOOL, + .off1 = offsetof(struct thread_options, lat_percentiles), + .help = "Enable the reporting of IO latency percentiles", + .def = "0", + .inverse = "clat_percentiles", .category = FIO_OPT_C_STAT, .group = FIO_OPT_G_INVALID, }, @@ -4035,6 +4206,19 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_STAT, .group = FIO_OPT_G_INVALID, }, + { + .name = "significant_figures", + .lname = "Significant figures", + .type = FIO_OPT_INT, + .off1 = offsetof(struct thread_options, sig_figs), + .maxval = 10, + .minval = 1, + .help = "Significant figures for output-format set to normal", + .def = "4", + .interval = 1, + .category = FIO_OPT_C_STAT, + .group = FIO_OPT_G_INVALID, + }, #ifdef FIO_HAVE_DISK_UTIL { @@ -4288,15 +4472,15 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .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", }, }, @@ -4364,17 +4548,6 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_IO, .group = FIO_OPT_G_IO_FLOW, }, - { - .name = "skip_bad", - .lname = "Skip operations against bad blocks", - .type = FIO_OPT_BOOL, - .off1 = offsetof(struct thread_options, skip_bad), - .help = "Skip operations against known bad blocks.", - .hide = 1, - .def = "0", - .category = FIO_OPT_C_IO, - .group = FIO_OPT_G_MTD, - }, { .name = "steadystate", .lname = "Steady state threshold", @@ -4775,7 +4948,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); @@ -4801,7 +4974,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]) @@ -4832,9 +5005,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); } @@ -4899,7 +5072,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; @@ -4988,8 +5161,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; @@ -5026,7 +5198,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; @@ -5036,7 +5208,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;