[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 <jens.axboe@oracle.com>
diff --git a/HOWTO b/HOWTO
index 2616156..1e1f409 100644
--- a/HOWTO
+++ b/HOWTO
@@ -218,22 +218,20 @@
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 3c27ea5..a8ff5ac 100644
--- a/init.c
+++ b/init.c
@@ -142,16 +142,7 @@
.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 @@
.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 @@
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 f37878f..6e935f3 100644
--- a/parse.c
+++ b/parse.c
@@ -53,6 +53,8 @@
int len;
len = strlen(str);
+ if (!len)
+ return 1;
*val = strtoul(str, NULL, 10);
if (*val == ULONG_MAX && errno == ERANGE)
@@ -131,7 +133,8 @@
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 @@
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 @@
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 {
- *ilp2 = ul2;
+ 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 @@
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 @@
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 @@
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 563712e..9b34de9 100644
--- a/parse.h
+++ b/parse.h
@@ -23,6 +23,8 @@
enum fio_opt_type type;
unsigned int off1;
unsigned int off2;
+ unsigned int off3;
+ unsigned int off4;
unsigned int max_val;
void *cb;
};