Add possibility to make sequential IO "holed"
authorJens Axboe <jaxboe@fusionio.com>
Thu, 25 Aug 2011 07:09:37 +0000 (09:09 +0200)
committerJens Axboe <jaxboe@fusionio.com>
Thu, 25 Aug 2011 07:09:37 +0000 (09:09 +0200)
For sequential IO, it is now possible to add a number of bytes to
be skipped for every block read or written. Using:

bs=8k
rw=read:8k

will first read 0k->8k, then 16k->24k, and so on. This skips 8k
for every 'bs' sized block read. Similar for writes, doing

bs=4k
rw=write:4k

will write 0k->4k, then 8k->12k, etc. End result being that every
other block is written, in a sequential fashion.

Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
HOWTO
fio.1
fio.h
io_u.c
options.c

diff --git a/HOWTO b/HOWTO
index 72a29a96eb1f05f69561fe85086fd9c5aa6e5cbc..a1b2e8c0bf7a6f51bceb8016618acb32e7dae01e 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -319,8 +319,12 @@ rw=str             Type of io pattern. Accepted values are:
                a number of IO's to do before getting a new offset, this is
                one by appending a ':<nr>' to the end of the string given.
                For a random read, it would look like 'rw=randread:8' for
-               passing in an offset modifier with a value of 8. See the
-               'rw_sequencer' option.
+               passing in an offset modifier with a value of 8. If the
+               postfix is used with a sequential IO pattern, then the value
+               specified will be added to the generated offset for each IO.
+               For instance, using rw=write:4k will skip 4k for every
+               write. It turns sequential IO into sequential IO with holes.
+               See the 'rw_sequencer' option.
 
 rw_sequencer=str If an offset modifier is given by appending a number to
                the rw=<str> line, then this option controls how that
diff --git a/fio.1 b/fio.1
index 40940f3e74dd1da2e5de6c3b1129032e65a334d1..488896cea76b803c13e35e8e498a0b23611a8e33 100644 (file)
--- a/fio.1
+++ b/fio.1
@@ -181,7 +181,10 @@ may still be skewed a bit, since the speed may be different. It is possible to
 specify a number of IO's to do before getting a new offset, this is one by
 appending a `:\fI<nr>\fR to the end of the string given. For a random read, it
 would look like \fBrw=randread:8\fR for passing in an offset modifier with a
-value of 8. See the \fBrw_sequencer\fR option.
+value of 8. If the postfix is used with a sequential IO pattern, then the value
+specified will be added to the generated offset for each IO. For instance,
+using \fBrw=write:4k\fR will skip 4k for every write. It turns sequential IO
+into sequential IO with holes. See the \fBrw_sequencer\fR option.
 .RE
 .TP
 .BI rw_sequencer \fR=\fPstr
diff --git a/fio.h b/fio.h
index 6c57496668d8b99a521699467147c70f6e8d48af..9d2a61ccedb2883aa00414ce84b80864af9af0c4 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -254,6 +254,7 @@ struct thread_options {
        unsigned int rw_seq;
        unsigned int kb_base;
        unsigned int ddir_seq_nr;
+       unsigned long ddir_seq_add;
        unsigned int iodepth;
        unsigned int iodepth_low;
        unsigned int iodepth_batch;
diff --git a/io_u.c b/io_u.c
index 51da223d3e02ab194c45a77e6249870d9d0a62d4..6a53bdaab074fcf9660c6e25e08c19408bd0dca2 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -249,7 +249,12 @@ static int get_next_seq_block(struct thread_data *td, struct fio_file *f,
        assert(ddir_rw(ddir));
 
        if (f->last_pos < f->real_file_size) {
-               *b = (f->last_pos - f->file_offset) / td->o.min_bs[ddir];
+               unsigned long long pos = f->last_pos - f->file_offset;
+
+               if (pos)
+                       pos += td->o.ddir_seq_add;
+
+               *b = pos / td->o.min_bs[ddir];
                return 0;
        }
 
index 3d8a720469655d82520bfe6e70d83bf5a0fde914..6a87e98fda6134f52167667225e69bd5757b296d 100644 (file)
--- a/options.c
+++ b/options.c
@@ -203,11 +203,26 @@ static int str_rw_cb(void *data, const char *str)
        char *nr = get_opt_postfix(str);
 
        td->o.ddir_seq_nr = 1;
-       if (nr) {
+       td->o.ddir_seq_add = 0;
+
+       if (!nr)
+               return 0;
+
+       if (td_random(td))
                td->o.ddir_seq_nr = atoi(nr);
-               free(nr);
+       else {
+               long long val;
+
+               if (str_to_decimal(nr, &val, 1, td)) {
+                       log_err("fio: rw postfix parsing failed\n");
+                       free(nr);
+                       return 1;
+               }
+
+               td->o.ddir_seq_add = val;
        }
 
+       free(nr);
        return 0;
 }