io_u: ensure that we align new start offset properly for time_based
authorJens Axboe <axboe@fb.com>
Thu, 14 Jan 2016 17:31:38 +0000 (10:31 -0700)
committerJens Axboe <axboe@fb.com>
Thu, 14 Jan 2016 17:31:38 +0000 (10:31 -0700)
If io_size isn't a multiple of the block size, weird things can
happen, which usually means that fio will exit with an unaligned
IO error:

fio: io_u error on file /dev/nvme0n1: Invalid argument: write offset=125830, buflen=1048576

where offset=125830 really should have been aligned to the block
size. Ensure that we do that.

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

diff --git a/io_u.c b/io_u.c
index 9628d5e32c791e1a847013be81cad3488687a024..8d3491281ddebd665b9cc294b87b324e7bd1d4b7 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -285,8 +285,15 @@ static int get_next_seq_offset(struct thread_data *td, struct fio_file *f,
        assert(ddir_rw(ddir));
 
        if (f->last_pos[ddir] >= f->io_size + get_start_offset(td, f) &&
        assert(ddir_rw(ddir));
 
        if (f->last_pos[ddir] >= f->io_size + get_start_offset(td, f) &&
-           o->time_based)
-               f->last_pos[ddir] = f->last_pos[ddir] - f->io_size;
+           o->time_based) {
+               struct thread_options *o = &td->o;
+               uint64_t io_size = f->io_size + (f->io_size % o->min_bs[ddir]);
+
+               if (io_size > f->last_pos[ddir])
+                       f->last_pos[ddir] = 0;
+               else
+                       f->last_pos[ddir] = f->last_pos[ddir] - io_size;
+       }
 
        if (f->last_pos[ddir] < f->real_file_size) {
                uint64_t pos;
 
        if (f->last_pos[ddir] < f->real_file_size) {
                uint64_t pos;