+ return ret;
+}
+
+int td_io_init(struct thread_data *td)
+{
+ int ret = 0;
+
+ if (td->io_ops->init) {
+ ret = td->io_ops->init(td);
+ if (ret && td->o.iodepth > 1) {
+ log_err("fio: io engine init failed. Perhaps try"
+ " reducing io depth?\n");
+ }
+ if (!td->error)
+ td->error = ret;
+ }
+
+ if (!ret && (td->io_ops->flags & FIO_NOIO))
+ td->flags |= TD_F_NOIO;
+
+ return ret;
+}
+
+int td_io_commit(struct thread_data *td)
+{
+ int ret;
+
+ dprint(FD_IO, "calling ->commit(), depth %d\n", td->cur_depth);
+
+ if (!td->cur_depth || !td->io_u_queued)
+ return 0;
+
+ io_u_mark_depth(td, td->io_u_queued);
+
+ if (td->io_ops->commit) {
+ ret = td->io_ops->commit(td);
+ if (ret)
+ td_verror(td, -ret, "io commit");
+ }
+
+ /*
+ * Reflect that events were submitted as async IO requests.
+ */
+ td->io_u_in_flight += td->io_u_queued;
+ td->io_u_queued = 0;
+
+ return 0;
+}
+
+int td_io_open_file(struct thread_data *td, struct fio_file *f)
+{
+ assert(!fio_file_open(f));
+ assert(f->fd == -1);
+
+ if (td->io_ops->open_file(td, f)) {
+ if (td->error == EINVAL && td->o.odirect)
+ log_err("fio: destination does not support O_DIRECT\n");
+ if (td->error == EMFILE) {
+ log_err("fio: try reducing/setting openfiles (failed"
+ " at %u of %u)\n", td->nr_open_files,
+ td->o.nr_files);
+ }
+
+ assert(f->fd == -1);
+ assert(!fio_file_open(f));