Merge branch 'adjusting-libpmem' of https://github.com/lukaszstolarczuk/fio into...
[fio.git] / io_u.c
diff --git a/io_u.c b/io_u.c
index ae1438fd665673e3077cc41c8dae0e4ace1b01c4..2ef5acec95fe798bd4a657e4936414ea84593efd 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -464,6 +464,7 @@ static int get_next_block(struct thread_data *td, struct io_u *io_u,
                        log_err("fio: bug in offset generation: offset=%llu, b=%llu\n", (unsigned long long) offset, (unsigned long long) b);
                        ret = 1;
                }
+               io_u->verify_offset = io_u->offset;
        }
 
        return ret;
@@ -506,6 +507,7 @@ static int get_next_offset(struct thread_data *td, struct io_u *io_u,
                return 1;
        }
 
+       io_u->verify_offset = io_u->offset;
        return 0;
 }
 
@@ -680,7 +682,22 @@ static enum fio_ddir rate_ddir(struct thread_data *td, enum fio_ddir ddir)
        if (td->o.io_submit_mode == IO_MODE_INLINE)
                io_u_quiesce(td);
 
+       if (td->o.timeout && ((usec + now) > td->o.timeout)) {
+               /*
+                * check if the usec is capable of taking negative values
+                */
+               if (now > td->o.timeout) {
+                       ddir = DDIR_INVAL;
+                       return ddir;
+               }
+               usec = td->o.timeout - now;
+       }
        usec_sleep(td, usec);
+
+       now = utime_since_now(&td->epoch);
+       if ((td->o.timeout && (now > td->o.timeout)) || td->terminate)
+               ddir = DDIR_INVAL;
+
        return ddir;
 }
 
@@ -896,6 +913,10 @@ static int fill_io_u(struct thread_data *td, struct io_u *io_u)
 
        set_rw_ddir(td, io_u);
 
+       if (io_u->ddir == DDIR_INVAL) {
+               dprint(FD_IO, "invalid direction received ddir = %d", io_u->ddir);
+               return 1;
+       }
        /*
         * fsync() or fdatasync() or trim etc, we are done
         */
@@ -945,6 +966,7 @@ static int fill_io_u(struct thread_data *td, struct io_u *io_u)
 
 out:
        dprint_io_u(io_u, "fill");
+       io_u->verify_offset = io_u->offset;
        td->zone_bytes += io_u->buflen;
        return 0;
 }
@@ -1545,9 +1567,10 @@ struct io_u *__get_io_u(struct thread_data *td)
                __td_io_u_lock(td);
 
 again:
-       if (!io_u_rempty(&td->io_u_requeues))
+       if (!io_u_rempty(&td->io_u_requeues)) {
                io_u = io_u_rpop(&td->io_u_requeues);
-       else if (!queue_full(td)) {
+               io_u->resid = 0;
+       } else if (!queue_full(td)) {
                io_u = io_u_qpop(&td->io_u_freelist);
 
                io_u->file = NULL;
@@ -1934,8 +1957,8 @@ static void io_completed(struct thread_data *td, struct io_u **io_u_ptr,
                if (io_u->error)
                        unlog_io_piece(td, io_u);
                else {
-                       io_u->ipo->flags &= ~IP_F_IN_FLIGHT;
-                       write_barrier();
+                       atomic_store_release(&io_u->ipo->flags,
+                                       io_u->ipo->flags & ~IP_F_IN_FLIGHT);
                }
        }
 
@@ -1954,9 +1977,24 @@ static void io_completed(struct thread_data *td, struct io_u **io_u_ptr,
        td->last_ddir = ddir;
 
        if (!io_u->error && ddir_rw(ddir)) {
-               unsigned long long bytes = io_u->buflen - io_u->resid;
+               unsigned long long bytes = io_u->xfer_buflen - io_u->resid;
                int ret;
 
+               /*
+                * Make sure we notice short IO from here, and requeue them
+                * appropriately!
+                */
+               if (io_u->resid) {
+                       io_u->xfer_buflen = io_u->resid;
+                       io_u->xfer_buf += bytes;
+                       io_u->offset += bytes;
+                       td->ts.short_io_u[io_u->ddir]++;
+                       if (io_u->offset < io_u->file->real_file_size) {
+                               requeue_io_u(td, io_u_ptr);
+                               return;
+                       }
+               }
+
                td->io_blocks[ddir]++;
                td->io_bytes[ddir] += bytes;