ioengines.c revision a978ba684deb758465a0ccb18a008797636e8054
1ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe/*
2ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe * The io parts of the fio tool, includes workers for sync and mmap'ed
3ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe * io, as well as both posix and linux libaio support.
4ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe *
5ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe * sync io is implemented on top of aio.
6ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe *
7ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe * This is not really specific to fio, if the get_io_u/put_io_u and
8ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe * structures was pulled into this as well it would be a perfectly
9ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe * generic io engine that could be used for other projects.
10ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe *
11ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe */
12ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe#include <stdio.h>
13ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe#include <stdlib.h>
14ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe#include <unistd.h>
155c4e1dbc4ec6ee963220c5f4e64a04cd6130dc81Jens Axboe#include <string.h>
162866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe#include <dlfcn.h>
170c6e75175bcaf8d05bfa88aa8caa584fbb848b74Jens Axboe#include <assert.h>
188c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
19ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe#include "fio.h"
20ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe#include "os.h"
21ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe
225f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboestatic LIST_HEAD(engine_list);
235f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
248c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboestatic int check_engine_ops(struct ioengine_ops *ops)
258c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe{
265f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (ops->version != FIO_IOOPS_VERSION) {
275f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		log_err("bad ioops version %d (want %d)\n", ops->version, FIO_IOOPS_VERSION);
285f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		return 1;
295f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	}
305f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
318c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	/*
328c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	 * cpu thread doesn't need to provide anything
338c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	 */
348c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	if (ops->flags & FIO_CPUIO)
358c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe		return 0;
368c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
3736167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	if (!ops->queue) {
3836167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		log_err("%s: no queue handler\n", ops->name);
3936167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		return 1;
4036167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	}
4136167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe
4236167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	/*
4336167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	 * sync engines only need a ->queue()
4436167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	 */
4536167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	if (ops->flags & FIO_SYNCIO)
4636167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		return 0;
4736167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe
488c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	if (!ops->event) {
4936167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		log_err("%s: no event handler\n", ops->name);
508c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe		return 1;
518c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	}
528c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	if (!ops->getevents) {
5336167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		log_err("%s: no getevents handler\n", ops->name);
548c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe		return 1;
558c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	}
568c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	if (!ops->queue) {
5736167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		log_err("%s: no queue handler\n", ops->name);
588c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe		return 1;
598c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	}
608c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
618c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	return 0;
628c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe}
638c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
645f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboevoid unregister_ioengine(struct ioengine_ops *ops)
65ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe{
665f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	list_del(&ops->list);
675f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	INIT_LIST_HEAD(&ops->list);
685f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe}
695f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
70b2fdda43cf0699f60e711429c778ff1685e30062Jens Axboevoid register_ioengine(struct ioengine_ops *ops)
715f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe{
725f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	INIT_LIST_HEAD(&ops->list);
735f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	list_add_tail(&ops->list, &engine_list);
745f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe}
755f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
765f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboestatic struct ioengine_ops *find_ioengine(const char *name)
775f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe{
785f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	struct ioengine_ops *ops;
795f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	struct list_head *entry;
80ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe
815f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	list_for_each(entry, &engine_list) {
825f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		ops = list_entry(entry, struct ioengine_ops, list);
83bc5b77a8c46aabea554c4a2c8cca37f27f97969aJens Axboe		if (!strcmp(name, ops->name))
845f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe			return ops;
855f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	}
865f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
875f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	return NULL;
885f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe}
895f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
905f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboestatic struct ioengine_ops *dlopen_ioengine(struct thread_data *td,
915f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe					    const char *engine_lib)
925f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe{
935f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	struct ioengine_ops *ops;
945f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	void *dlhandle;
955f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
962866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe	dlerror();
972866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe	dlhandle = dlopen(engine_lib, RTLD_LAZY);
98d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe	if (!dlhandle) {
99e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_vmsg(td, -1, dlerror(), "dlopen");
100d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe		return NULL;
101d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe	}
1028756e4d421722eaeb089067aeaaf317d05d53a57Jens Axboe
103da51c0505c753f64ad5f65808377b8f67b445828Jens Axboe	/*
104da51c0505c753f64ad5f65808377b8f67b445828Jens Axboe	 * Unlike the included modules, external engines should have a
105da51c0505c753f64ad5f65808377b8f67b445828Jens Axboe	 * non-static ioengine structure that we can reference.
106da51c0505c753f64ad5f65808377b8f67b445828Jens Axboe	 */
1072866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe	ops = dlsym(dlhandle, "ioengine");
108d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe	if (!ops) {
109e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_vmsg(td, -1, dlerror(), "dlsym");
110d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe		dlclose(dlhandle);
111d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe		return NULL;
112d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe	}
1138756e4d421722eaeb089067aeaaf317d05d53a57Jens Axboe
1145f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	ops->dlhandle = dlhandle;
1155f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	return ops;
1165f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe}
1175f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
1185f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboestruct ioengine_ops *load_ioengine(struct thread_data *td, const char *name)
1195f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe{
1205f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	struct ioengine_ops *ops, *ret;
1215f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	char engine[16];
1225f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
1235f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	strncpy(engine, name, sizeof(engine) - 1);
1245f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
1255f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	/*
1265f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	 * linux libaio has alias names, so convert to what we want
1275f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	 */
1285f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (!strncmp(engine, "linuxaio", 8) || !strncmp(engine, "aio", 3))
1295f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		strcpy(engine, "libaio");
1305f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
1315f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	ops = find_ioengine(engine);
1325f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (!ops)
1335f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		ops = dlopen_ioengine(td, name);
1345f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
1355f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (!ops) {
1365f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		log_err("fio: engine %s not loadable\n", name);
137b902ceb53977a12062c615ab529ca0c3422e3cffJens Axboe		return NULL;
138b902ceb53977a12062c615ab529ca0c3422e3cffJens Axboe	}
139b902ceb53977a12062c615ab529ca0c3422e3cffJens Axboe
1408c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	/*
1418c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	 * Check that the required methods are there.
1428c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	 */
1435f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (check_engine_ops(ops))
1448c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe		return NULL;
1458c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
14684585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	ret = malloc(sizeof(*ret));
14784585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	memcpy(ret, ops, sizeof(*ret));
14884585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	ret->data = NULL;
14984585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe
15084585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	return ret;
1518756e4d421722eaeb089067aeaaf317d05d53a57Jens Axboe}
1528756e4d421722eaeb089067aeaaf317d05d53a57Jens Axboe
1532866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboevoid close_ioengine(struct thread_data *td)
1548756e4d421722eaeb089067aeaaf317d05d53a57Jens Axboe{
1552866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe	if (td->io_ops->cleanup)
1562866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe		td->io_ops->cleanup(td);
157b990b5c06801d6d25e3fcc5415efbbe7bb23341eJens Axboe
1585f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (td->io_ops->dlhandle)
1595f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		dlclose(td->io_ops->dlhandle);
1605f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
16119a98c4140020e82652a835faa6e0eac6173fa18Jens Axboe#if 0
16219a98c4140020e82652a835faa6e0eac6173fa18Jens Axboe	/* we can't do this for threads, so just leak it, it's exiting */
16384585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	free(td->io_ops);
16419a98c4140020e82652a835faa6e0eac6173fa18Jens Axboe#endif
16584585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	td->io_ops = NULL;
166b990b5c06801d6d25e3fcc5415efbbe7bb23341eJens Axboe}
16710ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
16810ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboeint td_io_prep(struct thread_data *td, struct io_u *io_u)
16910ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe{
17036167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	if (td->io_ops->prep)
17136167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		return td->io_ops->prep(td, io_u);
17210ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
17310ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe	return 0;
17410ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe}
17510ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
17610ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboeint td_io_getevents(struct thread_data *td, int min, int max,
17710ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe		    struct timespec *t)
17810ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe{
179face81b280ab94ba5d975739578779157c8b54ceJens Axboe	if (min > 0 && td->io_ops->commit) {
180face81b280ab94ba5d975739578779157c8b54ceJens Axboe		int r = td->io_ops->commit(td);
181face81b280ab94ba5d975739578779157c8b54ceJens Axboe
182face81b280ab94ba5d975739578779157c8b54ceJens Axboe		if (r < 0)
183face81b280ab94ba5d975739578779157c8b54ceJens Axboe			return r;
184face81b280ab94ba5d975739578779157c8b54ceJens Axboe	}
18536167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	if (td->io_ops->getevents)
18636167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		return td->io_ops->getevents(td, min, max, t);
18736167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe
18836167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	return 0;
18910ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe}
19010ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
19110ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboeint td_io_queue(struct thread_data *td, struct io_u *io_u)
19210ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe{
1937e77dd026d85253936aef432ba8f3e89b96b805cJens Axboe	int ret;
1947e77dd026d85253936aef432ba8f3e89b96b805cJens Axboe
1950c6e75175bcaf8d05bfa88aa8caa584fbb848b74Jens Axboe	assert((io_u->flags & IO_U_F_FLIGHT) == 0);
1960c6e75175bcaf8d05bfa88aa8caa584fbb848b74Jens Axboe	io_u->flags |= IO_U_F_FLIGHT;
1970c6e75175bcaf8d05bfa88aa8caa584fbb848b74Jens Axboe
198117868024939609aebd94fff5afacfd29b2f9a6fJens Axboe	io_u->error = 0;
199117868024939609aebd94fff5afacfd29b2f9a6fJens Axboe	io_u->resid = 0;
200117868024939609aebd94fff5afacfd29b2f9a6fJens Axboe
201433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe	if (td->io_ops->flags & FIO_SYNCIO) {
2025aeb77df5d75d1065b339c47afbd882a3c04702eJens Axboe		fio_gettime(&io_u->issue_time, NULL);
20310ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
204433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		/*
205433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		 * for a sync engine, set the timeout upfront
206433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		 */
207433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		if (mtime_since(&td->timeout_end, &io_u->issue_time) < IO_U_TIMEOUT)
208433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe			io_u_set_timeout(td);
209433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe	}
210433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe
211755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe	if (io_u->ddir != DDIR_SYNC)
212755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe		td->io_issues[io_u->ddir]++;
213755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe
2147e77dd026d85253936aef432ba8f3e89b96b805cJens Axboe	ret = td->io_ops->queue(td, io_u);
2155aeb77df5d75d1065b339c47afbd882a3c04702eJens Axboe
216eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe	if (ret == FIO_Q_QUEUED) {
217eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe		int r;
218eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe
219cb5ab5121ac4fa62e0ca2612b359f19bfdd30f29Jens Axboe		td->io_u_queued++;
220eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe		if (td->io_u_queued > td->iodepth_batch) {
221eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe			r = td_io_commit(td);
222eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe			if (r < 0)
223eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe				return r;
224eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe		}
225eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe	}
226cb5ab5121ac4fa62e0ca2612b359f19bfdd30f29Jens Axboe
227433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe	if ((td->io_ops->flags & FIO_SYNCIO) == 0) {
2285aeb77df5d75d1065b339c47afbd882a3c04702eJens Axboe		fio_gettime(&io_u->issue_time, NULL);
2295aeb77df5d75d1065b339c47afbd882a3c04702eJens Axboe
230433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		/*
231433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		 * async engine, set the timeout here
232433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		 */
233433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		if (ret == FIO_Q_QUEUED &&
234433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		    mtime_since(&td->timeout_end, &io_u->issue_time) < IO_U_TIMEOUT)
235433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe			io_u_set_timeout(td);
236433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe	}
237433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe
2387e77dd026d85253936aef432ba8f3e89b96b805cJens Axboe	return ret;
23910ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe}
2408c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
2418c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboeint td_io_init(struct thread_data *td)
2428c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe{
2438c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	if (td->io_ops->init)
2448c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe		return td->io_ops->init(td);
2458c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
2468c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	return 0;
2478c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe}
248755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe
249755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboeint td_io_commit(struct thread_data *td)
250755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe{
251e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe	if (!td->cur_depth)
252e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		return 0;
253cb5ab5121ac4fa62e0ca2612b359f19bfdd30f29Jens Axboe
254cb5ab5121ac4fa62e0ca2612b359f19bfdd30f29Jens Axboe	td->io_u_queued = 0;
255755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe	if (td->io_ops->commit)
256755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe		return td->io_ops->commit(td);
257755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe
258755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe	return 0;
259755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe}
260b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
261b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboeint td_io_open_file(struct thread_data *td, struct fio_file *f)
262b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{
263a978ba684deb758465a0ccb18a008797636e8054Jens Axboe	if (td->io_ops->open_file(td, f))
264a978ba684deb758465a0ccb18a008797636e8054Jens Axboe		return 1;
265b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
266a978ba684deb758465a0ccb18a008797636e8054Jens Axboe	f->last_free_lookup = 0;
267a978ba684deb758465a0ccb18a008797636e8054Jens Axboe	f->last_completed_pos = 0;
268a978ba684deb758465a0ccb18a008797636e8054Jens Axboe	f->last_pos = 0;
269a978ba684deb758465a0ccb18a008797636e8054Jens Axboe	f->open = 1;
270a978ba684deb758465a0ccb18a008797636e8054Jens Axboe
271a978ba684deb758465a0ccb18a008797636e8054Jens Axboe	if (f->file_map)
272a978ba684deb758465a0ccb18a008797636e8054Jens Axboe		memset(f->file_map, 0, f->num_maps * sizeof(long));
273a978ba684deb758465a0ccb18a008797636e8054Jens Axboe
274a978ba684deb758465a0ccb18a008797636e8054Jens Axboe	td->nr_open_files++;
275a978ba684deb758465a0ccb18a008797636e8054Jens Axboe	return 0;
276b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}
277b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
278b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboevoid td_io_close_file(struct thread_data *td, struct fio_file *f)
279b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{
280860a3044085c676632f9832a78133cd9847cbe62Jens Axboe	if (f->open) {
281860a3044085c676632f9832a78133cd9847cbe62Jens Axboe		if (td->io_ops->close_file)
282860a3044085c676632f9832a78133cd9847cbe62Jens Axboe			td->io_ops->close_file(td, f);
283860a3044085c676632f9832a78133cd9847cbe62Jens Axboe		td->nr_open_files--;
284860a3044085c676632f9832a78133cd9847cbe62Jens Axboe		f->open = 0;
285860a3044085c676632f9832a78133cd9847cbe62Jens Axboe	}
286b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}
287