Verify requeue handling
[fio.git] / fio.c
diff --git a/fio.c b/fio.c
index 6e78949b52fd7771b94d31bc0b14c0575e18c84c..3c64b7b7cab87a1eb0a40d342bb410244a3b360f 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -136,27 +136,6 @@ static inline int runtime_exceeded(struct thread_data *td, struct timeval *t)
        return 0;
 }
 
-static struct fio_file *get_next_file(struct thread_data *td)
-{
-       unsigned int old_next_file = td->next_file;
-       struct fio_file *f;
-
-       do {
-               f = &td->files[td->next_file];
-
-               td->next_file++;
-               if (td->next_file >= td->nr_files)
-                       td->next_file = 0;
-
-               if (f->fd != -1)
-                       break;
-
-               f = NULL;
-       } while (td->next_file != old_next_file);
-
-       return f;
-}
-
 /*
  * When job exits, we can cancel the in-flight IO if we are using async
  * io. Attempt to do so.
@@ -209,6 +188,7 @@ static int fio_io_sync(struct thread_data *td, struct fio_file *f)
                return 1;
        }
 
+requeue:
        ret = td_io_queue(td, io_u);
        if (ret < 0) {
                td_verror(td, io_u->error);
@@ -224,6 +204,10 @@ static int fio_io_sync(struct thread_data *td, struct fio_file *f)
                }
 
                io_u_sync_complete(td, io_u, NULL);
+       } else if (ret == FIO_Q_BUSY) {
+               if (td_io_commit(td))
+                       return 1;
+               goto requeue;
        }
 
        return 0;
@@ -285,6 +269,10 @@ requeue:
                        continue;
                case FIO_Q_QUEUED:
                        break;
+               case FIO_Q_BUSY:
+                       requeue_io_u(td, &io_u);
+                       ret = td_io_commit(td);
+                       break;
                default:
                        assert(ret < 0);
                        td_verror(td, -ret);
@@ -299,7 +287,7 @@ requeue:
                 * completed io_u's first.
                 */
                min_events = 0;
-               if (queue_full(td))
+               if (queue_full(td) || ret == FIO_Q_BUSY)
                        min_events = 1;
 
                /*
@@ -352,7 +340,6 @@ static void do_io(struct thread_data *td)
 {
        struct timeval s;
        unsigned long usec;
-       struct fio_file *f;
        int i, ret = 0;
 
        td_set_runstate(td, TD_RUNNING);
@@ -366,11 +353,7 @@ static void do_io(struct thread_data *td)
                if (td->terminate)
                        break;
 
-               f = get_next_file(td);
-               if (!f)
-                       break;
-
-               io_u = get_io_u(td, f);
+               io_u = get_io_u(td);
                if (!io_u)
                        break;
 
@@ -403,6 +386,10 @@ requeue:
                        break;
                case FIO_Q_QUEUED:
                        break;
+               case FIO_Q_BUSY:
+                       requeue_io_u(td, &io_u);
+                       ret = td_io_commit(td);
+                       break;
                default:
                        assert(ret < 0);
                        put_io_u(td, io_u);
@@ -412,14 +399,15 @@ requeue:
                if (ret < 0 || td->error)
                        break;
 
-               add_slat_sample(td, io_u->ddir, mtime_since(&io_u->start_time, &io_u->issue_time));
+               if (io_u)
+                       add_slat_sample(td, io_u->ddir, mtime_since(&io_u->start_time, &io_u->issue_time));
 
                /*
                 * See if we need to complete some commands
                 */
-               if (ret == FIO_Q_QUEUED) {
+               if (ret == FIO_Q_QUEUED || ret == FIO_Q_BUSY) {
                        min_evts = 0;
-                       if (queue_full(td))
+                       if (queue_full(td) || ret == FIO_Q_BUSY)
                                min_evts = 1;
 
                        fio_gettime(&comp_time, NULL);
@@ -465,6 +453,8 @@ requeue:
        }
 
        if (!td->error) {
+               struct fio_file *f;
+
                if (td->cur_depth)
                        cleanup_pending_aio(td);
 
@@ -633,6 +623,7 @@ static void *thread_main(void *data)
 
        INIT_LIST_HEAD(&td->io_u_freelist);
        INIT_LIST_HEAD(&td->io_u_busylist);
+       INIT_LIST_HEAD(&td->io_u_requeues);
        INIT_LIST_HEAD(&td->io_hist_list);
        INIT_LIST_HEAD(&td->io_log_list);