uint64_t bytes_done[DDIR_RWDIR_CNT] = { 0, 0, 0 };
unsigned int i;
int ret = 0;
- uint64_t bytes_issued = 0;
+ uint64_t total_bytes, bytes_issued = 0;
if (in_ramp_time(td))
td_set_runstate(td, TD_RAMP);
lat_target_init(td);
+ /*
+ * If verify_backlog is enabled, we'll run the verify in this
+ * handler as well. For that case, we may need up to twice the
+ * amount of bytes.
+ */
+ total_bytes = td->o.size;
+ if (td->o.verify != VERIFY_NONE &&
+ (td_write(td) && td->o.verify_backlog))
+ total_bytes += td->o.size;
+
while ((td->o.read_iolog_file && !flist_empty(&td->io_log_list)) ||
(!flist_empty(&td->trim_list)) || !io_bytes_exceeded(td) ||
td->o.time_based) {
if (flow_threshold_exceeded(td))
continue;
- if (bytes_issued >= (uint64_t) td->o.size)
+ if (bytes_issued >= total_bytes)
break;
io_u = get_io_u(td);
else
td_set_runstate(td, TD_RUNNING);
+ /*
+ * Always log IO before it's issued, so we know the specific
+ * order of it. The logged unit will track when the IO has
+ * completed.
+ */
if (td_write(td) && io_u->ddir == DDIR_WRITE &&
td->o.do_verify &&
td->o.verify != VERIFY_NONE &&
fio_mutex_down(td->mutex);
dprint(FD_MUTEX, "done waiting on td->mutex\n");
- /*
- * the ->mutex mutex is now no longer used, close it to avoid
- * eating a file descriptor
- */
- fio_mutex_remove(td->mutex);
- td->mutex = NULL;
-
/*
* A new gid requires privilege, so we need to do this before setting
* the uid.
fio_mutex_remove(td->rusage_sem);
td->rusage_sem = NULL;
+ fio_mutex_remove(td->mutex);
+ td->mutex = NULL;
+
td_set_runstate(td, TD_EXITED);
return (void *) (uintptr_t) td->error;
}