Fix short IO handling for verifies as well
[fio.git] / io_u.c
diff --git a/io_u.c b/io_u.c
index 9c8ff2638df5ed3ea57bb943f04672a7b8f63077..17e188ad022ee05f3bb6dceedb153a24027b2fb3 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -100,7 +100,7 @@ static int get_next_free_block(struct thread_data *td, struct fio_file *f,
 static int get_next_rand_offset(struct thread_data *td, struct fio_file *f,
                                int ddir, unsigned long long *b)
 {
-       unsigned long long max_blocks = f->file_size / td->o.min_bs[ddir];
+       unsigned long long max_blocks = f->io_size / td->o.min_bs[ddir];
        unsigned long long r, rb;
        int loops = 5;
 
@@ -142,8 +142,12 @@ static int get_next_offset(struct thread_data *td, struct io_u *io_u)
 
                if (get_next_rand_offset(td, f, ddir, &b))
                        return 1;
-       } else
+       } else {
+               if (f->last_pos >= f->real_file_size)
+                       return 1;
+
                b = f->last_pos / td->o.min_bs[ddir];
+       }
 
        io_u->offset = (b * td->o.min_bs[ddir]) + f->file_offset;
        if (io_u->offset >= f->real_file_size)
@@ -154,7 +158,6 @@ static int get_next_offset(struct thread_data *td, struct io_u *io_u)
 
 static unsigned int get_next_buflen(struct thread_data *td, struct io_u *io_u)
 {
-       struct fio_file *f = io_u->file;
        const int ddir = io_u->ddir;
        unsigned int buflen;
        long r;
@@ -168,19 +171,6 @@ static unsigned int get_next_buflen(struct thread_data *td, struct io_u *io_u)
                        buflen = (buflen + td->o.min_bs[ddir] - 1) & ~(td->o.min_bs[ddir] - 1);
        }
 
-       while (buflen + io_u->offset > f->real_file_size) {
-               if (buflen == td->o.min_bs[ddir]) {
-                       if (!td->o.odirect) {
-                               assert(io_u->offset <= f->real_file_size);
-                               buflen = f->real_file_size - io_u->offset;
-                               return buflen;
-                       }
-                       return 0;
-               }
-
-               buflen = td->o.min_bs[ddir];
-       }
-
        return buflen;
 }
 
@@ -250,7 +240,7 @@ static enum fio_ddir get_rw_ddir(struct thread_data *td)
                         */
                        ddir = get_rand_ddir(td);
                        max_bytes = td->this_io_bytes[ddir];
-                       if (max_bytes >= (td->io_size * td->o.rwmix[ddir] / 100)) {
+                       if (max_bytes >= (td->o.size * td->o.rwmix[ddir] / 100)) {
                                if (!td->rw_end_set[ddir]) {
                                        td->rw_end_set[ddir] = 1;
                                        memcpy(&td->rw_end[ddir], &now, sizeof(now));
@@ -310,7 +300,7 @@ static int fill_io_u(struct thread_data *td, struct io_u *io_u)
           !(td->io_issues[DDIR_WRITE] % td->o.fsync_blocks) &&
             td->io_issues[DDIR_WRITE] && should_fsync(td)) {
                io_u->ddir = DDIR_SYNC;
-               return 0;
+               goto out;
        }
 
        io_u->ddir = get_rw_ddir(td);
@@ -329,12 +319,13 @@ static int fill_io_u(struct thread_data *td, struct io_u *io_u)
        /*
         * mark entry before potentially trimming io_u
         */
-       if (!td->o.read_iolog && td_random(td) && !td->o.norandommap)
+       if (td_random(td) && !td->o.norandommap)
                mark_random_map(td, io_u);
 
        /*
         * If using a write iolog, store this entry.
         */
+out:
        if (td->o.write_iolog_file)
                write_iolog_put(td, io_u);
 
@@ -417,6 +408,8 @@ static struct fio_file *get_next_file_rand(struct thread_data *td, int goodf,
 
                fno = (unsigned int) ((double) td->o.nr_files * (r / (RAND_MAX + 1.0)));
                f = &td->files[fno];
+               if (f->flags & FIO_FILE_DONE)
+                       continue;
 
                if ((!goodf || (f->flags & goodf)) && !(f->flags & badf))
                        return f;
@@ -439,6 +432,11 @@ static struct fio_file *get_next_file_rr(struct thread_data *td, int goodf,
                if (td->next_file >= td->o.nr_files)
                        td->next_file = 0;
 
+               if (f->flags & FIO_FILE_DONE) {
+                       f = NULL;
+                       continue;
+               }
+
                if ((!goodf || (f->flags & goodf)) && !(f->flags & badf))
                        break;
 
@@ -549,6 +547,7 @@ set_file:
                 */
                io_u->file = NULL;
                td_io_close_file(td, f);
+               f->flags |= FIO_FILE_DONE;
 
                /*
                 * probably not the right place to do this, but see
@@ -571,15 +570,6 @@ set_file:
                f->last_pos += td->o.zone_skip;
        }
 
-       if (io_u->buflen + io_u->offset > f->real_file_size) {
-               if (td->io_ops->flags & FIO_RAWIO) {
-                       put_io_u(td, io_u);
-                       return NULL;
-               }
-
-               io_u->buflen = f->real_file_size - io_u->offset;
-       }
-
        if (io_u->ddir != DDIR_SYNC) {
                if (!io_u->buflen) {
                        put_io_u(td, io_u);
@@ -660,7 +650,8 @@ static void io_completed(struct thread_data *td, struct io_u *io_u,
                add_bw_sample(td, idx, &icd->time);
                io_u_mark_latency(td, msec);
 
-               if ((td_rw(td) || td_write(td)) && idx == DDIR_WRITE)
+               if ((td_rw(td) || td_write(td)) && idx == DDIR_WRITE &&
+                   td->o.verify != VERIFY_NONE)
                        log_io_piece(td, io_u);
 
                icd->bytes_done[idx] += bytes;