ioengines.c revision 5ec10eaad3b09875b91e19a20bbdfa06f2117562
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) {
265ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe		log_err("bad ioops version %d (want %d)\n", ops->version,
275ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe							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;
415ec10eaad3b09875b91e19a20bbdfa06f2117562Jens 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	}
545ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe
558c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	return 0;
568c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe}
578c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
585f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboevoid unregister_ioengine(struct ioengine_ops *ops)
59ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe{
60ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	dprint(FD_IO, "ioengine %s unregistered\n", ops->name);
615f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	list_del(&ops->list);
625f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	INIT_LIST_HEAD(&ops->list);
635f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe}
645f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
65b2fdda43cf0699f60e711429c778ff1685e30062Jens Axboevoid register_ioengine(struct ioengine_ops *ops)
665f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe{
67ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	dprint(FD_IO, "ioengine %s registered\n", ops->name);
685f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	INIT_LIST_HEAD(&ops->list);
695f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	list_add_tail(&ops->list, &engine_list);
705f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe}
715f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
725f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboestatic struct ioengine_ops *find_ioengine(const char *name)
735f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe{
745f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	struct ioengine_ops *ops;
755f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	struct list_head *entry;
76ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe
775f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	list_for_each(entry, &engine_list) {
785f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		ops = list_entry(entry, struct ioengine_ops, list);
79bc5b77a8c46aabea554c4a2c8cca37f27f97969aJens Axboe		if (!strcmp(name, ops->name))
805f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe			return ops;
815f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	}
825f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
835f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	return NULL;
845f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe}
855f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
865f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboestatic struct ioengine_ops *dlopen_ioengine(struct thread_data *td,
875f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe					    const char *engine_lib)
885f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe{
895f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	struct ioengine_ops *ops;
905f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	void *dlhandle;
915f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
92ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	dprint(FD_IO, "dload engine %s\n", engine_lib);
93ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe
942866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe	dlerror();
952866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe	dlhandle = dlopen(engine_lib, RTLD_LAZY);
96d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe	if (!dlhandle) {
97e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_vmsg(td, -1, dlerror(), "dlopen");
98d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe		return NULL;
99d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe	}
1008756e4d421722eaeb089067aeaaf317d05d53a57Jens Axboe
101da51c0505c753f64ad5f65808377b8f67b445828Jens Axboe	/*
102da51c0505c753f64ad5f65808377b8f67b445828Jens Axboe	 * Unlike the included modules, external engines should have a
103da51c0505c753f64ad5f65808377b8f67b445828Jens Axboe	 * non-static ioengine structure that we can reference.
104da51c0505c753f64ad5f65808377b8f67b445828Jens Axboe	 */
1052866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe	ops = dlsym(dlhandle, "ioengine");
106d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe	if (!ops) {
107e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_vmsg(td, -1, dlerror(), "dlsym");
108d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe		dlclose(dlhandle);
109d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe		return NULL;
110d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe	}
1118756e4d421722eaeb089067aeaaf317d05d53a57Jens Axboe
1125f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	ops->dlhandle = dlhandle;
1135f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	return ops;
1145f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe}
1155f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
1165f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboestruct ioengine_ops *load_ioengine(struct thread_data *td, const char *name)
1175f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe{
1185f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	struct ioengine_ops *ops, *ret;
1195f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	char engine[16];
1205f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
121ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	dprint(FD_IO, "load ioengine %s\n", name);
122ee56ad500f6692381e131cc37299d23fa910a24aJens 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{
155ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	dprint(FD_IO, "close ioengine %s\n", td->io_ops->name);
156ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe
1572866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe	if (td->io_ops->cleanup)
1582866c82d598e30604d8a92723c664ee6ced90fb0Jens Axboe		td->io_ops->cleanup(td);
159b990b5c06801d6d25e3fcc5415efbbe7bb23341eJens Axboe
1605f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (td->io_ops->dlhandle)
1615f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		dlclose(td->io_ops->dlhandle);
1625f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
16384585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	free(td->io_ops);
16484585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	td->io_ops = NULL;
165b990b5c06801d6d25e3fcc5415efbbe7bb23341eJens Axboe}
16610ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
16710ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboeint td_io_prep(struct thread_data *td, struct io_u *io_u)
16810ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe{
169ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	dprint_io_u(io_u, "prep");
1707101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe	fio_ro_check(td, io_u);
1717101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe
1724d4e80f2b4260f2c8b37a8612ce655502a799f7aJens Axboe	lock_file(td, io_u->file, io_u->ddir);
173b2bd2bd96a09540b3add0ec74db2cdb1c145ca33Jens Axboe
1742ba1c290d09af6d630d84a58b97b8032f73bc2ceJens Axboe	if (td->io_ops->prep) {
1752ba1c290d09af6d630d84a58b97b8032f73bc2ceJens Axboe		int ret = td->io_ops->prep(td, io_u);
1762ba1c290d09af6d630d84a58b97b8032f73bc2ceJens Axboe
1772ba1c290d09af6d630d84a58b97b8032f73bc2ceJens Axboe		dprint(FD_IO, "->prep(%p)=%d\n", io_u, ret);
178b2bd2bd96a09540b3add0ec74db2cdb1c145ca33Jens Axboe		if (ret)
1794d4e80f2b4260f2c8b37a8612ce655502a799f7aJens Axboe			unlock_file(td, io_u->file);
1802ba1c290d09af6d630d84a58b97b8032f73bc2ceJens Axboe		return ret;
1812ba1c290d09af6d630d84a58b97b8032f73bc2ceJens Axboe	}
18210ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
18310ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe	return 0;
18410ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe}
18510ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
186e7d2e61694c62b90a2fb84c012b4edcc1973d72cJens Axboeint td_io_getevents(struct thread_data *td, unsigned int min, unsigned int max,
18710ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe		    struct timespec *t)
18810ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe{
189ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	int r = 0;
190face81b280ab94ba5d975739578779157c8b54ceJens Axboe
191ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	if (min > 0 && td->io_ops->commit) {
192ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe		r = td->io_ops->commit(td);
193face81b280ab94ba5d975739578779157c8b54ceJens Axboe		if (r < 0)
194ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe			goto out;
195face81b280ab94ba5d975739578779157c8b54ceJens Axboe	}
19636167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe
197ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	r = 0;
198ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	if (td->io_ops->getevents)
199ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe		r = td->io_ops->getevents(td, min, max, t);
200ee56ad500f6692381e131cc37299d23fa910a24aJens Axboeout:
201ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	dprint(FD_IO, "getevents: %d\n", r);
202ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	return r;
20310ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe}
20410ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
20510ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboeint td_io_queue(struct thread_data *td, struct io_u *io_u)
20610ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe{
2077e77dd026d85253936aef432ba8f3e89b96b805cJens Axboe	int ret;
2087e77dd026d85253936aef432ba8f3e89b96b805cJens Axboe
209ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	dprint_io_u(io_u, "queue");
2107101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe	fio_ro_check(td, io_u);
2117101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe
2120c6e75175bcaf8d05bfa88aa8caa584fbb848b74Jens Axboe	assert((io_u->flags & IO_U_F_FLIGHT) == 0);
2130c6e75175bcaf8d05bfa88aa8caa584fbb848b74Jens Axboe	io_u->flags |= IO_U_F_FLIGHT;
2140c6e75175bcaf8d05bfa88aa8caa584fbb848b74Jens Axboe
2153d7b485f9478ed5d291ec58a16a40781ae3ab4aeJens Axboe	assert(io_u->file->flags & FIO_FILE_OPEN);
2163d7b485f9478ed5d291ec58a16a40781ae3ab4aeJens Axboe
217117868024939609aebd94fff5afacfd29b2f9a6fJens Axboe	io_u->error = 0;
218117868024939609aebd94fff5afacfd29b2f9a6fJens Axboe	io_u->resid = 0;
219117868024939609aebd94fff5afacfd29b2f9a6fJens Axboe
220433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe	if (td->io_ops->flags & FIO_SYNCIO) {
2215aeb77df5d75d1065b339c47afbd882a3c04702eJens Axboe		fio_gettime(&io_u->issue_time, NULL);
2225ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe		memcpy(&td->last_issue, &io_u->issue_time,
2235ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe					sizeof(struct timeval));
22410ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
225433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		/*
226433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		 * for a sync engine, set the timeout upfront
227433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		 */
2285ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe		if (mtime_since(&td->timeout_end, &io_u->issue_time)
2295ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe		    < IO_U_TIMEOUT)
230433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe			io_u_set_timeout(td);
231433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe	}
232433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe
233755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe	if (io_u->ddir != DDIR_SYNC)
234755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe		td->io_issues[io_u->ddir]++;
235755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe
2367e77dd026d85253936aef432ba8f3e89b96b805cJens Axboe	ret = td->io_ops->queue(td, io_u);
2375aeb77df5d75d1065b339c47afbd882a3c04702eJens Axboe
2384d4e80f2b4260f2c8b37a8612ce655502a799f7aJens Axboe	unlock_file(td, io_u->file);
239b2bd2bd96a09540b3add0ec74db2cdb1c145ca33Jens Axboe
240163f849eea2b0ce443825fa510a1cb311092a234Jens Axboe	if (ret != FIO_Q_BUSY)
241163f849eea2b0ce443825fa510a1cb311092a234Jens Axboe		io_u_mark_depth(td, io_u);
242163f849eea2b0ce443825fa510a1cb311092a234Jens Axboe
243eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe	if (ret == FIO_Q_QUEUED) {
244eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe		int r;
245eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe
246cb5ab5121ac4fa62e0ca2612b359f19bfdd30f29Jens Axboe		td->io_u_queued++;
2472dc1bbeb58edc85f2829eed6729862c438ea2353Jens Axboe		if (td->io_u_queued > td->o.iodepth_batch) {
248eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe			r = td_io_commit(td);
249eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe			if (r < 0)
250eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe				return r;
251eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe		}
252eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe	}
253cb5ab5121ac4fa62e0ca2612b359f19bfdd30f29Jens Axboe
254433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe	if ((td->io_ops->flags & FIO_SYNCIO) == 0) {
2555aeb77df5d75d1065b339c47afbd882a3c04702eJens Axboe		fio_gettime(&io_u->issue_time, NULL);
2565ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe		memcpy(&td->last_issue, &io_u->issue_time,
2575ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe				sizeof(struct timeval));
2585aeb77df5d75d1065b339c47afbd882a3c04702eJens Axboe
259433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		/*
260433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		 * async engine, set the timeout here
261433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		 */
262433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe		if (ret == FIO_Q_QUEUED &&
2635ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe		    (mtime_since(&td->timeout_end, &io_u->issue_time)
2645ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe			< IO_U_TIMEOUT)) {
265433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe			io_u_set_timeout(td);
2665ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe		}
267433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe	}
268433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe
2697e77dd026d85253936aef432ba8f3e89b96b805cJens Axboe	return ret;
27010ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe}
2718c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
2728c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboeint td_io_init(struct thread_data *td)
2738c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe{
274eeb121607c2a7f36b0fac17649cb8081d6fd853bJens Axboe	int ret = 0;
2758c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
276eeb121607c2a7f36b0fac17649cb8081d6fd853bJens Axboe	if (td->io_ops->init) {
277eeb121607c2a7f36b0fac17649cb8081d6fd853bJens Axboe		ret = td->io_ops->init(td);
2785ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe		if (ret && td->o.iodepth > 1) {
2795ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe			log_err("fio: io engine init failed. Perhaps try"
2805ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe				" reducing io depth?\n");
2815ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe		}
282eeb121607c2a7f36b0fac17649cb8081d6fd853bJens Axboe	}
283eeb121607c2a7f36b0fac17649cb8081d6fd853bJens Axboe
284eeb121607c2a7f36b0fac17649cb8081d6fd853bJens Axboe	return ret;
2858c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe}
286755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe
287755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboeint td_io_commit(struct thread_data *td)
288755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe{
289ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	dprint(FD_IO, "calling ->commit(), depth %d\n", td->cur_depth);
290ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe
291e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe	if (!td->cur_depth)
292e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		return 0;
293cb5ab5121ac4fa62e0ca2612b359f19bfdd30f29Jens Axboe
294cb5ab5121ac4fa62e0ca2612b359f19bfdd30f29Jens Axboe	td->io_u_queued = 0;
295755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe	if (td->io_ops->commit)
296755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe		return td->io_ops->commit(td);
297755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe
298755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe	return 0;
299755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe}
300b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
301b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboeint td_io_open_file(struct thread_data *td, struct fio_file *f)
302b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{
303413d669320995eaef092c58e67cdb7b500134551Jens Axboe	if (td->io_ops->open_file(td, f)) {
304413d669320995eaef092c58e67cdb7b500134551Jens Axboe		if (td->error == EINVAL && td->o.odirect)
305413d669320995eaef092c58e67cdb7b500134551Jens Axboe			log_err("fio: destination does not support O_DIRECT\n");
3065ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe		if (td->error == EMFILE) {
3075ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe			log_err("fio: try reducing/setting openfiles (failed"
3085ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe				" at %u of %u)\n", td->nr_open_files,
3095ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe							td->o.nr_files);
3105ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe		}
311413d669320995eaef092c58e67cdb7b500134551Jens Axboe
312413d669320995eaef092c58e67cdb7b500134551Jens Axboe		return 1;
313413d669320995eaef092c58e67cdb7b500134551Jens Axboe	}
314413d669320995eaef092c58e67cdb7b500134551Jens Axboe
315661598287ecc3b8987f312cf8403936552ce686aJens Axboe	if (f->filetype == FIO_TYPE_PIPE) {
316661598287ecc3b8987f312cf8403936552ce686aJens Axboe		if (td_random(td)) {
317661598287ecc3b8987f312cf8403936552ce686aJens Axboe			log_err("fio: can't seek on pipes (no random io)\n");
318661598287ecc3b8987f312cf8403936552ce686aJens Axboe			goto err;
319661598287ecc3b8987f312cf8403936552ce686aJens Axboe		}
320661598287ecc3b8987f312cf8403936552ce686aJens Axboe	}
321661598287ecc3b8987f312cf8403936552ce686aJens Axboe
322413d669320995eaef092c58e67cdb7b500134551Jens Axboe	f->last_free_lookup = 0;
323bcdedd0ac6e9413258b608ecb3511867b1a9c534ljzhang,Yaxin Hu,Jianchao Tang	f->last_pos = f->file_offset;
324413d669320995eaef092c58e67cdb7b500134551Jens Axboe	f->flags |= FIO_FILE_OPEN;
325413d669320995eaef092c58e67cdb7b500134551Jens Axboe	f->flags &= ~FIO_FILE_CLOSING;
326413d669320995eaef092c58e67cdb7b500134551Jens Axboe
327413d669320995eaef092c58e67cdb7b500134551Jens Axboe	if (td->io_ops->flags & FIO_DISKLESSIO)
328413d669320995eaef092c58e67cdb7b500134551Jens Axboe		goto done;
329413d669320995eaef092c58e67cdb7b500134551Jens Axboe
330413d669320995eaef092c58e67cdb7b500134551Jens Axboe	if (td->o.invalidate_cache && file_invalidate_cache(td, f))
331413d669320995eaef092c58e67cdb7b500134551Jens Axboe		goto err;
332413d669320995eaef092c58e67cdb7b500134551Jens Axboe
333661598287ecc3b8987f312cf8403936552ce686aJens Axboe	if (td->o.fadvise_hint &&
334661598287ecc3b8987f312cf8403936552ce686aJens Axboe	    (f->filetype == FIO_TYPE_BD || f->filetype == FIO_TYPE_FILE)) {
335413d669320995eaef092c58e67cdb7b500134551Jens Axboe		int flags;
336413d669320995eaef092c58e67cdb7b500134551Jens Axboe
337413d669320995eaef092c58e67cdb7b500134551Jens Axboe		if (td_random(td))
338413d669320995eaef092c58e67cdb7b500134551Jens Axboe			flags = POSIX_FADV_RANDOM;
339413d669320995eaef092c58e67cdb7b500134551Jens Axboe		else
340413d669320995eaef092c58e67cdb7b500134551Jens Axboe			flags = POSIX_FADV_SEQUENTIAL;
341413d669320995eaef092c58e67cdb7b500134551Jens Axboe
342413d669320995eaef092c58e67cdb7b500134551Jens Axboe		if (fadvise(f->fd, f->file_offset, f->io_size, flags) < 0) {
343413d669320995eaef092c58e67cdb7b500134551Jens Axboe			td_verror(td, errno, "fadvise");
344413d669320995eaef092c58e67cdb7b500134551Jens Axboe			goto err;
345413d669320995eaef092c58e67cdb7b500134551Jens Axboe		}
3467bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	}
347a978ba684deb758465a0ccb18a008797636e8054Jens Axboe
348413d669320995eaef092c58e67cdb7b500134551Jens Axboe	if (f->file_map)
349413d669320995eaef092c58e67cdb7b500134551Jens Axboe		memset(f->file_map, 0, f->num_maps * sizeof(long));
350a978ba684deb758465a0ccb18a008797636e8054Jens Axboe
351413d669320995eaef092c58e67cdb7b500134551Jens Axboedone:
352f29b25a370598d387e539c3dcae126274c6cbf4dJens Axboe	log_file(td, f, FIO_LOG_OPEN_FILE);
353413d669320995eaef092c58e67cdb7b500134551Jens Axboe	td->nr_open_files++;
354413d669320995eaef092c58e67cdb7b500134551Jens Axboe	get_file(f);
355413d669320995eaef092c58e67cdb7b500134551Jens Axboe	return 0;
356413d669320995eaef092c58e67cdb7b500134551Jens Axboeerr:
357b284075ab5414220496f396dff038003e57e3047Jens Axboe	if (td->io_ops->close_file)
358b284075ab5414220496f396dff038003e57e3047Jens Axboe		td->io_ops->close_file(td, f);
3597bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	return 1;
360b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}
361b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
3626977bcd0e4ee3faa7ffd8f208e4031bdf906ed88Jens Axboeint td_io_close_file(struct thread_data *td, struct fio_file *f)
363b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{
364f29b25a370598d387e539c3dcae126274c6cbf4dJens Axboe	if (!(f->flags & FIO_FILE_CLOSING))
365f29b25a370598d387e539c3dcae126274c6cbf4dJens Axboe		log_file(td, f, FIO_LOG_CLOSE_FILE);
366f29b25a370598d387e539c3dcae126274c6cbf4dJens Axboe
3670ad920e7f85db1fdc26649be6bc7e584e8c7fdc9Jens Axboe	/*
3680ad920e7f85db1fdc26649be6bc7e584e8c7fdc9Jens Axboe	 * mark as closing, do real close when last io on it has completed
3690ad920e7f85db1fdc26649be6bc7e584e8c7fdc9Jens Axboe	 */
3700ad920e7f85db1fdc26649be6bc7e584e8c7fdc9Jens Axboe	f->flags |= FIO_FILE_CLOSING;
3710ad920e7f85db1fdc26649be6bc7e584e8c7fdc9Jens Axboe
3724d4e80f2b4260f2c8b37a8612ce655502a799f7aJens Axboe	unlock_file_all(td, f);
37329c1349f1840c3f60434c9da602074bc8fde4afeJens Axboe
3746977bcd0e4ee3faa7ffd8f208e4031bdf906ed88Jens Axboe	return put_file(td, f);
375b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}
376