From 3d7c391dbdc56f261447b2d8ab65e74a42a20c41 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 19 Feb 2007 13:16:12 +0100 Subject: [PATCH] Retrieve next file to service in get_io_u() This improves requeue handling, we don't want to inadvertently skip a file because we requeue an io_u. Signed-off-by: Jens Axboe --- fio.c | 30 +++--------------------------- fio.h | 2 +- io_u.c | 32 +++++++++++++++++++++++++++++++- 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/fio.c b/fio.c index 858d6b81..3c64b7b7 100644 --- 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. @@ -361,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); @@ -375,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; @@ -479,6 +453,8 @@ requeue: } if (!td->error) { + struct fio_file *f; + if (td->cur_depth) cleanup_pending_aio(td); diff --git a/fio.h b/fio.h index baaa9a8d..12afa065 100644 --- 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 *); -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 *); diff --git a/io_u.c b/io_u.c index 781599f4..645cba40 100644 --- 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]++; } +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; @@ -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. */ -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); @@ -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; + 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; -- 2.25.1