* The main verify engine. Runs over the writes we previously submitted,
* reads the blocks back in, and checks the crc/md5 of the data.
*/
-static void do_verify(struct thread_data *td)
+static void do_verify(struct thread_data *td, uint64_t verify_bytes)
{
struct fio_file *f;
struct io_u *io_u;
int ret, min_events;
+ uint64_t io_bytes;
unsigned int i;
dprint(FD_VERIFY, "starting loop\n");
td_set_runstate(td, TD_VERIFYING);
io_u = NULL;
+ io_bytes = 0;
while (!td->terminate) {
+ enum fio_ddir ddir;
int ret2, full;
update_tv_cache(td);
if (flow_threshold_exceeded(td))
continue;
- io_u = __get_io_u(td);
- if (!io_u)
- break;
+ if (!td->o.experimental_verify) {
+ io_u = __get_io_u(td);
+ if (!io_u)
+ break;
- if (get_next_verify(td, io_u)) {
- put_io_u(td, io_u);
- break;
- }
+ if (get_next_verify(td, io_u)) {
+ put_io_u(td, io_u);
+ break;
+ }
- if (td_io_prep(td, io_u)) {
- put_io_u(td, io_u);
- break;
+ if (td_io_prep(td, io_u)) {
+ put_io_u(td, io_u);
+ break;
+ }
+ } else {
+ io_u = get_io_u(td);
+ if (!io_u)
+ break;
+
+ if (io_u->buflen + io_bytes > verify_bytes)
+ break;
}
if (td->o.verify_async)
else
io_u->end_io = verify_io_u;
+ ddir = io_u->ddir;
+
ret = td_io_queue(td, io_u);
switch (ret) {
case FIO_Q_COMPLETED:
io_u->xfer_buflen = io_u->resid;
io_u->xfer_buf += bytes;
io_u->offset += bytes;
+ io_bytes += bytes;
if (ddir_rw(io_u->ddir))
td->ts.short_io_u[io_u->ddir]++;
if (ret < 0)
break;
}
+ io_bytes += io_u->xfer_buflen;
continue;
case FIO_Q_QUEUED:
break;
break;
}
- if (break_on_this_error(td, io_u->ddir, &ret))
+ if (break_on_this_error(td, ddir, &ret))
break;
/*
min_events = 1;
do {
+ unsigned long bytes = 0;
+
/*
* Reap required number of io units, if any,
* and do the verification on them through
* the callback handler
*/
- if (io_u_queued_complete(td, min_events, NULL) < 0) {
+ if (io_u_queued_complete(td, min_events, &bytes) < 0) {
ret = -1;
break;
}
+ io_bytes += bytes;
} while (full && (td->cur_depth > td->o.iodepth_low));
}
if (ret < 0)
io_u = flist_entry(entry, struct io_u, list);
flist_del(&io_u->list);
+
+ if (td->io_ops->io_u_free)
+ td->io_ops->io_u_free(td, io_u);
+
fio_memfree(io_u, sizeof(*io_u));
}
io_u->index = i;
io_u->flags = IO_U_F_FREE;
flist_add(&io_u->list, &td->io_u_freelist);
+
+ if (td->io_ops->io_u_init) {
+ int ret = td->io_ops->io_u_init(td, io_u);
+
+ if (ret) {
+ log_err("fio: failed to init engine data: %d\n", ret);
+ return 1;
+ }
+ }
+
p += max_bs;
}
} else
td->pid = gettid();
+ fio_local_clock_init(td->o.use_thread);
+
dprint(FD_PROCESS, "jobs pid=%d started\n", (int) td->pid);
INIT_FLIST_HEAD(&td->io_u_freelist);
INIT_FLIST_HEAD(&td->io_hist_list);
INIT_FLIST_HEAD(&td->verify_list);
INIT_FLIST_HEAD(&td->trim_list);
+ INIT_FLIST_HEAD(&td->next_rand_list);
pthread_mutex_init(&td->io_u_lock, NULL);
td->io_hist_tree = RB_ROOT;
goto err;
}
-#ifdef FIO_HAVE_LIBNUMA
+#ifdef CONFIG_LIBNUMA
/* numa node setup */
if (td->o.numa_cpumask_set || td->o.numa_memmask_set) {
int ret;
clear_state = 0;
while (keep_running(td)) {
+ uint64_t write_bytes;
+
fio_gettime(&td->start, NULL);
memcpy(&td->bw_sample_time, &td->start, sizeof(td->start));
memcpy(&td->iops_sample_time, &td->start, sizeof(td->start));
prune_io_piece_log(td);
+ write_bytes = td->io_bytes[DDIR_WRITE];
do_io(td);
+ write_bytes = td->io_bytes[DDIR_WRITE] - write_bytes;
clear_state = 1;
fio_gettime(&td->start, NULL);
- do_verify(td);
+ do_verify(td, write_bytes);
td->ts.runtime[DDIR_READ] += utime_since_now(&td->start);
verify_async_exit(td);
close_and_free_files(td);
- close_ioengine(td);
cleanup_io_u(td);
+ close_ioengine(td);
cgroup_shutdown(td, &cgroup_mnt);
if (td->o.cpumask_set) {
if (WIFSIGNALED(status)) {
int sig = WTERMSIG(status);
- if (sig != SIGTERM)
+ if (sig != SIGTERM && sig != SIGUSR2)
log_err("fio: pid=%d, got signal=%d\n",
(int) td->pid, sig);
td->sig = sig;