X-Git-Url: https://git.kernel.dk/?a=blobdiff_plain;f=io_u.c;h=09e5f15a8b1ffe785adcd546da1e8232c9f47399;hb=1e34a6eade43132d5a2076a540b7759a93dcea97;hp=27b6c92ab99e6209db805563db5a58aed3ad527a;hpb=2091760e59615146d7cce41afc8d38e6d74eda97;p=fio.git diff --git a/io_u.c b/io_u.c index 27b6c92a..09e5f15a 100644 --- a/io_u.c +++ b/io_u.c @@ -717,7 +717,7 @@ static enum fio_ddir rate_ddir(struct thread_data *td, enum fio_ddir ddir) * check if the usec is capable of taking negative values */ if (now > td->o.timeout) { - ddir = DDIR_INVAL; + ddir = DDIR_TIMEOUT; return ddir; } usec = td->o.timeout - now; @@ -726,7 +726,7 @@ static enum fio_ddir rate_ddir(struct thread_data *td, enum fio_ddir ddir) now = utime_since_now(&td->epoch); if ((td->o.timeout && (now > td->o.timeout)) || td->terminate) - ddir = DDIR_INVAL; + ddir = DDIR_TIMEOUT; return ddir; } @@ -940,6 +940,65 @@ static void setup_strided_zone_mode(struct thread_data *td, struct io_u *io_u) fio_file_reset(td, f); } +static int fill_multi_range_io_u(struct thread_data *td, struct io_u *io_u) +{ + bool is_random; + uint64_t buflen, i = 0; + struct trim_range *range; + struct fio_file *f = io_u->file; + uint8_t *buf; + + buf = io_u->buf; + buflen = 0; + + while (i < td->o.num_range) { + range = (struct trim_range *)buf; + if (get_next_offset(td, io_u, &is_random)) { + dprint(FD_IO, "io_u %p, failed getting offset\n", + io_u); + break; + } + + io_u->buflen = get_next_buflen(td, io_u, is_random); + if (!io_u->buflen) { + dprint(FD_IO, "io_u %p, failed getting buflen\n", io_u); + break; + } + + if (io_u->offset + io_u->buflen > io_u->file->real_file_size) { + dprint(FD_IO, "io_u %p, off=0x%llx + len=0x%llx exceeds file size=0x%llx\n", + io_u, + (unsigned long long) io_u->offset, io_u->buflen, + (unsigned long long) io_u->file->real_file_size); + break; + } + + range->start = io_u->offset; + range->len = io_u->buflen; + buflen += io_u->buflen; + f->last_start[io_u->ddir] = io_u->offset; + f->last_pos[io_u->ddir] = io_u->offset + range->len; + + buf += sizeof(struct trim_range); + i++; + + if (td_random(td) && file_randommap(td, io_u->file)) + mark_random_map(td, io_u, io_u->offset, io_u->buflen); + dprint_io_u(io_u, "fill"); + } + if (buflen) { + /* + * Set buffer length as overall trim length for this IO, and + * tell the ioengine about the number of ranges to be trimmed. + */ + io_u->buflen = buflen; + io_u->number_trim = i; + return 0; + } + + return 1; +} + static int fill_io_u(struct thread_data *td, struct io_u *io_u) { bool is_random; @@ -951,7 +1010,7 @@ static int fill_io_u(struct thread_data *td, struct io_u *io_u) set_rw_ddir(td, io_u); - if (io_u->ddir == DDIR_INVAL) { + if (io_u->ddir == DDIR_INVAL || io_u->ddir == DDIR_TIMEOUT) { dprint(FD_IO, "invalid direction received ddir = %d", io_u->ddir); return 1; } @@ -966,22 +1025,27 @@ static int fill_io_u(struct thread_data *td, struct io_u *io_u) else if (td->o.zone_mode == ZONE_MODE_ZBD) setup_zbd_zone_mode(td, io_u); - /* - * No log, let the seq/rand engine retrieve the next buflen and - * position. - */ - if (get_next_offset(td, io_u, &is_random)) { - dprint(FD_IO, "io_u %p, failed getting offset\n", io_u); - return 1; - } + if (multi_range_trim(td, io_u)) { + if (fill_multi_range_io_u(td, io_u)) + return 1; + } else { + /* + * No log, let the seq/rand engine retrieve the next buflen and + * position. + */ + if (get_next_offset(td, io_u, &is_random)) { + dprint(FD_IO, "io_u %p, failed getting offset\n", io_u); + return 1; + } - io_u->buflen = get_next_buflen(td, io_u, is_random); - if (!io_u->buflen) { - dprint(FD_IO, "io_u %p, failed getting buflen\n", io_u); - return 1; + io_u->buflen = get_next_buflen(td, io_u, is_random); + if (!io_u->buflen) { + dprint(FD_IO, "io_u %p, failed getting buflen\n", io_u); + return 1; + } } - offset = io_u->offset; + if (td->o.zone_mode == ZONE_MODE_ZBD) { ret = zbd_adjust_block(td, io_u); if (ret == io_u_eof) { @@ -1004,11 +1068,12 @@ static int fill_io_u(struct thread_data *td, struct io_u *io_u) /* * mark entry before potentially trimming io_u */ - if (td_random(td) && file_randommap(td, io_u->file)) + if (!multi_range_trim(td, io_u) && td_random(td) && file_randommap(td, io_u->file)) io_u->buflen = mark_random_map(td, io_u, offset, io_u->buflen); out: - dprint_io_u(io_u, "fill"); + if (!multi_range_trim(td, io_u)) + dprint_io_u(io_u, "fill"); io_u->verify_offset = io_u->offset; td->zone_bytes += io_u->buflen; return 0; @@ -1419,6 +1484,10 @@ static long set_io_u_file(struct thread_data *td, struct io_u *io_u) put_file_log(td, f); td_io_close_file(td, f); io_u->file = NULL; + + if (io_u->ddir == DDIR_TIMEOUT) + return 1; + if (td->o.file_service_type & __FIO_FSERVICE_NONUNIFORM) fio_file_reset(td, f); else { @@ -1810,7 +1879,7 @@ struct io_u *get_io_u(struct thread_data *td) assert(fio_file_open(f)); - if (ddir_rw(io_u->ddir)) { + if (ddir_rw(io_u->ddir) && !multi_range_trim(td, io_u)) { if (!io_u->buflen && !td_ioengine_flagged(td, FIO_NOIO)) { dprint(FD_IO, "get_io_u: zero buflen on %p\n", io_u); goto err_put; @@ -1826,8 +1895,9 @@ struct io_u *get_io_u(struct thread_data *td) io_u->buflen); } else if ((td->flags & TD_F_SCRAMBLE_BUFFERS) && !(td->flags & TD_F_COMPRESS) && - !(td->flags & TD_F_DO_VERIFY)) + !(td->flags & TD_F_DO_VERIFY)) { do_scramble = 1; + } } else if (io_u->ddir == DDIR_READ) { /* * Reset the buf_filled parameters so next time if the @@ -1879,6 +1949,8 @@ static void __io_u_log_error(struct thread_data *td, struct io_u *io_u) io_ddir_name(io_u->ddir), io_u->offset, io_u->xfer_buflen); + zbd_log_err(td, io_u); + if (td->io_ops->errdetails) { char *err = td->io_ops->errdetails(io_u); @@ -2145,7 +2217,8 @@ static void io_u_update_bytes_done(struct thread_data *td, if (td->runstate == TD_VERIFYING) { td->bytes_verified += icd->bytes_done[DDIR_READ]; - return; + if (td_write(td)) + return; } for (ddir = 0; ddir < DDIR_RWDIR_CNT; ddir++)