static FLIST_HEAD(engine_list);
-static int check_engine_ops(struct ioengine_ops *ops)
+static bool check_engine_ops(struct ioengine_ops *ops)
{
if (ops->version != FIO_IOOPS_VERSION) {
log_err("bad ioops version %d (want %d)\n", ops->version,
FIO_IOOPS_VERSION);
- return 1;
+ return true;
}
if (!ops->queue) {
log_err("%s: no queue handler\n", ops->name);
- return 1;
+ return true;
}
/*
* sync engines only need a ->queue()
*/
if (ops->flags & FIO_SYNCIO)
- return 0;
+ return false;
- if (!ops->event) {
- log_err("%s: no event handler\n", ops->name);
- return 1;
- }
- if (!ops->getevents) {
- log_err("%s: no getevents handler\n", ops->name);
- return 1;
- }
- if (!ops->queue) {
- log_err("%s: no queue handler\n", ops->name);
- return 1;
+ if (!ops->event || !ops->getevents) {
+ log_err("%s: no event/getevents handler\n", ops->name);
+ return true;
}
- return 0;
+ return false;
}
void unregister_ioengine(struct ioengine_ops *ops)
return NULL;
}
- ops->dlhandle = dlhandle;
+ td->io_ops_dlhandle = dlhandle;
return ops;
}
struct ioengine_ops *load_ioengine(struct thread_data *td, const char *name)
{
- struct ioengine_ops *ops, *ret;
- char engine[16];
+ struct ioengine_ops *ops;
+ char engine[64];
dprint(FD_IO, "load ioengine %s\n", name);
+ engine[sizeof(engine) - 1] = '\0';
strncpy(engine, name, sizeof(engine) - 1);
/*
if (check_engine_ops(ops))
return NULL;
- ret = malloc(sizeof(*ret));
- memcpy(ret, ops, sizeof(*ret));
- ret->data = NULL;
-
- return ret;
+ return ops;
}
/*
td->eo = NULL;
}
- if (td->io_ops->dlhandle)
- dlclose(td->io_ops->dlhandle);
+ if (td->io_ops_dlhandle)
+ dlclose(td->io_ops_dlhandle);
- free(td->io_ops);
td->io_ops = NULL;
}
if (td->io_ops->cleanup) {
td->io_ops->cleanup(td);
- td->io_ops->data = NULL;
+ td->io_ops_data = NULL;
}
free_ioengine(td);
int td_io_queue(struct thread_data *td, struct io_u *io_u)
{
+ const enum fio_ddir ddir = acct_ddir(io_u);
+ unsigned long buflen = io_u->xfer_buflen;
int ret;
dprint_io_u(io_u, "queue");
fio_ro_check(td, io_u);
assert((io_u->flags & IO_U_F_FLIGHT) == 0);
- io_u->flags |= IO_U_F_FLIGHT;
+ io_u_set(td, io_u, IO_U_F_FLIGHT);
assert(fio_file_open(io_u->file));
io_u->error = 0;
io_u->resid = 0;
- if (td->io_ops->flags & FIO_SYNCIO) {
+ if (td_ioengine_flagged(td, FIO_SYNCIO)) {
if (fio_fill_issue_time(td))
fio_gettime(&io_u->issue_time, NULL);
sizeof(struct timeval));
}
- if (ddir_rw(acct_ddir(io_u)))
- td->io_issues[acct_ddir(io_u)]++;
+ if (ddir_rw(ddir)) {
+ td->io_issues[ddir]++;
+ td->io_issue_bytes[ddir] += buflen;
+ td->rate_io_issue_bytes[ddir] += buflen;
+ }
ret = td->io_ops->queue(td, io_u);
unlock_file(td, io_u->file);
+ if (ret == FIO_Q_BUSY && ddir_rw(ddir)) {
+ td->io_issues[ddir]--;
+ td->io_issue_bytes[ddir] -= buflen;
+ td->rate_io_issue_bytes[ddir] -= buflen;
+ }
+
/*
* If an error was seen and the io engine didn't propagate it
* back to 'td', do so.
td->o.odirect) {
log_info("fio: first direct IO errored. File system may not "
- "support direct IO, or iomem_align= is bad.\n");
+ "support direct IO, or iomem_align= is bad. Try "
+ "setting direct=0.\n");
}
if (!td->io_ops->commit || io_u->ddir == DDIR_TRIM) {
} else if (ret == FIO_Q_QUEUED) {
int r;
- if (ddir_rw(io_u->ddir)) {
- td->io_u_queued++;
+ td->io_u_queued++;
+
+ if (ddir_rw(io_u->ddir))
td->ts.total_io_u[io_u->ddir]++;
- }
if (td->io_u_queued >= td->o.iodepth_batch) {
r = td_io_commit(td);
}
}
- if ((td->io_ops->flags & FIO_SYNCIO) == 0) {
+ if (!td_ioengine_flagged(td, FIO_SYNCIO)) {
if (fio_fill_issue_time(td))
fio_gettime(&io_u->issue_time, NULL);
td->error = ret;
}
- if (!ret && (td->io_ops->flags & FIO_NOIO))
+ if (!ret && td_ioengine_flagged(td, FIO_NOIO))
td->flags |= TD_F_NOIO;
return ret;
}
}
- if (td->io_ops->flags & FIO_DISKLESSIO)
+ if (td_ioengine_flagged(td, FIO_DISKLESSIO))
goto done;
if (td->o.invalidate_cache && file_invalidate_cache(td, f))
goto err;
}
}
+#ifdef FIO_HAVE_STREAMID
+ if (td->o.fadvise_stream &&
+ (f->filetype == FIO_TYPE_BD || f->filetype == FIO_TYPE_FILE)) {
+ off_t stream = td->o.fadvise_stream;
+
+ if (posix_fadvise(f->fd, stream, f->io_size, POSIX_FADV_STREAMID) < 0) {
+ td_verror(td, errno, "fadvise streamid");
+ goto err;
+ }
+ }
+#endif
#ifdef FIO_OS_DIRECTIO
/*
{
if (td->io_ops->unlink_file)
return td->io_ops->unlink_file(td, f);
- else
- return unlink(f->file_name);
+ else {
+ int ret;
+
+ ret = unlink(f->file_name);
+ if (ret < 0)
+ return errno;
+
+ return 0;
+ }
}
int td_io_get_file_size(struct thread_data *td, struct fio_file *f)