Fix bug with rw sequence offset and io_limit
authorJens Axboe <axboe@fb.com>
Sun, 28 Sep 2014 22:18:43 +0000 (16:18 -0600)
committerJens Axboe <axboe@fb.com>
Sun, 28 Sep 2014 22:18:43 +0000 (16:18 -0600)
If you do:

dd if=/dev/zero of=/dev/shm/1M bs=1M count=1
fio --bs=4k --rw=write:4k --filename=/dev/shm/1M --name=go --io_limit=2M

then fio will exit prematurely after having done 128 4KB ios,
so only 512KB are read. This is because after 128 ios, we have
reache the end of the file. Handle this case and wrap around
properly.

Signed-off-by: Jens Axboe <axboe@fb.com>
io_u.c

diff --git a/io_u.c b/io_u.c
index 8546899c03e79184fdbe7c1ab58282fa9b5713d7..583f1e39b2dd25a70c770b78c5f5519eda978925 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -271,20 +271,32 @@ static int get_next_rand_block(struct thread_data *td, struct fio_file *f,
 static int get_next_seq_offset(struct thread_data *td, struct fio_file *f,
                               enum fio_ddir ddir, uint64_t *offset)
 {
+       struct thread_options *o = &td->o;
+
        assert(ddir_rw(ddir));
 
-       if (f->last_pos >= f->io_size + get_start_offset(td, f) && td->o.time_based)
+       if (f->last_pos >= f->io_size + get_start_offset(td, f) &&
+           o->time_based)
                f->last_pos = f->last_pos - f->io_size;
 
        if (f->last_pos < f->real_file_size) {
                uint64_t pos;
 
-               if (f->last_pos == f->file_offset && td->o.ddir_seq_add < 0)
+               if (f->last_pos == f->file_offset && o->ddir_seq_add < 0)
                        f->last_pos = f->real_file_size;
 
                pos = f->last_pos - f->file_offset;
-               if (pos)
-                       pos += td->o.ddir_seq_add;
+               if (pos && o->ddir_seq_add) {
+                       pos += o->ddir_seq_add;
+
+                       /*
+                        * If we reach beyond the end of the file
+                        * with holed IO, wrap around to the
+                        * beginning again.
+                        */
+                       if (pos >= f->real_file_size)
+                               pos = f->file_offset;
+               }
 
                *offset = pos;
                return 0;