X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=options.c;h=5b97ec413aae0ba43d8f911ccfda8dc24397553f;hp=16b6636991d65290bd10f4befbf06c00904dc580;hb=23ed19b0e10749dca2389511f78d89db886c064a;hpb=04778baf2def8c1c5a3d7d60233c56d140831711 diff --git a/options.c b/options.c index 16b66369..5b97ec41 100644 --- a/options.c +++ b/options.c @@ -821,6 +821,18 @@ static int str_directory_cb(void *data, const char fio_unused *str) return 0; } +static int str_lockfile_cb(void *data, const char fio_unused *str) +{ + struct thread_data *td = data; + + if (td->files_index) { + log_err("fio: lockfile= option must precede filename=\n"); + return 1; + } + + return 0; +} + static int str_opendir_cb(void *data, const char fio_unused *str) { struct thread_data *td = data; @@ -834,11 +846,12 @@ static int str_opendir_cb(void *data, const char fio_unused *str) return add_dir_files(td, td->o.opendir); } -static int str_verify_pattern_cb(void *data, const char *input) +static int pattern_cb(char *pattern, unsigned int max_size, + const char *input, unsigned int *pattern_bytes) { - struct thread_data *td = data; long off; - int i = 0, j = 0, len, k, base = 10, pattern_length; + int i = 0, j = 0, len, k, base = 10; + uint32_t pattern_length; char *loc1, *loc2; loc1 = strstr(input, "0x"); @@ -848,7 +861,7 @@ static int str_verify_pattern_cb(void *data, const char *input) off = strtol(input, NULL, base); if (off != LONG_MAX || errno != ERANGE) { while (off) { - td->o.verify_pattern[i] = off & 0xff; + pattern[i] = off & 0xff; off >>= 8; i++; } @@ -862,13 +875,13 @@ static int str_verify_pattern_cb(void *data, const char *input) j = loc2 - input + 2; } else return 1; - if (len - j < MAX_PATTERN_SIZE * 2) { + if (len - j < max_size * 2) { while (k >= j) { off = converthexchartoint(input[k--]); if (k >= j) off += (converthexchartoint(input[k--]) * 16); - td->o.verify_pattern[i++] = (char) off; + pattern[i++] = (char) off; } } } @@ -878,19 +891,19 @@ static int str_verify_pattern_cb(void *data, const char *input) * the number of memcpy's we have to do when verifying the IO. */ pattern_length = i; - while (i > 1 && i * 2 <= MAX_PATTERN_SIZE) { - memcpy(&td->o.verify_pattern[i], &td->o.verify_pattern[0], 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_PATTERN_SIZE. + * max_size. */ - while (i > 1 && i < MAX_PATTERN_SIZE) { - unsigned int b = min(pattern_length, MAX_PATTERN_SIZE - i); + while (i > 1 && i < max_size) { + unsigned int b = min(pattern_length, max_size - i); - memcpy(&td->o.verify_pattern[i], &td->o.verify_pattern[0], b); + memcpy(&pattern[i], &pattern[0], b); i += b; } @@ -899,19 +912,45 @@ static int str_verify_pattern_cb(void *data, const char *input) * The code in verify_io_u_pattern assumes a single byte pattern * fills the whole verify pattern buffer. */ - memset(td->o.verify_pattern, td->o.verify_pattern[0], - MAX_PATTERN_SIZE); + memset(pattern, pattern[0], max_size); } - td->o.verify_pattern_bytes = i; + *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); + + if (!ret) { + td->o.refill_buffers = 0; + td->o.scramble_buffers = 0; + td->o.zero_buffers = 0; + } + + return ret; +} + +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); /* * VERIFY_META could already be set */ - if (td->o.verify == VERIFY_NONE) + if (!ret && td->o.verify == VERIFY_NONE) td->o.verify = VERIFY_PATTERN; - return 0; + return ret; } static int str_gtod_reduce_cb(void *data, int *il) @@ -1200,9 +1239,11 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .type = FIO_OPT_STR, .off1 = td_var_offset(file_lock_mode), .help = "Lock file when doing IO to it", + .prio = 1, .parent = "filename", .hide = 0, .def = "none", + .cb = str_lockfile_cb, .category = FIO_OPT_C_FILE, .group = FIO_OPT_G_FILENAME, .posval = { @@ -1346,6 +1387,11 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { { .ival = "windowsaio", .help = "Windows native asynchronous IO" }, +#endif +#ifdef CONFIG_RBD + { .ival = "rbd", + .help = "Rados Block Device asynchronous IO" + }, #endif { .ival = "mmap", .help = "Memory mapped IO" @@ -1629,7 +1675,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { { .name = "randseed", .lname = "The random generator seed", - .type = FIO_OPT_INT, + .type = FIO_OPT_STR_VAL, .off1 = td_var_offset(rand_seed), .help = "Set the random generator seed value", .parent = "rw", @@ -1737,6 +1783,13 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_IO, .group = FIO_OPT_G_RANDOM, }, + { + .name = "allrandrepeat", + .type = FIO_OPT_BOOL, + .off1 = td_var_offset(allrand_repeatable), + .help = "Use repeatable random numbers for everything", + .def = "0", + }, { .name = "nrfiles", .lname = "Number of files", @@ -1873,18 +1926,18 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { { .ival = "wait_before", .oval = SYNC_FILE_RANGE_WAIT_BEFORE, .help = "SYNC_FILE_RANGE_WAIT_BEFORE", - .or = 1, + .orval = 1, }, { .ival = "write", .oval = SYNC_FILE_RANGE_WRITE, .help = "SYNC_FILE_RANGE_WRITE", - .or = 1, + .orval = 1, }, { .ival = "wait_after", .oval = SYNC_FILE_RANGE_WAIT_AFTER, .help = "SYNC_FILE_RANGE_WAIT_AFTER", - .or = 1, + .orval = 1, }, }, .type = FIO_OPT_STR_MULTI, @@ -1965,6 +2018,7 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .lname = "Start delay", .type = FIO_OPT_STR_VAL_TIME, .off1 = td_var_offset(start_delay), + .off2 = td_var_offset(start_delay_high), .help = "Only start job when this period has passed", .def = "0", .category = FIO_OPT_C_GENERAL, @@ -1990,6 +2044,15 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_GENERAL, .group = FIO_OPT_G_RUNTIME, }, + { + .name = "verify_only", + .lname = "Verify only", + .type = FIO_OPT_STR_SET, + .off1 = td_var_offset(verify_only), + .help = "Verifies previously written data is still valid", + .category = FIO_OPT_C_GENERAL, + .group = FIO_OPT_G_RUNTIME, + }, { .name = "ramp_time", .lname = "Ramp time", @@ -2946,6 +3009,15 @@ struct fio_option fio_options[FIO_MAX_OPTS] = { .category = FIO_OPT_C_IO, .group = FIO_OPT_G_IO_BUF, }, + { + .name = "buffer_pattern", + .lname = "Buffer pattern", + .type = FIO_OPT_STR, + .cb = str_buffer_pattern_cb, + .help = "Fill pattern for IO buffers", + .category = FIO_OPT_C_IO, + .group = FIO_OPT_G_IO_BUF, + }, { .name = "buffer_compress_percentage", .lname = "Buffer compression percentage", @@ -3681,7 +3753,7 @@ void options_mem_dupe(void *data, struct fio_option *options) if (o->type != FIO_OPT_STR_STORE) continue; - ptr = td_var(data, o->off1); + ptr = td_var(data, o, o->off1); if (*ptr) *ptr = strdup(*ptr); } @@ -3727,7 +3799,13 @@ int add_option(struct fio_option *o) __o++; } + if (opt_index + 1 == FIO_MAX_OPTS) { + log_err("fio: FIO_MAX_OPTS is too small\n"); + return 1; + } + memcpy(&fio_options[opt_index], o, sizeof(*o)); + fio_options[opt_index + 1].name = NULL; return 0; }