* and invalidate the cache, if we need to.
*/
if (f->last_pos[ddir] >= f->io_size + get_start_offset(td, f) &&
- o->time_based) {
+ o->time_based && o->nr_files == 1) {
f->last_pos[ddir] = f->file_offset;
loop_cache_invalidate(td, f);
}
break;
case 1 ... 4:
idx = 1;
- fallthrough;
+ fio_fallthrough;
case 0:
break;
}
break;
case 2 ... 3:
idx = 1;
- fallthrough;
+ fio_fallthrough;
case 1:
break;
}
break;
case 2 ... 3:
idx = 1;
- fallthrough;
+ fio_fallthrough;
case 0 ... 1:
break;
}
break;
case 2 ... 3:
idx = 1;
- fallthrough;
+ fio_fallthrough;
case 0 ... 1:
break;
}
break;
case 2 ... 3:
idx = 1;
- fallthrough;
+ fio_fallthrough;
case 0 ... 1:
break;
}
assert(io_u->flags & IO_U_F_FREE);
io_u_clear(td, io_u, IO_U_F_FREE | IO_U_F_NO_FILE_PUT |
IO_U_F_TRIMMED | IO_U_F_BARRIER |
- IO_U_F_VER_LIST | IO_U_F_PRIORITY);
+ IO_U_F_VER_LIST);
io_u->error = 0;
io_u->acct_ddir = -1;
io_u->xfer_buf = io_u->buf;
io_u->xfer_buflen = io_u->buflen;
+ /*
+ * Remember the issuing context priority. The IO engine may change this.
+ */
+ io_u->ioprio = td->ioprio;
+ io_u->clat_prio_index = 0;
out:
assert(io_u->file);
if (!td_io_prep(td, io_u)) {
unsigned long long tnsec;
tnsec = ntime_since(&io_u->start_time, &icd->time);
- add_lat_sample(td, idx, tnsec, bytes, io_u->offset, io_u_is_prio(io_u));
+ add_lat_sample(td, idx, tnsec, bytes, io_u->offset,
+ io_u->ioprio, io_u->clat_prio_index);
if (td->flags & TD_F_PROFILE_OPS) {
struct prof_io_ops *ops = &td->prof_io_ops;
if (ddir_rw(idx)) {
if (!td->o.disable_clat) {
- add_clat_sample(td, idx, llnsec, bytes, io_u->offset, io_u_is_prio(io_u));
+ add_clat_sample(td, idx, llnsec, bytes, io_u->offset,
+ io_u->ioprio, io_u->clat_prio_index);
io_u_mark_latency(td, llnsec);
}
* Make sure we notice short IO from here, and requeue them
* appropriately!
*/
- if (io_u->resid) {
+ if (bytes && io_u->resid) {
io_u->xfer_buflen = io_u->resid;
io_u->xfer_buf += bytes;
io_u->offset += bytes;
td = td->parent;
add_slat_sample(td, io_u->ddir, slat_time, io_u->xfer_buflen,
- io_u->offset, io_u_is_prio(io_u));
+ io_u->offset, io_u->ioprio);
}
}
if (o->compress_percentage || o->dedupe_percentage) {
unsigned int perc = td->o.compress_percentage;
- struct frand_state *rs;
+ struct frand_state *rs = NULL;
unsigned long long left = max_bs;
unsigned long long this_write;
do {
- rs = get_buf_state(td);
+ /*
+ * Buffers are either entirely dedupe-able or not.
+ * If we choose to dedup, the buffer should undergo
+ * the same manipulation as the original write. Which
+ * means we should retrack the steps we took for compression
+ * as well.
+ */
+ if (!rs)
+ rs = get_buf_state(td);
min_write = min(min_write, left);
- if (perc) {
- this_write = min_not_zero(min_write,
- (unsigned long long) td->o.compress_chunk);
+ this_write = min_not_zero(min_write,
+ (unsigned long long) td->o.compress_chunk);
- fill_random_buf_percentage(rs, buf, perc,
- this_write, this_write,
- o->buffer_pattern,
- o->buffer_pattern_bytes);
- } else {
- fill_random_buf(rs, buf, min_write);
- this_write = min_write;
- }
+ fill_random_buf_percentage(rs, buf, perc,
+ this_write, this_write,
+ o->buffer_pattern,
+ o->buffer_pattern_bytes);
buf += this_write;
left -= this_write;
int ret;
if (io_u->ddir == DDIR_SYNC) {
+#ifdef CONFIG_FCNTL_SYNC
+ ret = fcntl(io_u->file->fd, F_FULLFSYNC);
+#else
ret = fsync(io_u->file->fd);
+#endif
} else if (io_u->ddir == DDIR_DATASYNC) {
#ifdef CONFIG_FDATASYNC
ret = fdatasync(io_u->file->fd);
struct fio_file *f = io_u->file;
int ret;
+ if (td->o.zone_mode == ZONE_MODE_ZBD) {
+ ret = zbd_do_io_u_trim(td, io_u);
+ if (ret == io_u_completed)
+ return io_u->xfer_buflen;
+ if (ret)
+ goto err;
+ }
+
ret = os_trim(f, io_u->offset, io_u->xfer_buflen);
if (!ret)
return io_u->xfer_buflen;
+err:
io_u->error = ret;
return 0;
#endif