X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=io_u.c;h=8cc348a835fed67a2310c04f84b4608281db1315;hp=a630817f6f41a3b036530affb0a06dce8908b5f0;hb=8bad3c5b15c221cbd141a357d8ba81ca4cc45cac;hpb=a917a8b3dfeefdd7007ba2f46f21fc145574309d diff --git a/io_u.c b/io_u.c index a630817f..8cc348a8 100644 --- a/io_u.c +++ b/io_u.c @@ -126,16 +126,20 @@ static unsigned long long last_block(struct thread_data *td, struct fio_file *f, static int get_next_free_block(struct thread_data *td, struct fio_file *f, enum fio_ddir ddir, unsigned long long *b) { - unsigned long long min_bs = td->o.rw_min_bs; + unsigned long long min_bs = td->o.rw_min_bs, lastb; int i; + lastb = last_block(td, f, ddir); + if (!lastb) + return 1; + i = f->last_free_lookup; *b = (i * BLOCKS_PER_MAP); while ((*b) * min_bs < f->real_file_size && (*b) * min_bs < f->io_size) { if (f->file_map[i] != (unsigned int) -1) { *b += ffz(f->file_map[i]); - if (*b > last_block(td, f, ddir)) + if (*b > lastb) break; f->last_free_lookup = i; return 0; @@ -152,14 +156,17 @@ static int get_next_free_block(struct thread_data *td, struct fio_file *f, static int get_next_rand_offset(struct thread_data *td, struct fio_file *f, enum fio_ddir ddir, unsigned long long *b) { - unsigned long long r; + unsigned long long r, lastb; int loops = 5; + lastb = last_block(td, f, ddir); + if (!lastb) + return 1; + do { r = os_random_long(&td->random_state); dprint(FD_RANDOM, "off rand %llu\n", r); - *b = (last_block(td, f, ddir) - 1) - * (r / ((unsigned long long) OS_RAND_MAX + 1.0)); + *b = (lastb - 1) * (r / ((unsigned long long) OS_RAND_MAX + 1.0)); /* * if we are not maintaining a random map, we are done. @@ -246,7 +253,8 @@ static int get_next_block(struct thread_data *td, struct io_u *io_u, ret = get_next_rand_block(td, f, ddir, b); } else if (td->o.rw_seq == RW_SEQ_IDENT) { if (f->last_start != -1ULL) - *b = (f->last_start - f->file_offset) / td->o.min_bs[ddir]; + *b = (f->last_start - f->file_offset) + / td->o.min_bs[ddir]; else *b = 0; ret = 0; @@ -278,10 +286,8 @@ static int __get_next_offset(struct thread_data *td, struct io_u *io_u) td->ddir_seq_nr = td->o.ddir_seq_nr; } - if (get_next_block(td, io_u, ddir, rw_seq_hit, &b)) { - printf("fail\n"); + if (get_next_block(td, io_u, ddir, rw_seq_hit, &b)) return 1; - } io_u->offset = b * td->o.ba[ddir]; if (io_u->offset >= f->io_size) { @@ -502,6 +508,17 @@ static enum fio_ddir get_rw_ddir(struct thread_data *td) return td->rwmix_ddir; } +static void set_rw_ddir(struct thread_data *td, struct io_u *io_u) +{ + io_u->ddir = get_rw_ddir(td); + + if (io_u->ddir == DDIR_WRITE && (td->io_ops->flags & FIO_BARRIER) && + td->o.barrier_blocks && + !(td->io_issues[DDIR_WRITE] % td->o.barrier_blocks) && + td->io_issues[DDIR_WRITE]) + io_u->flags |= IO_U_F_BARRIER; +} + void put_file_log(struct thread_data *td, struct fio_file *f) { int ret = put_file(td, f); @@ -561,7 +578,7 @@ static int fill_io_u(struct thread_data *td, struct io_u *io_u) if (td->io_ops->flags & FIO_NOIO) goto out; - io_u->ddir = get_rw_ddir(td); + set_rw_ddir(td, io_u); /* * fsync() or fdatasync() or trim etc, we are done @@ -964,7 +981,7 @@ again: if (io_u) { assert(io_u->flags & IO_U_F_FREE); io_u->flags &= ~(IO_U_F_FREE | IO_U_F_FREE_DEF); - io_u->flags &= ~IO_U_F_TRIMMED; + io_u->flags &= ~(IO_U_F_TRIMMED | IO_U_F_BARRIER); io_u->error = 0; flist_del(&io_u->list);