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 <jens.axboe@oracle.com>
size if larger than the current file size. If this parameter
is not given and the file exists, the file size will be used.
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
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
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
.name = "bs",
.type = FIO_OPT_STR_VAL_INT,
.off1 = td_var_offset(bs[DDIR_READ]),
.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]),
.type = FIO_OPT_RANGE,
.off1 = td_var_offset(min_bs[DDIR_READ]),
.off2 = td_var_offset(max_bs[DDIR_READ]),
.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]),
if (td_read(td) || td_rw(td))
td->overwrite = 1;
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])
if (!td->min_bs[DDIR_READ])
td->min_bs[DDIR_READ]= td->bs[DDIR_READ];
if (!td->max_bs[DDIR_READ])
int len;
len = strlen(str);
int len;
len = strlen(str);
*val = strtoul(str, NULL, 10);
if (*val == ULONG_MAX && errno == ERANGE)
*val = strtoul(str, NULL, 10);
if (*val == ULONG_MAX && errno == ERANGE)
-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;
{
unsigned int il, *ilp1, *ilp2;
unsigned long long ull, *ullp;
ret = fn(data, &ull);
else {
if (o->type == FIO_OPT_STR_VAL_INT) {
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;
+ }
- 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;
+ }
ret = 1;
if (!check_range_bytes(p1, &ul1) && !check_range_bytes(p2, &ul2)) {
ret = 0;
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);
- *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;
+ 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);
if (fn)
ret = fn(data, &il);
else {
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);
+
if (fn)
ret = fn(data);
else {
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);
+
+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)
{
int parse_cmd_option(const char *opt, const char *val,
struct fio_option *options, void *data)
{
enum fio_opt_type type;
unsigned int off1;
unsigned int off2;
enum fio_opt_type type;
unsigned int off1;
unsigned int off2;
+ unsigned int off3;
+ unsigned int off4;
unsigned int max_val;
void *cb;
};
unsigned int max_val;
void *cb;
};