ioengines.c revision b3605062146bce0136918763bb8eb584478ae042
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
3136167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	if (!ops->queue) {
3236167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		log_err("%s: no queue handler\n", ops->name);
3336167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		return 1;
3436167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	}
3536167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe
3636167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	/*
3736167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	 * sync engines only need a ->queue()
3836167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	 */
3936167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	if (ops->flags & FIO_SYNCIO)
4036167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		return 0;
4136167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe
428c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	if (!ops->event) {
4336167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		log_err("%s: no event handler\n", ops->name);
448c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe		return 1;
458c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	}
468c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	if (!ops->getevents) {
4736167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		log_err("%s: no getevents handler\n", ops->name);
488c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe		return 1;
498c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	}
508c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	if (!ops->queue) {
5136167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		log_err("%s: no queue handler\n", ops->name);
528c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe		return 1;
538c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	}
548c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
558c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	return 0;
568c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe}
578c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
585f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboevoid unregister_ioengine(struct ioengine_ops *ops)
59ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe{
605f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	list_del(&ops->list);
615f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	INIT_LIST_HEAD(&ops->list);
625f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe}
635f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
64b2fdda43cf0699f60e711429c778ff1685e30062Jens Axboevoid register_ioengine(struct ioengine_ops *ops)
655f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe{
665f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	INIT_LIST_HEAD(&ops->list);
675f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	list_add_tail(&ops->list, &engine_list);
685f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe}
695f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
705f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboestatic struct ioengine_ops *find_ioengine(const char *name)
715f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe{
725f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	struct ioengine_ops *ops;
735f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	struct list_head *entry;
74ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe
755f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	list_for_each(entry, &engine_list) {
765f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		ops = list_entry(entry, struct ioengine_ops, list);
77bc5b77a8c46aabea554c4a2c8cca37f27f97969aJens Axboe		if (!strcmp(name, ops->name))
785f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe			return ops;
795f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	}
805f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
815f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	return NULL;
825f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe}
835f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
845f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboestatic struct ioengine_ops *dlopen_ioengine(struct thread_data *td,
855f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe					    const char *engine_lib)
865f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe{
875f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	struct ioengine_ops *ops;
885f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	void *dlhandle;
895f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
902866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe	dlerror();
912866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe	dlhandle = dlopen(engine_lib, RTLD_LAZY);
92d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe	if (!dlhandle) {
93e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_vmsg(td, -1, dlerror(), "dlopen");
94d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe		return NULL;
95d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe	}
968756e4d421722eaeb089067aeaaf317d05d53a57Jens Axboe
97da51c0505c753f64ad5f65808377b8f67b445828Jens Axboe	/*
98da51c0505c753f64ad5f65808377b8f67b445828Jens Axboe	 * Unlike the included modules, external engines should have a
99da51c0505c753f64ad5f65808377b8f67b445828Jens Axboe	 * non-static ioengine structure that we can reference.
100da51c0505c753f64ad5f65808377b8f67b445828Jens Axboe	 */
1012866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe	ops = dlsym(dlhandle, "ioengine");
102d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe	if (!ops) {
103e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_vmsg(td, -1, dlerror(), "dlsym");
104d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe		dlclose(dlhandle);
105d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe		return NULL;
106d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe	}
1078756e4d421722eaeb089067aeaaf317d05d53a57Jens Axboe
1085f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	ops->dlhandle = dlhandle;
1095f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	return ops;
1105f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe}
1115f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
1125f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboestruct ioengine_ops *load_ioengine(struct thread_data *td, const char *name)
1135f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe{
1145f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	struct ioengine_ops *ops, *ret;
1155f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	char engine[16];
1165f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
1175f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	strncpy(engine, name, sizeof(engine) - 1);
1185f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
1195f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	/*
1205f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	 * linux libaio has alias names, so convert to what we want
1215f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	 */
1225f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (!strncmp(engine, "linuxaio", 8) || !strncmp(engine, "aio", 3))
1235f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		strcpy(engine, "libaio");
1245f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
1255f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	ops = find_ioengine(engine);
1265f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (!ops)
1275f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		ops = dlopen_ioengine(td, name);
1285f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
1295f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (!ops) {
1305f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		log_err("fio: engine %s not loadable\n", name);
131b902ceb53977a12062c615ab529ca0c3422e3cffJens Axboe		return NULL;
132b902ceb53977a12062c615ab529ca0c3422e3cffJens Axboe	}
133b902ceb53977a12062c615ab529ca0c3422e3cffJens Axboe
1348c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	/*
1358c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	 * Check that the required methods are there.
1368c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	 */
1375f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (check_engine_ops(ops))
1388c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe		return NULL;
1398c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
14084585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	ret = malloc(sizeof(*ret));
14184585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	memcpy(ret, ops, sizeof(*ret));
14284585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	ret->data = NULL;
14384585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe
14484585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	return ret;
1458756e4d421722eaeb089067aeaaf317d05d53a57Jens Axboe}
1468756e4d421722eaeb089067aeaaf317d05d53a57Jens Axboe
1472866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboevoid close_ioengine(struct thread_data *td)
1488756e4d421722eaeb089067aeaaf317d05d53a57Jens Axboe{
1492866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe	if (td->io_ops->cleanup)
1502866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe		td->io_ops->cleanup(td);
151b990b5c06801d6d25e3fcc5415efbbe7bb23341eJens Axboe
1525f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (td->io_ops->dlhandle)
1535f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		dlclose(td->io_ops->dlhandle);
1545f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
15584585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	free(td->io_ops);
15684585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	td->io_ops = NULL;
157b990b5c06801d6d25e3fcc5415efbbe7bb23341eJens Axboe}
15810ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
15910ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboeint td_io_prep(struct thread_data *td, struct io_u *io_u)
16010ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe{
16136167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	if (td->io_ops->prep)
16236167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		return td->io_ops->prep(td, io_u);
16310ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
16410ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe	return 0;
16510ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe}
16610ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
16710ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboeint td_io_getevents(struct thread_data *td, int min, int max,
16810ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe		    struct timespec *t)
16910ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe{
170face81b280ab94ba5d975739578779157c8b54ceJens Axboe	if (min > 0 && td->io_ops->commit) {
171face81b280ab94ba5d975739578779157c8b54ceJens Axboe		int r = td->io_ops->commit(td);
172face81b280ab94ba5d975739578779157c8b54ceJens Axboe
173face81b280ab94ba5d975739578779157c8b54ceJens Axboe		if (r < 0)
174face81b280ab94ba5d975739578779157c8b54ceJens Axboe			return r;
175face81b280ab94ba5d975739578779157c8b54ceJens Axboe	}
17636167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	if (td->io_ops->getevents)
17736167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		return td->io_ops->getevents(td, min, max, t);
17836167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe
17936167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	return 0;
18010ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe}
18110ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
18210ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboeint td_io_queue(struct thread_data *td, struct io_u *io_u)
18310ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe{
1847e77dd026d85253936aef432ba8f3e89b96b805cJens Axboe	int ret;
1857e77dd026d85253936aef432ba8f3e89b96b805cJens Axboe
1860c6e75175bcaf8d05bfa88aa8caa584fbb848b74Jens Axboe	assert((io_u->flags & IO_U_F_FLIGHT) == 0);
1870c6e75175bcaf8d05bfa88aa8caa584fbb848b74Jens Axboe	io_u->flags |= IO_U_F_FLIGHT;
1880c6e75175bcaf8d05bfa88aa8caa584fbb848b74Jens Axboe
189117868024939609aebd94fff5afacfd29b2f9a6fJens Axboe	io_u->error = 0;
190117868024939609aebd94fff5afacfd29b2f9a6fJens Axboe	io_u->resid = 0;
191117868024939609aebd94fff5afacfd29b2f9a6fJens Axboe
192433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe	if (td->io_ops->flags & FIO_SYNCIO) {
1935aeb77df5d75d1065b339c47afbd882a3c04702eJens Axboe		fio_gettime(&io_u->issue_time, NULL);
19410ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
195433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		/*
196433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		 * for a sync engine, set the timeout upfront
197433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		 */
198433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		if (mtime_since(&td->timeout_end, &io_u->issue_time) < IO_U_TIMEOUT)
199433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe			io_u_set_timeout(td);
200433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe	}
201433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe
202755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe	if (io_u->ddir != DDIR_SYNC)
203755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe		td->io_issues[io_u->ddir]++;
204755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe
205b3605062146bce0136918763bb8eb584478ae042Jens Axboe	io_u_mark_depth(td, io_u);
206b3605062146bce0136918763bb8eb584478ae042Jens Axboe
2077e77dd026d85253936aef432ba8f3e89b96b805cJens Axboe	ret = td->io_ops->queue(td, io_u);
2085aeb77df5d75d1065b339c47afbd882a3c04702eJens Axboe
209eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe	if (ret == FIO_Q_QUEUED) {
210eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe		int r;
211eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe
212cb5ab5121ac4fa62e0ca2612b359f19bfdd30f29Jens Axboe		td->io_u_queued++;
213eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe		if (td->io_u_queued > td->iodepth_batch) {
214eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe			r = td_io_commit(td);
215eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe			if (r < 0)
216eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe				return r;
217eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe		}
218eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe	}
219cb5ab5121ac4fa62e0ca2612b359f19bfdd30f29Jens Axboe
220433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe	if ((td->io_ops->flags & FIO_SYNCIO) == 0) {
2215aeb77df5d75d1065b339c47afbd882a3c04702eJens Axboe		fio_gettime(&io_u->issue_time, NULL);
2225aeb77df5d75d1065b339c47afbd882a3c04702eJens Axboe
223433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		/*
224433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		 * async engine, set the timeout here
225433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		 */
226433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		if (ret == FIO_Q_QUEUED &&
227433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		    mtime_since(&td->timeout_end, &io_u->issue_time) < IO_U_TIMEOUT)
228433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe			io_u_set_timeout(td);
229433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe	}
230433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe
2317e77dd026d85253936aef432ba8f3e89b96b805cJens Axboe	return ret;
23210ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe}
2338c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
2348c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboeint td_io_init(struct thread_data *td)
2358c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe{
2368c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	if (td->io_ops->init)
2378c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe		return td->io_ops->init(td);
2388c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
2398c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	return 0;
2408c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe}
241755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe
242755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboeint td_io_commit(struct thread_data *td)
243755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe{
244e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe	if (!td->cur_depth)
245e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		return 0;
246cb5ab5121ac4fa62e0ca2612b359f19bfdd30f29Jens Axboe
247cb5ab5121ac4fa62e0ca2612b359f19bfdd30f29Jens Axboe	td->io_u_queued = 0;
248755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe	if (td->io_ops->commit)
249755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe		return td->io_ops->commit(td);
250755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe
251755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe	return 0;
252755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe}
253b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
254b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboeint td_io_open_file(struct thread_data *td, struct fio_file *f)
255b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{
256a978ba684deb758465a0ccb18a008797636e8054Jens Axboe	if (td->io_ops->open_file(td, f))
257a978ba684deb758465a0ccb18a008797636e8054Jens Axboe		return 1;
258b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
259a978ba684deb758465a0ccb18a008797636e8054Jens Axboe	f->last_free_lookup = 0;
260a978ba684deb758465a0ccb18a008797636e8054Jens Axboe	f->last_completed_pos = 0;
261a978ba684deb758465a0ccb18a008797636e8054Jens Axboe	f->last_pos = 0;
262a978ba684deb758465a0ccb18a008797636e8054Jens Axboe	f->open = 1;
263a978ba684deb758465a0ccb18a008797636e8054Jens Axboe
264a978ba684deb758465a0ccb18a008797636e8054Jens Axboe	if (f->file_map)
265a978ba684deb758465a0ccb18a008797636e8054Jens Axboe		memset(f->file_map, 0, f->num_maps * sizeof(long));
266a978ba684deb758465a0ccb18a008797636e8054Jens Axboe
267a978ba684deb758465a0ccb18a008797636e8054Jens Axboe	td->nr_open_files++;
268a978ba684deb758465a0ccb18a008797636e8054Jens Axboe	return 0;
269b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}
270b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
271b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboevoid td_io_close_file(struct thread_data *td, struct fio_file *f)
272b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{
273860a3044085c676632f9832a78133cd9847cbe62Jens Axboe	if (f->open) {
274860a3044085c676632f9832a78133cd9847cbe62Jens Axboe		if (td->io_ops->close_file)
275860a3044085c676632f9832a78133cd9847cbe62Jens Axboe			td->io_ops->close_file(td, f);
276860a3044085c676632f9832a78133cd9847cbe62Jens Axboe		td->nr_open_files--;
277860a3044085c676632f9832a78133cd9847cbe62Jens Axboe		f->open = 0;
278860a3044085c676632f9832a78133cd9847cbe62Jens Axboe	}
279b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}
280