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 <jens.axboe@oracle.com>
diff --git a/fio.c b/fio.c
index 858d6b8..3c64b7b 100644
--- a/fio.c
+++ b/fio.c
@@ -136,27 +136,6 @@
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 @@
{
struct timeval s;
unsigned long usec;
- struct fio_file *f;
int i, ret = 0;
td_set_runstate(td, TD_RUNNING);
@@ -375,11 +353,7 @@
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 @@
}
if (!td->error) {
+ struct fio_file *f;
+
if (td->cur_depth)
cleanup_pending_aio(td);
diff --git a/fio.h b/fio.h
index baaa9a8..12afa06 100644
--- a/fio.h
+++ b/fio.h
@@ -609,7 +609,7 @@
*/
#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 781599f..645cba4 100644
--- a/io_u.c
+++ b/io_u.c
@@ -316,6 +316,27 @@
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 @@
* 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 @@
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;