X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=io_u.c;h=c78865636b1f52f159bf8ef7d6846deb5fec5ef1;hp=69f2f19d426053d8fc487affc991534a55c3f4f9;hb=d3aad8f28b9e214fccfce5e3a406dec723f57a62;hpb=762e595063e15559ba125fa5ac4b496ee69f4d23 diff --git a/io_u.c b/io_u.c index 69f2f19d..c7886563 100644 --- a/io_u.c +++ b/io_u.c @@ -111,7 +111,10 @@ static int get_next_offset(struct thread_data *td, struct io_u *io_u) do { r = os_random_long(&td->random_state); - b = ((max_blocks - 1) * r / (unsigned long long) (RAND_MAX+1.0)); + if (!max_blocks) + b = 0; + else + b = ((max_blocks - 1) * r / (unsigned long long) (RAND_MAX+1.0)); if (td->norandommap) break; rb = b + (f->file_offset / td->min_bs[ddir]); @@ -151,8 +154,14 @@ static unsigned int get_next_buflen(struct thread_data *td, struct io_u *io_u) } while (buflen + io_u->offset > f->real_file_size) { - if (buflen == td->min_bs[ddir]) + if (buflen == td->min_bs[ddir]) { + if (!td->odirect) { + assert(io_u->offset <= f->real_file_size); + buflen = f->real_file_size - io_u->offset; + return buflen; + } return 0; + } buflen = td->min_bs[ddir]; } @@ -330,17 +339,19 @@ static void io_u_mark_latency(struct thread_data *td, unsigned long msec) /* * Get next file to service by choosing one at random */ -static struct fio_file *get_next_file_rand(struct thread_data *td) +static struct fio_file *get_next_file_rand(struct thread_data *td, int goodf, + int badf) { - unsigned int fileno; struct fio_file *f; + int fno; do { long r = os_random_long(&td->next_file_state); - fileno = (unsigned int) ((double) (td->open_files * r) / (RAND_MAX + 1.0)); - f = &td->files[fileno]; - if (f->open) + fno = (unsigned int) ((double) td->nr_files * (r / (RAND_MAX + 1.0))); + f = &td->files[fno]; + + if ((!goodf || (f->flags & goodf)) && !(f->flags & badf)) return f; } while (1); } @@ -348,7 +359,8 @@ static struct fio_file *get_next_file_rand(struct thread_data *td) /* * Get next file to service by doing round robin between all available ones */ -static struct fio_file *get_next_file_rr(struct thread_data *td) +static struct fio_file *get_next_file_rr(struct thread_data *td, int goodf, + int badf) { unsigned int old_next_file = td->next_file; struct fio_file *f; @@ -357,10 +369,10 @@ static struct fio_file *get_next_file_rr(struct thread_data *td) f = &td->files[td->next_file]; td->next_file++; - if (td->next_file >= td->open_files) + if (td->next_file >= td->nr_files) td->next_file = 0; - if (f->open) + if ((!goodf || (f->flags & goodf)) && !(f->flags & badf)) break; f = NULL; @@ -373,23 +385,37 @@ static struct fio_file *get_next_file(struct thread_data *td) { struct fio_file *f; + assert(td->nr_files <= td->files_index); + if (!td->nr_open_files) return NULL; f = td->file_service_file; - if (f && f->open && td->file_service_left--) + if (f && (f->flags & FIO_FILE_OPEN) && td->file_service_left--) return f; if (td->file_service_type == FIO_FSERVICE_RR) - f = get_next_file_rr(td); + f = get_next_file_rr(td, FIO_FILE_OPEN, FIO_FILE_CLOSING); else - f = get_next_file_rand(td); + 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; return f; } +static struct fio_file *find_next_new_file(struct thread_data *td) +{ + struct fio_file *f; + + if (td->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; +} + struct io_u *__get_io_u(struct thread_data *td) { struct io_u *io_u = NULL; @@ -426,6 +452,7 @@ struct io_u *get_io_u(struct thread_data *td) { struct fio_file *f; struct io_u *io_u; + int ret; io_u = __get_io_u(td); if (!io_u) @@ -444,6 +471,7 @@ struct io_u *get_io_u(struct thread_data *td) return NULL; } +set_file: io_u->file = f; if (!fill_io_u(td, io_u)) @@ -459,14 +487,15 @@ struct io_u *get_io_u(struct thread_data *td) * probably not the right place to do this, but see * if we need to open a new file */ - if (td->nr_open_files < td->nr_files && + if (td->nr_open_files < td->open_files && td->open_files != td->nr_files) { - int ret = td_io_open_file(td, f); + f = find_next_new_file(td); - if (ret) { + if (!f || (ret = td_io_open_file(td, f))) { put_io_u(td, io_u); return NULL; } + goto set_file; } } while (1); @@ -537,6 +566,8 @@ static void io_completed(struct thread_data *td, struct io_u *io_u, assert(io_u->flags & IO_U_F_FLIGHT); io_u->flags &= ~IO_U_F_FLIGHT; + put_file(td, io_u->file); + if (io_u->ddir == DDIR_SYNC) { td->last_was_sync = 1; return;