Retrieve next file to service in get_io_u()
authorJens Axboe <jens.axboe@oracle.com>
Mon, 19 Feb 2007 12:16:12 +0000 (13:16 +0100)
committerJens Axboe <jens.axboe@oracle.com>
Mon, 19 Feb 2007 12:16:12 +0000 (13:16 +0100)
This improves requeue handling, we don't want to inadvertently
skip a file because we requeue an io_u.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
fio.c
fio.h
io_u.c

diff --git a/fio.c b/fio.c
index 858d6b81e6c5df199e17ae33f09d802105b1011b..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;
 }
 
        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.
 /*
  * When job exits, we can cancel the in-flight IO if we are using async
  * io. Attempt to do so.
@@ -361,7 +340,6 @@ static void do_io(struct thread_data *td)
 {
        struct timeval s;
        unsigned long usec;
 {
        struct timeval s;
        unsigned long usec;
-       struct fio_file *f;
        int i, ret = 0;
 
        td_set_runstate(td, TD_RUNNING);
        int i, ret = 0;
 
        td_set_runstate(td, TD_RUNNING);
@@ -375,11 +353,7 @@ static void do_io(struct thread_data *td)
                if (td->terminate)
                        break;
 
                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;
 
                if (!io_u)
                        break;
 
@@ -479,6 +453,8 @@ requeue:
        }
 
        if (!td->error) {
        }
 
        if (!td->error) {
+               struct fio_file *f;
+
                if (td->cur_depth)
                        cleanup_pending_aio(td);
 
                if (td->cur_depth)
                        cleanup_pending_aio(td);
 
diff --git a/fio.h b/fio.h
index baaa9a8d51f57512d2a5ed062e12fa0d4cc658be..12afa0651ae6e6800d7d316d09735a13178d88bf 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -609,7 +609,7 @@ extern void free_io_mem(struct thread_data *);
  */
 #define queue_full(td) list_empty(&(td)->io_u_freelist)
 extern struct io_u *__get_io_u(struct thread_data *);
  */
 #define queue_full(td) list_empty(&(td)->io_u_freelist)
 extern struct io_u *__get_io_u(struct thread_data *);
-extern struct io_u *get_io_u(struct thread_data *, struct fio_file *);
+extern struct io_u *get_io_u(struct thread_data *);
 extern void put_io_u(struct thread_data *, struct io_u *);
 extern void requeue_io_u(struct thread_data *, struct io_u **);
 extern long io_u_sync_complete(struct thread_data *, struct io_u *, endio_handler *);
 extern void put_io_u(struct thread_data *, struct io_u *);
 extern void requeue_io_u(struct thread_data *, struct io_u **);
 extern long io_u_sync_complete(struct thread_data *, struct io_u *, endio_handler *);
diff --git a/io_u.c b/io_u.c
index 781599f48724c14530e81a0e6020c100fffd1a31..645cba40b4f012096bafff178b697ecff0ec46aa 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -316,6 +316,27 @@ static void io_u_mark_latency(struct thread_data *td, unsigned long msec)
        td->io_u_lat[index]++;
 }
 
        td->io_u_lat[index]++;
 }
 
+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;
+}
+
 struct io_u *__get_io_u(struct thread_data *td)
 {
        struct io_u *io_u = NULL;
 struct io_u *__get_io_u(struct thread_data *td)
 {
        struct io_u *io_u = NULL;
@@ -345,8 +366,9 @@ struct io_u *__get_io_u(struct thread_data *td)
  * Return an io_u to be processed. Gets a buflen and offset, sets direction,
  * etc. The returned io_u is fully ready to be prepped and submitted.
  */
  * Return an io_u to be processed. Gets a buflen and offset, sets direction,
  * etc. The returned io_u is fully ready to be prepped and submitted.
  */
-struct io_u *get_io_u(struct thread_data *td, struct fio_file *f)
+struct io_u *get_io_u(struct thread_data *td)
 {
 {
+       struct fio_file *f;
        struct io_u *io_u;
 
        io_u = __get_io_u(td);
        struct io_u *io_u;
 
        io_u = __get_io_u(td);
@@ -359,6 +381,14 @@ struct io_u *get_io_u(struct thread_data *td, struct fio_file *f)
        if (io_u->file)
                return io_u;
 
        if (io_u->file)
                return io_u;
 
+       f = get_next_file(td);
+       if (!f) {
+               put_io_u(td, io_u);
+               return NULL;
+       }
+
+       io_u->file = f;
+
        if (td->zone_bytes >= td->zone_size) {
                td->zone_bytes = 0;
                f->last_pos += td->zone_skip;
        if (td->zone_bytes >= td->zone_size) {
                td->zone_bytes = 0;
                f->last_pos += td->zone_skip;