[PATCH] bs= and bsrange= takes both read and write sizes
authorJens Axboe <jens.axboe@oracle.com>
Mon, 6 Nov 2006 10:08:21 +0000 (11:08 +0100)
committerJens Axboe <jens.axboe@oracle.com>
Mon, 6 Nov 2006 10:08:21 +0000 (11:08 +0100)
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>
HOWTO
init.c
parse.c
parse.h

diff --git a/HOWTO b/HOWTO
index 2616156d1234017a1d08da368c3bb461c29fcf0a..1e1f4097f54218e8c9d70e9479aecc9bf62c635d 100644 (file)
--- 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 3c27ea55aa09107a9a62595aa658c86ce11871c5..a8ff5ac0dc9b22532f43b66f8125fa66f755e038 100644 (file)
--- 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 f37878f1cbc8d6a94f8d21aac91ea04a08deff5d..6e935f31069f3cf0076fb5806c8a595d82b6ff65 100644 (file)
--- 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 563712eede06dca557bfbdcbaae8ecbb73123dfe..9b34de9aad60b178a5257e78f7e96d2d158db015 100644 (file)
--- 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;
 };