From f90eff5a414f6e8c16a51c3a7d9b5e077ab49aac Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 6 Nov 2006 11:08:21 +0100 Subject: [PATCH] [PATCH] bs= and bsrange= takes both read and write sizes Get rid of read_bs/write_bs and read_bsrange/write_bsrange. It was ugly and too complicated. Instead support giving both values in a single bs= or bsrange= seperated by a comma. Example: bs=1k,4k will use 1k blocks for reads, 4k blocks for writes. bs=32k will use 32k blocks for both reads and writes. Similar for bsrange= Signed-off-by: Jens Axboe --- HOWTO | 22 +++++++-------- init.c | 27 ++---------------- parse.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++-------- parse.h | 2 ++ 4 files changed, 91 insertions(+), 48 deletions(-) diff --git a/HOWTO b/HOWTO index 2616156d..1e1f4097 100644 --- a/HOWTO +++ b/HOWTO @@ -218,22 +218,20 @@ size=siint The total size of file io for this job. This may describe size if larger than the current file size. If this parameter is not given and the file exists, the file size will be used. -bs=siint The block size used for the io units. Defaults to 4k. - -read_bs=siint -write_bs=siint If the workload is a mixed read-write workload, you can use - these options to set separate block sizes. +bs=siint The block size used for the io units. Defaults to 4k. Values + can be given for both read and writes. If a single siint is + given, it will apply to both. If a second siint is specified + after a comma, it will apply to writes only. In other words, + the format is either bs=read_and_write or bs=read,write. + bs=4k,8k will thus use 4k blocks for reads, and 8k blocks + for writes. bsrange=irange Instead of giving a single block size, specify a range and fio will mix the issued io block sizes. The issued io unit will always be a multiple of the minimum value - given (also see bs_unaligned). - -read_bsrange=irange -write_bsrange=irange - If the workload is a mixed read-write workload, you can use - one of these options to set separate block size ranges for - reads and writes. + given (also see bs_unaligned). Applies to both reads and + writes, however a second range can be given after a comma. + See bs=. bs_unaligned If this option is given, any byte size value within bsrange may be used as a block range. This typically wont work with diff --git a/init.c b/init.c index 3c27ea55..a8ff5ac0 100644 --- a/init.c +++ b/init.c @@ -142,16 +142,7 @@ static struct fio_option options[] = { .name = "bs", .type = FIO_OPT_STR_VAL_INT, .off1 = td_var_offset(bs[DDIR_READ]), - }, - { - .name = "read_bs", - .type = FIO_OPT_STR_VAL_INT, - .off1 = td_var_offset(bs[DDIR_READ]), - }, - { - .name = "write_bs", - .type = FIO_OPT_STR_VAL_INT, - .off1 = td_var_offset(bs[DDIR_WRITE]), + .off2 = td_var_offset(bs[DDIR_WRITE]), }, { .name = "offset", @@ -178,18 +169,8 @@ static struct fio_option options[] = { .type = FIO_OPT_RANGE, .off1 = td_var_offset(min_bs[DDIR_READ]), .off2 = td_var_offset(max_bs[DDIR_READ]), - }, - { - .name = "read_bsrange", - .type = FIO_OPT_RANGE, - .off1 = td_var_offset(min_bs[DDIR_READ]), - .off2 = td_var_offset(max_bs[DDIR_READ]), - }, - { - .name = "write_bsrange", - .type = FIO_OPT_RANGE, - .off1 = td_var_offset(min_bs[DDIR_WRITE]), - .off2 = td_var_offset(max_bs[DDIR_WRITE]), + .off3 = td_var_offset(min_bs[DDIR_WRITE]), + .off4 = td_var_offset(max_bs[DDIR_WRITE]), }, { .name = "nrfiles", @@ -508,8 +489,6 @@ static void fixup_options(struct thread_data *td) if (td_read(td) || td_rw(td)) td->overwrite = 1; - if (td->bs[DDIR_READ] != DEF_BS) - td->bs[DDIR_WRITE] = td->bs[DDIR_READ]; if (!td->min_bs[DDIR_READ]) td->min_bs[DDIR_READ]= td->bs[DDIR_READ]; if (!td->max_bs[DDIR_READ]) diff --git a/parse.c b/parse.c index f37878f1..6e935f31 100644 --- a/parse.c +++ b/parse.c @@ -53,6 +53,8 @@ static int str_to_decimal(const char *str, unsigned long long *val, int kilo) int len; len = strlen(str); + if (!len) + return 1; *val = strtoul(str, NULL, 10); if (*val == ULONG_MAX && errno == ERANGE) @@ -131,7 +133,8 @@ static struct fio_option *find_option(struct fio_option *options, return NULL; } -static int handle_option(struct fio_option *o, const char *ptr, void *data) +static int __handle_option(struct fio_option *o, const char *ptr, void *data, + int first) { unsigned int il, *ilp1, *ilp2; unsigned long long ull, *ullp; @@ -167,11 +170,29 @@ static int handle_option(struct fio_option *o, const char *ptr, void *data) ret = fn(data, &ull); else { if (o->type == FIO_OPT_STR_VAL_INT) { - ilp1 = td_var(data, o->off1); - *ilp1 = ull; + if (first) { + ilp1 = td_var(data, o->off1); + *ilp1 = ull; + if (o->off2) { + ilp1 = td_var(data, o->off2); + *ilp1 = ull; + } + } else if (o->off2) { + ilp1 = td_var(data, o->off2); + *ilp1 = ull; + } } else { - ullp = td_var(data, o->off1); - *ullp = ull; + if (first) { + ullp = td_var(data, o->off1); + *ullp = ull; + if (o->off2) { + ullp = td_var(data, o->off2); + *ullp = ull; + } + } else if (o->off2) { + ullp = td_var(data, o->off2); + *ullp = ull; + } } } break; @@ -199,14 +220,29 @@ static int handle_option(struct fio_option *o, const char *ptr, void *data) ret = 1; if (!check_range_bytes(p1, &ul1) && !check_range_bytes(p2, &ul2)) { ret = 0; - ilp1 = td_var(data, o->off1); - ilp2 = td_var(data, o->off2); if (ul1 > ul2) { - *ilp1 = ul2; - *ilp2 = ul1; - } else { + unsigned long foo = ul1; + + ul1 = ul2; + ul2 = foo; + } + + if (first) { + ilp1 = td_var(data, o->off1); + ilp2 = td_var(data, o->off2); + *ilp1 = ul1; *ilp2 = ul2; + if (o->off3 && o->off4) { + ilp1 = td_var(data, o->off3); + ilp2 = td_var(data, o->off4); + *ilp1 = ul1; + *ilp2 = ul2; + } + } else if (o->off3 && o->off4) { + ilp1 = td_var(data, o->off3); + ilp2 = td_var(data, o->off4); *ilp1 = ul1; + *ilp2 = ul2; } } @@ -225,7 +261,11 @@ static int handle_option(struct fio_option *o, const char *ptr, void *data) if (fn) ret = fn(data, &il); else { - ilp1 = td_var(data, o->off1); + if (first || !o->off2) + ilp1 = td_var(data, o->off1); + else + ilp1 = td_var(data, o->off2); + *ilp1 = il; } break; @@ -236,7 +276,11 @@ static int handle_option(struct fio_option *o, const char *ptr, void *data) if (fn) ret = fn(data); else { - ilp1 = td_var(data, o->off1); + if (first || !o->off2) + ilp1 = td_var(data, o->off1); + else + ilp1 = td_var(data, o->off2); + *ilp1 = 1; } break; @@ -249,6 +293,26 @@ static int handle_option(struct fio_option *o, const char *ptr, void *data) return ret; } +static int handle_option(struct fio_option *o, const char *ptr, void *data) +{ + const char *ptr2; + int ret; + + ret = __handle_option(o, ptr, data, 1); + if (ret) + return ret; + + /* + * See if we have a second set of parameters, hidden after a comma + */ + ptr2 = strchr(ptr, ','); + if (!ptr2) + return 0; + + ptr2++; + return __handle_option(o, ptr2, data, 0); +} + int parse_cmd_option(const char *opt, const char *val, struct fio_option *options, void *data) { diff --git a/parse.h b/parse.h index 563712ee..9b34de9a 100644 --- a/parse.h +++ b/parse.h @@ -23,6 +23,8 @@ struct fio_option { enum fio_opt_type type; unsigned int off1; unsigned int off2; + unsigned int off3; + unsigned int off4; unsigned int max_val; void *cb; }; -- 2.25.1