ioengines.c revision 7101d9c24abec4be58a086d85d6d92ec6e6492e9
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
215f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboestatic LIST_HEAD(engine_list);
225f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
238c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboestatic int check_engine_ops(struct ioengine_ops *ops)
248c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe{
255f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (ops->version != FIO_IOOPS_VERSION) {
265f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		log_err("bad ioops version %d (want %d)\n", ops->version, FIO_IOOPS_VERSION);
275f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		return 1;
285f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	}
295f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
3036167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	if (!ops->queue) {
3136167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		log_err("%s: no queue handler\n", ops->name);
3236167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		return 1;
3336167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	}
3436167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe
3536167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	/*
3636167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	 * sync engines only need a ->queue()
3736167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	 */
3836167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	if (ops->flags & FIO_SYNCIO)
3936167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		return 0;
4036167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe
418c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	if (!ops->event) {
4236167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		log_err("%s: no event handler\n", ops->name);
438c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe		return 1;
448c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	}
458c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	if (!ops->getevents) {
4636167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		log_err("%s: no getevents handler\n", ops->name);
478c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe		return 1;
488c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	}
498c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	if (!ops->queue) {
5036167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		log_err("%s: no queue handler\n", ops->name);
518c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe		return 1;
528c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	}
538c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
548c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	return 0;
558c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe}
568c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
575f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboevoid unregister_ioengine(struct ioengine_ops *ops)
58ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe{
595f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	list_del(&ops->list);
605f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	INIT_LIST_HEAD(&ops->list);
615f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe}
625f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
63b2fdda43cf0699f60e711429c778ff1685e30062Jens Axboevoid register_ioengine(struct ioengine_ops *ops)
645f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe{
655f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	INIT_LIST_HEAD(&ops->list);
665f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	list_add_tail(&ops->list, &engine_list);
675f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe}
685f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
695f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboestatic struct ioengine_ops *find_ioengine(const char *name)
705f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe{
715f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	struct ioengine_ops *ops;
725f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	struct list_head *entry;
73ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe
745f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	list_for_each(entry, &engine_list) {
755f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		ops = list_entry(entry, struct ioengine_ops, list);
76bc5b77a8c46aabea554c4a2c8cca37f27f97969aJens Axboe		if (!strcmp(name, ops->name))
775f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe			return ops;
785f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	}
795f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
805f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	return NULL;
815f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe}
825f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
835f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboestatic struct ioengine_ops *dlopen_ioengine(struct thread_data *td,
845f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe					    const char *engine_lib)
855f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe{
865f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	struct ioengine_ops *ops;
875f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	void *dlhandle;
885f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
892866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe	dlerror();
902866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe	dlhandle = dlopen(engine_lib, RTLD_LAZY);
91d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe	if (!dlhandle) {
92e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_vmsg(td, -1, dlerror(), "dlopen");
93d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe		return NULL;
94d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe	}
958756e4d421722eaeb089067aeaaf317d05d53a57Jens Axboe
96da51c0505c753f64ad5f65808377b8f67b445828Jens Axboe	/*
97da51c0505c753f64ad5f65808377b8f67b445828Jens Axboe	 * Unlike the included modules, external engines should have a
98da51c0505c753f64ad5f65808377b8f67b445828Jens Axboe	 * non-static ioengine structure that we can reference.
99da51c0505c753f64ad5f65808377b8f67b445828Jens Axboe	 */
1002866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe	ops = dlsym(dlhandle, "ioengine");
101d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe	if (!ops) {
102e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_vmsg(td, -1, dlerror(), "dlsym");
103d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe		dlclose(dlhandle);
104d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe		return NULL;
105d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe	}
1068756e4d421722eaeb089067aeaaf317d05d53a57Jens Axboe
1075f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	ops->dlhandle = dlhandle;
1085f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	return ops;
1095f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe}
1105f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
1115f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboestruct ioengine_ops *load_ioengine(struct thread_data *td, const char *name)
1125f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe{
1135f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	struct ioengine_ops *ops, *ret;
1145f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	char engine[16];
1155f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
1165f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	strncpy(engine, name, sizeof(engine) - 1);
1175f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
1185f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	/*
1195f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	 * linux libaio has alias names, so convert to what we want
1205f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	 */
1215f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (!strncmp(engine, "linuxaio", 8) || !strncmp(engine, "aio", 3))
1225f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		strcpy(engine, "libaio");
1235f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
1245f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	ops = find_ioengine(engine);
1255f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (!ops)
1265f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		ops = dlopen_ioengine(td, name);
1275f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
1285f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (!ops) {
1295f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		log_err("fio: engine %s not loadable\n", name);
130b902ceb53977a12062c615ab529ca0c3422e3cffJens Axboe		return NULL;
131b902ceb53977a12062c615ab529ca0c3422e3cffJens Axboe	}
132b902ceb53977a12062c615ab529ca0c3422e3cffJens Axboe
1338c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	/*
1348c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	 * Check that the required methods are there.
1358c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	 */
1365f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (check_engine_ops(ops))
1378c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe		return NULL;
1388c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
13984585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	ret = malloc(sizeof(*ret));
14084585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	memcpy(ret, ops, sizeof(*ret));
14184585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	ret->data = NULL;
14284585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe
14384585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	return ret;
1448756e4d421722eaeb089067aeaaf317d05d53a57Jens Axboe}
1458756e4d421722eaeb089067aeaaf317d05d53a57Jens Axboe
1462866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboevoid close_ioengine(struct thread_data *td)
1478756e4d421722eaeb089067aeaaf317d05d53a57Jens Axboe{
1482866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe	if (td->io_ops->cleanup)
1492866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe		td->io_ops->cleanup(td);
150b990b5c06801d6d25e3fcc5415efbbe7bb23341eJens Axboe
1515f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (td->io_ops->dlhandle)
1525f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		dlclose(td->io_ops->dlhandle);
1535f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
15484585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	free(td->io_ops);
15584585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	td->io_ops = NULL;
156b990b5c06801d6d25e3fcc5415efbbe7bb23341eJens Axboe}
15710ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
15810ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboeint td_io_prep(struct thread_data *td, struct io_u *io_u)
15910ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe{
1607101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe	fio_ro_check(td, io_u);
1617101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe
16236167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	if (td->io_ops->prep)
16336167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		return td->io_ops->prep(td, io_u);
16410ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
16510ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe	return 0;
16610ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe}
16710ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
16810ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboeint td_io_getevents(struct thread_data *td, int min, int max,
16910ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe		    struct timespec *t)
17010ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe{
171face81b280ab94ba5d975739578779157c8b54ceJens Axboe	if (min > 0 && td->io_ops->commit) {
172face81b280ab94ba5d975739578779157c8b54ceJens Axboe		int r = td->io_ops->commit(td);
173face81b280ab94ba5d975739578779157c8b54ceJens Axboe
174face81b280ab94ba5d975739578779157c8b54ceJens Axboe		if (r < 0)
175face81b280ab94ba5d975739578779157c8b54ceJens Axboe			return r;
176face81b280ab94ba5d975739578779157c8b54ceJens Axboe	}
17736167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	if (td->io_ops->getevents)
17836167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		return td->io_ops->getevents(td, min, max, t);
17936167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe
18036167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	return 0;
18110ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe}
18210ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
18310ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboeint td_io_queue(struct thread_data *td, struct io_u *io_u)
18410ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe{
1857e77dd026d85253936aef432ba8f3e89b96b805cJens Axboe	int ret;
1867e77dd026d85253936aef432ba8f3e89b96b805cJens Axboe
1877101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe	fio_ro_check(td, io_u);
1887101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe
1890c6e75175bcaf8d05bfa88aa8caa584fbb848b74Jens Axboe	assert((io_u->flags & IO_U_F_FLIGHT) == 0);
1900c6e75175bcaf8d05bfa88aa8caa584fbb848b74Jens Axboe	io_u->flags |= IO_U_F_FLIGHT;
1910c6e75175bcaf8d05bfa88aa8caa584fbb848b74Jens Axboe
1923d7b485f9478ed5d291ec58a16a40781ae3ab4aeJens Axboe	assert(io_u->file->flags & FIO_FILE_OPEN);
1933d7b485f9478ed5d291ec58a16a40781ae3ab4aeJens Axboe
194117868024939609aebd94fff5afacfd29b2f9a6fJens Axboe	io_u->error = 0;
195117868024939609aebd94fff5afacfd29b2f9a6fJens Axboe	io_u->resid = 0;
196117868024939609aebd94fff5afacfd29b2f9a6fJens Axboe
197433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe	if (td->io_ops->flags & FIO_SYNCIO) {
1985aeb77df5d75d1065b339c47afbd882a3c04702eJens Axboe		fio_gettime(&io_u->issue_time, NULL);
199a61eddecca21d19f3f4c297400d6c5d93dc29259Jens Axboe		memcpy(&td->last_issue, &io_u->issue_time, sizeof(struct timeval));
20010ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
201433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		/*
202433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		 * for a sync engine, set the timeout upfront
203433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		 */
204433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		if (mtime_since(&td->timeout_end, &io_u->issue_time) < IO_U_TIMEOUT)
205433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe			io_u_set_timeout(td);
206433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe	}
207433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe
208755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe	if (io_u->ddir != DDIR_SYNC)
209755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe		td->io_issues[io_u->ddir]++;
210755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe
211b3605062146bce0136918763bb8eb584478ae042Jens Axboe	io_u_mark_depth(td, io_u);
212b3605062146bce0136918763bb8eb584478ae042Jens Axboe
2137e77dd026d85253936aef432ba8f3e89b96b805cJens Axboe	ret = td->io_ops->queue(td, io_u);
2145aeb77df5d75d1065b339c47afbd882a3c04702eJens Axboe
215eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe	if (ret == FIO_Q_QUEUED) {
216eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe		int r;
217eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe
218cb5ab5121ac4fa62e0ca2612b359f19bfdd30f29Jens Axboe		td->io_u_queued++;
2192dc1bbeb58edc85f2829eed6729862c438ea2353Jens Axboe		if (td->io_u_queued > td->o.iodepth_batch) {
220eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe			r = td_io_commit(td);
221eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe			if (r < 0)
222eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe				return r;
223eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe		}
224eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe	}
225cb5ab5121ac4fa62e0ca2612b359f19bfdd30f29Jens Axboe
226433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe	if ((td->io_ops->flags & FIO_SYNCIO) == 0) {
2275aeb77df5d75d1065b339c47afbd882a3c04702eJens Axboe		fio_gettime(&io_u->issue_time, NULL);
228a61eddecca21d19f3f4c297400d6c5d93dc29259Jens Axboe		memcpy(&td->last_issue, &io_u->issue_time, sizeof(struct timeval));
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{
243eeb121607c2a7f36b0fac17649cb8081d6fd853bJens Axboe	int ret = 0;
2448c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
245eeb121607c2a7f36b0fac17649cb8081d6fd853bJens Axboe	if (td->io_ops->init) {
246eeb121607c2a7f36b0fac17649cb8081d6fd853bJens Axboe		ret = td->io_ops->init(td);
247eeb121607c2a7f36b0fac17649cb8081d6fd853bJens Axboe		if (ret && td->o.iodepth > 1)
248eeb121607c2a7f36b0fac17649cb8081d6fd853bJens Axboe			log_err("fio: io engine init failed. Perhaps try reducing io dpeth?\n");
249eeb121607c2a7f36b0fac17649cb8081d6fd853bJens Axboe	}
250eeb121607c2a7f36b0fac17649cb8081d6fd853bJens Axboe
251eeb121607c2a7f36b0fac17649cb8081d6fd853bJens Axboe	return ret;
2528c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe}
253755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe
254755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboeint td_io_commit(struct thread_data *td)
255755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe{
256e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe	if (!td->cur_depth)
257e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		return 0;
258cb5ab5121ac4fa62e0ca2612b359f19bfdd30f29Jens Axboe
259cb5ab5121ac4fa62e0ca2612b359f19bfdd30f29Jens Axboe	td->io_u_queued = 0;
260755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe	if (td->io_ops->commit)
261755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe		return td->io_ops->commit(td);
262755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe
263755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe	return 0;
264755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe}
265b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
266b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboeint td_io_open_file(struct thread_data *td, struct fio_file *f)
267b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{
268413d669320995eaef092c58e67cdb7b500134551Jens Axboe	if (td->io_ops->open_file(td, f)) {
269413d669320995eaef092c58e67cdb7b500134551Jens Axboe		if (td->error == EINVAL && td->o.odirect)
270413d669320995eaef092c58e67cdb7b500134551Jens Axboe			log_err("fio: destination does not support O_DIRECT\n");
271413d669320995eaef092c58e67cdb7b500134551Jens Axboe		if (td->error == EMFILE)
272413d669320995eaef092c58e67cdb7b500134551Jens Axboe			log_err("fio: try reducing/setting openfiles (failed at %u of %u)\n", td->nr_open_files, td->o.nr_files);
273413d669320995eaef092c58e67cdb7b500134551Jens Axboe
274413d669320995eaef092c58e67cdb7b500134551Jens Axboe		return 1;
275413d669320995eaef092c58e67cdb7b500134551Jens Axboe	}
276413d669320995eaef092c58e67cdb7b500134551Jens Axboe
277661598287ecc3b8987f312cf8403936552ce686aJens Axboe	if (f->filetype == FIO_TYPE_PIPE) {
278661598287ecc3b8987f312cf8403936552ce686aJens Axboe		if (td_random(td)) {
279661598287ecc3b8987f312cf8403936552ce686aJens Axboe			log_err("fio: can't seek on pipes (no random io)\n");
280661598287ecc3b8987f312cf8403936552ce686aJens Axboe			goto err;
281661598287ecc3b8987f312cf8403936552ce686aJens Axboe		}
282661598287ecc3b8987f312cf8403936552ce686aJens Axboe	}
283661598287ecc3b8987f312cf8403936552ce686aJens Axboe
284413d669320995eaef092c58e67cdb7b500134551Jens Axboe	f->last_free_lookup = 0;
285413d669320995eaef092c58e67cdb7b500134551Jens Axboe	f->last_completed_pos = 0;
286bcdedd0ac6e9413258b608ecb3511867b1a9c534ljzhang,Yaxin Hu,Jianchao Tang	f->last_pos = f->file_offset;
287413d669320995eaef092c58e67cdb7b500134551Jens Axboe	f->flags |= FIO_FILE_OPEN;
288413d669320995eaef092c58e67cdb7b500134551Jens Axboe	f->flags &= ~FIO_FILE_CLOSING;
289413d669320995eaef092c58e67cdb7b500134551Jens Axboe
290413d669320995eaef092c58e67cdb7b500134551Jens Axboe	if (td->io_ops->flags & FIO_DISKLESSIO)
291413d669320995eaef092c58e67cdb7b500134551Jens Axboe		goto done;
292413d669320995eaef092c58e67cdb7b500134551Jens Axboe
293413d669320995eaef092c58e67cdb7b500134551Jens Axboe	if (td->o.invalidate_cache && file_invalidate_cache(td, f))
294413d669320995eaef092c58e67cdb7b500134551Jens Axboe		goto err;
295413d669320995eaef092c58e67cdb7b500134551Jens Axboe
296661598287ecc3b8987f312cf8403936552ce686aJens Axboe	if (td->o.fadvise_hint &&
297661598287ecc3b8987f312cf8403936552ce686aJens Axboe	    (f->filetype == FIO_TYPE_BD || f->filetype == FIO_TYPE_FILE)) {
298661598287ecc3b8987f312cf8403936552ce686aJens Axboe
299413d669320995eaef092c58e67cdb7b500134551Jens Axboe		int flags;
300413d669320995eaef092c58e67cdb7b500134551Jens Axboe
301413d669320995eaef092c58e67cdb7b500134551Jens Axboe		if (td_random(td))
302413d669320995eaef092c58e67cdb7b500134551Jens Axboe			flags = POSIX_FADV_RANDOM;
303413d669320995eaef092c58e67cdb7b500134551Jens Axboe		else
304413d669320995eaef092c58e67cdb7b500134551Jens Axboe			flags = POSIX_FADV_SEQUENTIAL;
305413d669320995eaef092c58e67cdb7b500134551Jens Axboe
306413d669320995eaef092c58e67cdb7b500134551Jens Axboe		if (fadvise(f->fd, f->file_offset, f->io_size, flags) < 0) {
307413d669320995eaef092c58e67cdb7b500134551Jens Axboe			td_verror(td, errno, "fadvise");
308413d669320995eaef092c58e67cdb7b500134551Jens Axboe			goto err;
309413d669320995eaef092c58e67cdb7b500134551Jens Axboe		}
3107bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	}
311a978ba684deb758465a0ccb18a008797636e8054Jens Axboe
312413d669320995eaef092c58e67cdb7b500134551Jens Axboe	if (f->file_map)
313413d669320995eaef092c58e67cdb7b500134551Jens Axboe		memset(f->file_map, 0, f->num_maps * sizeof(long));
314a978ba684deb758465a0ccb18a008797636e8054Jens Axboe
315413d669320995eaef092c58e67cdb7b500134551Jens Axboedone:
316f29b25a370598d387e539c3dcae126274c6cbf4dJens Axboe	log_file(td, f, FIO_LOG_OPEN_FILE);
317413d669320995eaef092c58e67cdb7b500134551Jens Axboe	td->nr_open_files++;
318413d669320995eaef092c58e67cdb7b500134551Jens Axboe	get_file(f);
319413d669320995eaef092c58e67cdb7b500134551Jens Axboe	return 0;
320413d669320995eaef092c58e67cdb7b500134551Jens Axboeerr:
321b284075ab5414220496f396dff038003e57e3047Jens Axboe	if (td->io_ops->close_file)
322b284075ab5414220496f396dff038003e57e3047Jens Axboe		td->io_ops->close_file(td, f);
3237bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	return 1;
324b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}
325b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
326b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboevoid td_io_close_file(struct thread_data *td, struct fio_file *f)
327b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{
328f29b25a370598d387e539c3dcae126274c6cbf4dJens Axboe	if (!(f->flags & FIO_FILE_CLOSING))
329f29b25a370598d387e539c3dcae126274c6cbf4dJens Axboe		log_file(td, f, FIO_LOG_CLOSE_FILE);
330f29b25a370598d387e539c3dcae126274c6cbf4dJens Axboe
3310ad920e7f85db1fdc26649be6bc7e584e8c7fdc9Jens Axboe	/*
3320ad920e7f85db1fdc26649be6bc7e584e8c7fdc9Jens Axboe	 * mark as closing, do real close when last io on it has completed
3330ad920e7f85db1fdc26649be6bc7e584e8c7fdc9Jens Axboe	 */
3340ad920e7f85db1fdc26649be6bc7e584e8c7fdc9Jens Axboe	f->flags |= FIO_FILE_CLOSING;
3350ad920e7f85db1fdc26649be6bc7e584e8c7fdc9Jens Axboe
3360ad920e7f85db1fdc26649be6bc7e584e8c7fdc9Jens Axboe	put_file(td, f);
337b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}
338