+ f = get_next_file_rand(td, FIO_FILE_OPEN, FIO_FILE_CLOSING);
+
+ td->file_service_file = f;
+ td->file_service_left = td->file_service_nr - 1;
+out:
+ dprint(FD_FILE, "get_next_file: %p\n", f);
+ return f;
+}
+
+static struct fio_file *find_next_new_file(struct thread_data *td)
+{
+ struct fio_file *f;
+
+ if (!td->nr_open_files || td->nr_done_files >= td->o.nr_files)
+ return NULL;
+
+ if (td->o.file_service_type == FIO_FSERVICE_RR)
+ f = get_next_file_rr(td, 0, FIO_FILE_OPEN);
+ else
+ f = get_next_file_rand(td, 0, FIO_FILE_OPEN);
+
+ return f;
+}
+
+static int set_io_u_file(struct thread_data *td, struct io_u *io_u)
+{
+ struct fio_file *f;
+
+ do {
+ f = get_next_file(td);
+ if (!f)
+ return 1;
+
+set_file:
+ io_u->file = f;
+ get_file(f);
+
+ if (!fill_io_u(td, io_u))
+ break;
+
+ /*
+ * optimization to prevent close/open of the same file. This
+ * way we preserve queueing etc.
+ */
+ if (td->o.nr_files == 1 && td->o.time_based) {
+ put_file_log(td, f);
+ fio_file_reset(f);
+ goto set_file;
+ }
+
+ /*
+ * td_io_close() does a put_file() as well, so no need to
+ * do that here.
+ */
+ io_u->file = NULL;
+ td_io_close_file(td, f);
+ f->flags |= FIO_FILE_DONE;
+ td->nr_done_files++;
+
+ /*
+ * probably not the right place to do this, but see
+ * if we need to open a new file
+ */
+ if (td->nr_open_files < td->o.open_files &&
+ td->o.open_files != td->o.nr_files) {
+ f = find_next_new_file(td);
+
+ if (!f || td_io_open_file(td, f))
+ return 1;
+
+ goto set_file;
+ }
+ } while (1);
+
+ return 0;