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>
17ecc314ba7c5f02b7e90ac1dfbce1a74cd4e6d6feBruce Cran#include <fcntl.h>
180c6e75175bcaf8d05bfa88aa8caa584fbb848b74Jens Axboe#include <assert.h>
198c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
20ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe#include "fio.h"
217c9b1bce094d58c374b086bbb780c08265623ea4Jens Axboe#include "diskutil.h"
22ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe
2301743ee1718e7ec4b16ae3e53c8f64900c6052ccJens Axboestatic FLIST_HEAD(engine_list);
245f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
258c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboestatic int check_engine_ops(struct ioengine_ops *ops)
268c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe{
275f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (ops->version != FIO_IOOPS_VERSION) {
285ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe		log_err("bad ioops version %d (want %d)\n", ops->version,
295ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe							FIO_IOOPS_VERSION);
305f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		return 1;
315f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	}
325f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
3336167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	if (!ops->queue) {
3436167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		log_err("%s: no queue handler\n", ops->name);
3536167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		return 1;
3636167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	}
3736167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe
3836167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	/*
3936167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	 * sync engines only need a ->queue()
4036167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	 */
4136167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe	if (ops->flags & FIO_SYNCIO)
4236167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		return 0;
435ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe
448c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	if (!ops->event) {
4536167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		log_err("%s: no event handler\n", ops->name);
468c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe		return 1;
478c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	}
488c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	if (!ops->getevents) {
4936167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		log_err("%s: no getevents handler\n", ops->name);
508c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe		return 1;
518c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	}
528c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	if (!ops->queue) {
5336167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe		log_err("%s: no queue handler\n", ops->name);
548c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe		return 1;
558c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	}
565ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe
578c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	return 0;
588c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe}
598c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
605f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboevoid unregister_ioengine(struct ioengine_ops *ops)
61ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe{
62ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	dprint(FD_IO, "ioengine %s unregistered\n", ops->name);
6301743ee1718e7ec4b16ae3e53c8f64900c6052ccJens Axboe	flist_del(&ops->list);
6401743ee1718e7ec4b16ae3e53c8f64900c6052ccJens Axboe	INIT_FLIST_HEAD(&ops->list);
655f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe}
665f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
67b2fdda43cf0699f60e711429c778ff1685e30062Jens Axboevoid register_ioengine(struct ioengine_ops *ops)
685f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe{
69ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	dprint(FD_IO, "ioengine %s registered\n", ops->name);
7001743ee1718e7ec4b16ae3e53c8f64900c6052ccJens Axboe	INIT_FLIST_HEAD(&ops->list);
7101743ee1718e7ec4b16ae3e53c8f64900c6052ccJens Axboe	flist_add_tail(&ops->list, &engine_list);
725f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe}
735f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
745f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboestatic struct ioengine_ops *find_ioengine(const char *name)
755f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe{
765f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	struct ioengine_ops *ops;
7701743ee1718e7ec4b16ae3e53c8f64900c6052ccJens Axboe	struct flist_head *entry;
78ebac4655dd3624f3296ff83be48e0cdc02852f1Jens Axboe
7901743ee1718e7ec4b16ae3e53c8f64900c6052ccJens Axboe	flist_for_each(entry, &engine_list) {
8001743ee1718e7ec4b16ae3e53c8f64900c6052ccJens Axboe		ops = flist_entry(entry, struct ioengine_ops, list);
81bc5b77a8c46aabea554c4a2c8cca37f27f97969aJens Axboe		if (!strcmp(name, ops->name))
825f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe			return ops;
835f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	}
845f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
855f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	return NULL;
865f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe}
875f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
885f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboestatic struct ioengine_ops *dlopen_ioengine(struct thread_data *td,
895f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe					    const char *engine_lib)
905f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe{
915f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	struct ioengine_ops *ops;
925f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	void *dlhandle;
935f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
94ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	dprint(FD_IO, "dload engine %s\n", engine_lib);
95ee56ad500f6692381e131cc37299d23fa910a24aJens 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	 */
1070abea0b7428f930d423640feb4472218b83b8eeaDmitry Monakhov	ops = dlsym(dlhandle, engine_lib);
1080abea0b7428f930d423640feb4472218b83b8eeaDmitry Monakhov	if (!ops)
1090abea0b7428f930d423640feb4472218b83b8eeaDmitry Monakhov		ops = dlsym(dlhandle, "ioengine");
110a8075704d3392fede7bd7cfa394616fa0eed7ae0Daniel Gollub
111a8075704d3392fede7bd7cfa394616fa0eed7ae0Daniel Gollub	/*
112a8075704d3392fede7bd7cfa394616fa0eed7ae0Daniel Gollub	 * For some external engines (like C++ ones) it is not that trivial
113a8075704d3392fede7bd7cfa394616fa0eed7ae0Daniel Gollub	 * to provide a non-static ionengine structure that we can reference.
114a8075704d3392fede7bd7cfa394616fa0eed7ae0Daniel Gollub	 * Instead we call a method which allocates the required ioengine
115a8075704d3392fede7bd7cfa394616fa0eed7ae0Daniel Gollub	 * structure.
116a8075704d3392fede7bd7cfa394616fa0eed7ae0Daniel Gollub	 */
117a8075704d3392fede7bd7cfa394616fa0eed7ae0Daniel Gollub	if (!ops) {
118a8075704d3392fede7bd7cfa394616fa0eed7ae0Daniel Gollub		get_ioengine_t get_ioengine = dlsym(dlhandle, "get_ioengine");
119a8075704d3392fede7bd7cfa394616fa0eed7ae0Daniel Gollub
120a8075704d3392fede7bd7cfa394616fa0eed7ae0Daniel Gollub		if (get_ioengine)
121a8075704d3392fede7bd7cfa394616fa0eed7ae0Daniel Gollub			get_ioengine(&ops);
122a8075704d3392fede7bd7cfa394616fa0eed7ae0Daniel Gollub	}
123a8075704d3392fede7bd7cfa394616fa0eed7ae0Daniel Gollub
124d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe	if (!ops) {
125e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		td_vmsg(td, -1, dlerror(), "dlsym");
126d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe		dlclose(dlhandle);
127d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe		return NULL;
128d4dbaaa821b9d3dd34ca002d1976d4f924a07a47Jens Axboe	}
1298756e4d421722eaeb089067aeaaf317d05d53a57Jens Axboe
1305f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	ops->dlhandle = dlhandle;
1315f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	return ops;
1325f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe}
1335f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
1345f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboestruct ioengine_ops *load_ioengine(struct thread_data *td, const char *name)
1355f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe{
1365f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	struct ioengine_ops *ops, *ret;
1375f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	char engine[16];
1385f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
139ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	dprint(FD_IO, "load ioengine %s\n", name);
140ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe
1415f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	strncpy(engine, name, sizeof(engine) - 1);
1425f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
1435f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	/*
1445f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	 * linux libaio has alias names, so convert to what we want
1455f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	 */
1465f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (!strncmp(engine, "linuxaio", 8) || !strncmp(engine, "aio", 3))
1475f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		strcpy(engine, "libaio");
1485f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
1495f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	ops = find_ioengine(engine);
1505f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (!ops)
1515f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		ops = dlopen_ioengine(td, name);
1525f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
1535f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (!ops) {
1545f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		log_err("fio: engine %s not loadable\n", name);
155b902ceb53977a12062c615ab529ca0c3422e3cffJens Axboe		return NULL;
156b902ceb53977a12062c615ab529ca0c3422e3cffJens Axboe	}
157b902ceb53977a12062c615ab529ca0c3422e3cffJens Axboe
1588c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	/*
1598c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	 * Check that the required methods are there.
1608c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe	 */
1615f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (check_engine_ops(ops))
1628c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe		return NULL;
1638c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
16484585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	ret = malloc(sizeof(*ret));
16584585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	memcpy(ret, ops, sizeof(*ret));
16684585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	ret->data = NULL;
16784585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe
16884585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	return ret;
1698756e4d421722eaeb089067aeaaf317d05d53a57Jens Axboe}
1708756e4d421722eaeb089067aeaaf317d05d53a57Jens Axboe
171de890a1e48d40238dac69f302708dde8719de240Steven Lang/*
172de890a1e48d40238dac69f302708dde8719de240Steven Lang * For cleaning up an ioengine which never made it to init().
173de890a1e48d40238dac69f302708dde8719de240Steven Lang */
174de890a1e48d40238dac69f302708dde8719de240Steven Langvoid free_ioengine(struct thread_data *td)
1758756e4d421722eaeb089067aeaaf317d05d53a57Jens Axboe{
176de890a1e48d40238dac69f302708dde8719de240Steven Lang	dprint(FD_IO, "free ioengine %s\n", td->io_ops->name);
177ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe
178de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (td->eo && td->io_ops->options) {
179de890a1e48d40238dac69f302708dde8719de240Steven Lang		options_free(td->io_ops->options, td->eo);
180de890a1e48d40238dac69f302708dde8719de240Steven Lang		free(td->eo);
181de890a1e48d40238dac69f302708dde8719de240Steven Lang		td->eo = NULL;
1822992b059b8f54ac91e723a8bde629b4d8fed513eJens Axboe	}
183b990b5c06801d6d25e3fcc5415efbbe7bb23341eJens Axboe
1845f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe	if (td->io_ops->dlhandle)
1855f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe		dlclose(td->io_ops->dlhandle);
1865f350952eff89948bfbf1eb6ac4d3d08a9109581Jens Axboe
18784585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	free(td->io_ops);
18884585003d025a38b91749cb0d68f6b5653d1f1a3Jens Axboe	td->io_ops = NULL;
189b990b5c06801d6d25e3fcc5415efbbe7bb23341eJens Axboe}
19010ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
191de890a1e48d40238dac69f302708dde8719de240Steven Langvoid close_ioengine(struct thread_data *td)
192de890a1e48d40238dac69f302708dde8719de240Steven Lang{
193de890a1e48d40238dac69f302708dde8719de240Steven Lang	dprint(FD_IO, "close ioengine %s\n", td->io_ops->name);
194de890a1e48d40238dac69f302708dde8719de240Steven Lang
195de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (td->io_ops->cleanup) {
196de890a1e48d40238dac69f302708dde8719de240Steven Lang		td->io_ops->cleanup(td);
197de890a1e48d40238dac69f302708dde8719de240Steven Lang		td->io_ops->data = NULL;
198de890a1e48d40238dac69f302708dde8719de240Steven Lang	}
199de890a1e48d40238dac69f302708dde8719de240Steven Lang
200de890a1e48d40238dac69f302708dde8719de240Steven Lang	free_ioengine(td);
201de890a1e48d40238dac69f302708dde8719de240Steven Lang}
202de890a1e48d40238dac69f302708dde8719de240Steven Lang
20310ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboeint td_io_prep(struct thread_data *td, struct io_u *io_u)
20410ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe{
205ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	dprint_io_u(io_u, "prep");
2067101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe	fio_ro_check(td, io_u);
2077101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe
2084d4e80f2b4260f2c8b37a8612ce655502a799f7aJens Axboe	lock_file(td, io_u->file, io_u->ddir);
209b2bd2bd96a09540b3add0ec74db2cdb1c145ca33Jens Axboe
2102ba1c290d09af6d630d84a58b97b8032f73bc2ceJens Axboe	if (td->io_ops->prep) {
2112ba1c290d09af6d630d84a58b97b8032f73bc2ceJens Axboe		int ret = td->io_ops->prep(td, io_u);
2122ba1c290d09af6d630d84a58b97b8032f73bc2ceJens Axboe
2132ba1c290d09af6d630d84a58b97b8032f73bc2ceJens Axboe		dprint(FD_IO, "->prep(%p)=%d\n", io_u, ret);
214b2bd2bd96a09540b3add0ec74db2cdb1c145ca33Jens Axboe		if (ret)
2154d4e80f2b4260f2c8b37a8612ce655502a799f7aJens Axboe			unlock_file(td, io_u->file);
2162ba1c290d09af6d630d84a58b97b8032f73bc2ceJens Axboe		return ret;
2172ba1c290d09af6d630d84a58b97b8032f73bc2ceJens Axboe	}
21810ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
21910ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe	return 0;
22010ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe}
22110ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
222e7d2e61694c62b90a2fb84c012b4edcc1973d72cJens Axboeint td_io_getevents(struct thread_data *td, unsigned int min, unsigned int max,
22310ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe		    struct timespec *t)
22410ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe{
225ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	int r = 0;
226face81b280ab94ba5d975739578779157c8b54ceJens Axboe
227a05d62b28f18e37256f2698106169b1177708cc1Yufei Ren	/*
228a05d62b28f18e37256f2698106169b1177708cc1Yufei Ren	 * For ioengine=rdma one side operation RDMA_WRITE or RDMA_READ,
229a05d62b28f18e37256f2698106169b1177708cc1Yufei Ren	 * server side gets a message from the client
230a05d62b28f18e37256f2698106169b1177708cc1Yufei Ren	 * side that the task is finished, and
231a05d62b28f18e37256f2698106169b1177708cc1Yufei Ren	 * td->done is set to 1 after td_io_commit(). In this case,
232a05d62b28f18e37256f2698106169b1177708cc1Yufei Ren	 * there is no need to reap complete event in server side.
233a05d62b28f18e37256f2698106169b1177708cc1Yufei Ren	 */
234a05d62b28f18e37256f2698106169b1177708cc1Yufei Ren	if (td->done)
235a05d62b28f18e37256f2698106169b1177708cc1Yufei Ren		return 0;
236a05d62b28f18e37256f2698106169b1177708cc1Yufei Ren
237ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	if (min > 0 && td->io_ops->commit) {
238ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe		r = td->io_ops->commit(td);
239face81b280ab94ba5d975739578779157c8b54ceJens Axboe		if (r < 0)
240ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe			goto out;
241face81b280ab94ba5d975739578779157c8b54ceJens Axboe	}
2424950421a7e379ba0ca642390ae4ae7b68e92a42fJens Axboe	if (max > td->cur_depth)
2434950421a7e379ba0ca642390ae4ae7b68e92a42fJens Axboe		max = td->cur_depth;
2444950421a7e379ba0ca642390ae4ae7b68e92a42fJens Axboe	if (min > max)
2454950421a7e379ba0ca642390ae4ae7b68e92a42fJens Axboe		max = min;
24636167d82e5f49dee91c6d2cd426068edee90e36fJens Axboe
247ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	r = 0;
2484950421a7e379ba0ca642390ae4ae7b68e92a42fJens Axboe	if (max && td->io_ops->getevents)
249ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe		r = td->io_ops->getevents(td, min, max, t);
250ee56ad500f6692381e131cc37299d23fa910a24aJens Axboeout:
251422f9e4b57549ce1e163b9c1de71932d9ea24de4Ryan Marchand	if (r >= 0) {
252422f9e4b57549ce1e163b9c1de71932d9ea24de4Ryan Marchand		/*
2533fd9efbc3e986697c68975f5ee629040b35e8cd0Jens Axboe		 * Reflect that our submitted requests were retrieved with
254422f9e4b57549ce1e163b9c1de71932d9ea24de4Ryan Marchand		 * whatever OS async calls are in the underlying engine.
255422f9e4b57549ce1e163b9c1de71932d9ea24de4Ryan Marchand		 */
256422f9e4b57549ce1e163b9c1de71932d9ea24de4Ryan Marchand		td->io_u_in_flight -= r;
257838bc709279964bdcc64070d4eb2777a0f79bcbbJens Axboe		io_u_mark_complete(td, r);
258422f9e4b57549ce1e163b9c1de71932d9ea24de4Ryan Marchand	} else
2597c639b1495d2776afbf66f91accff1e6000aa8f0Jens Axboe		td_verror(td, r, "get_events");
260f3e11d0575df5b93cd09f8658964e1fb5d38a774Jens Axboe
261ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	dprint(FD_IO, "getevents: %d\n", r);
262ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	return r;
26310ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe}
26410ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe
26510ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboeint td_io_queue(struct thread_data *td, struct io_u *io_u)
26610ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe{
2677e77dd026d85253936aef432ba8f3e89b96b805cJens Axboe	int ret;
2687e77dd026d85253936aef432ba8f3e89b96b805cJens Axboe
269ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	dprint_io_u(io_u, "queue");
2707101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe	fio_ro_check(td, io_u);
2717101d9c24abec4be58a086d85d6d92ec6e6492e9Jens Axboe
2720c6e75175bcaf8d05bfa88aa8caa584fbb848b74Jens Axboe	assert((io_u->flags & IO_U_F_FLIGHT) == 0);
2730c6e75175bcaf8d05bfa88aa8caa584fbb848b74Jens Axboe	io_u->flags |= IO_U_F_FLIGHT;
2740c6e75175bcaf8d05bfa88aa8caa584fbb848b74Jens Axboe
275d6aed795f2e3e403828abf60874dd2d6e8342a1bJens Axboe	assert(fio_file_open(io_u->file));
2763d7b485f9478ed5d291ec58a16a40781ae3ab4aeJens Axboe
277bcd5abfa9f230bbe4365dad1289fdea1f5509f74Jens Axboe	/*
278bcd5abfa9f230bbe4365dad1289fdea1f5509f74Jens Axboe	 * If using a write iolog, store this entry.
279bcd5abfa9f230bbe4365dad1289fdea1f5509f74Jens Axboe	 */
280bcd5abfa9f230bbe4365dad1289fdea1f5509f74Jens Axboe	log_io_u(td, io_u);
281bcd5abfa9f230bbe4365dad1289fdea1f5509f74Jens Axboe
282117868024939609aebd94fff5afacfd29b2f9a6fJens Axboe	io_u->error = 0;
283117868024939609aebd94fff5afacfd29b2f9a6fJens Axboe	io_u->resid = 0;
284117868024939609aebd94fff5afacfd29b2f9a6fJens Axboe
285433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe	if (td->io_ops->flags & FIO_SYNCIO) {
28612d9d841526ad75a67bb43a90edeefd05f85f11eJens Axboe		if (fio_fill_issue_time(td))
2879520ebb9f4dd88d086e313ae97e37ebb6d4f240bJens Axboe			fio_gettime(&io_u->issue_time, NULL);
288d0c153284c1e6505e711c71e6412e6fef02853b8Jens Axboe
289d0c153284c1e6505e711c71e6412e6fef02853b8Jens Axboe		/*
290d0c153284c1e6505e711c71e6412e6fef02853b8Jens Axboe		 * only used for iolog
291d0c153284c1e6505e711c71e6412e6fef02853b8Jens Axboe		 */
292d0c153284c1e6505e711c71e6412e6fef02853b8Jens Axboe		if (td->o.read_iolog_file)
293d0c153284c1e6505e711c71e6412e6fef02853b8Jens Axboe			memcpy(&td->last_issue, &io_u->issue_time,
2945ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe					sizeof(struct timeval));
295433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe	}
296433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe
297bcd5abfa9f230bbe4365dad1289fdea1f5509f74Jens Axboe	if (ddir_rw(acct_ddir(io_u)))
298bcd5abfa9f230bbe4365dad1289fdea1f5509f74Jens Axboe		td->io_issues[acct_ddir(io_u)]++;
299755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe
3007e77dd026d85253936aef432ba8f3e89b96b805cJens Axboe	ret = td->io_ops->queue(td, io_u);
3015aeb77df5d75d1065b339c47afbd882a3c04702eJens Axboe
3024d4e80f2b4260f2c8b37a8612ce655502a799f7aJens Axboe	unlock_file(td, io_u->file);
303b2bd2bd96a09540b3add0ec74db2cdb1c145ca33Jens Axboe
304cb21168269d746d80d82f28ed4db65c2750a8fd7Jens Axboe	/*
30539a43d34f168d1921819f0a1f9b2f9800e68aaa1Jens Axboe	 * If an error was seen and the io engine didn't propagate it
30639a43d34f168d1921819f0a1f9b2f9800e68aaa1Jens Axboe	 * back to 'td', do so.
30739a43d34f168d1921819f0a1f9b2f9800e68aaa1Jens Axboe	 */
30839a43d34f168d1921819f0a1f9b2f9800e68aaa1Jens Axboe	if (io_u->error && !td->error)
30939a43d34f168d1921819f0a1f9b2f9800e68aaa1Jens Axboe		td_verror(td, io_u->error, "td_io_queue");
31039a43d34f168d1921819f0a1f9b2f9800e68aaa1Jens Axboe
31139a43d34f168d1921819f0a1f9b2f9800e68aaa1Jens Axboe	/*
312cb21168269d746d80d82f28ed4db65c2750a8fd7Jens Axboe	 * Add warning for O_DIRECT so that users have an easier time
313cb21168269d746d80d82f28ed4db65c2750a8fd7Jens Axboe	 * spotting potentially bad alignment. If this triggers for the first
314cb21168269d746d80d82f28ed4db65c2750a8fd7Jens Axboe	 * IO, then it's likely an alignment problem or because the host fs
315cb21168269d746d80d82f28ed4db65c2750a8fd7Jens Axboe	 * does not support O_DIRECT
316cb21168269d746d80d82f28ed4db65c2750a8fd7Jens Axboe	 */
317ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe	if (io_u->error == EINVAL && td->io_issues[io_u->ddir & 1] == 1 &&
318cb21168269d746d80d82f28ed4db65c2750a8fd7Jens Axboe	    td->o.odirect) {
319214ac7e009897f8f82ab9e21aff9bc86d33bb470Dan Ehrenberg
320cb21168269d746d80d82f28ed4db65c2750a8fd7Jens Axboe		log_info("fio: first direct IO errored. File system may not "
321cb21168269d746d80d82f28ed4db65c2750a8fd7Jens Axboe			 "support direct IO, or iomem_align= is bad.\n");
322cb21168269d746d80d82f28ed4db65c2750a8fd7Jens Axboe	}
323cb21168269d746d80d82f28ed4db65c2750a8fd7Jens Axboe
3246eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li	if (!td->io_ops->commit || ddir_trim(io_u->ddir)) {
325838bc709279964bdcc64070d4eb2777a0f79bcbbJens Axboe		io_u_mark_submit(td, 1);
326838bc709279964bdcc64070d4eb2777a0f79bcbbJens Axboe		io_u_mark_complete(td, 1);
327838bc709279964bdcc64070d4eb2777a0f79bcbbJens Axboe	}
328838bc709279964bdcc64070d4eb2777a0f79bcbbJens Axboe
329d8005759746a2cb5c8269201911b1997aa714e80Jens Axboe	if (ret == FIO_Q_COMPLETED) {
330ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe		if (ddir_rw(io_u->ddir)) {
331d8005759746a2cb5c8269201911b1997aa714e80Jens Axboe			io_u_mark_depth(td, 1);
332d8005759746a2cb5c8269201911b1997aa714e80Jens Axboe			td->ts.total_io_u[io_u->ddir]++;
3336eaf09d6e9ca1f8accb057cdb18620b7e53ae33fShaohua Li		}
334d8005759746a2cb5c8269201911b1997aa714e80Jens Axboe	} else if (ret == FIO_Q_QUEUED) {
335eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe		int r;
336eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe
337ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe		if (ddir_rw(io_u->ddir)) {
338d8005759746a2cb5c8269201911b1997aa714e80Jens Axboe			td->io_u_queued++;
339d8005759746a2cb5c8269201911b1997aa714e80Jens Axboe			td->ts.total_io_u[io_u->ddir]++;
340d8005759746a2cb5c8269201911b1997aa714e80Jens Axboe		}
341d8005759746a2cb5c8269201911b1997aa714e80Jens Axboe
342d8005759746a2cb5c8269201911b1997aa714e80Jens Axboe		if (td->io_u_queued >= td->o.iodepth_batch) {
343eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe			r = td_io_commit(td);
344eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe			if (r < 0)
345eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe				return r;
346eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe		}
347eb7c8ae27bc301b77490b3586dd5ccab7c95880aJens Axboe	}
348cb5ab5121ac4fa62e0ca2612b359f19bfdd30f29Jens Axboe
349433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe	if ((td->io_ops->flags & FIO_SYNCIO) == 0) {
35012d9d841526ad75a67bb43a90edeefd05f85f11eJens Axboe		if (fio_fill_issue_time(td))
3519520ebb9f4dd88d086e313ae97e37ebb6d4f240bJens Axboe			fio_gettime(&io_u->issue_time, NULL);
352d0c153284c1e6505e711c71e6412e6fef02853b8Jens Axboe
353d0c153284c1e6505e711c71e6412e6fef02853b8Jens Axboe		/*
354d0c153284c1e6505e711c71e6412e6fef02853b8Jens Axboe		 * only used for iolog
355d0c153284c1e6505e711c71e6412e6fef02853b8Jens Axboe		 */
356d0c153284c1e6505e711c71e6412e6fef02853b8Jens Axboe		if (td->o.read_iolog_file)
357d0c153284c1e6505e711c71e6412e6fef02853b8Jens Axboe			memcpy(&td->last_issue, &io_u->issue_time,
358d0c153284c1e6505e711c71e6412e6fef02853b8Jens Axboe					sizeof(struct timeval));
359433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe	}
360433afcb4fe81e775c15af9d39a6f4db8a53d693aJens Axboe
3617e77dd026d85253936aef432ba8f3e89b96b805cJens Axboe	return ret;
36210ba535a5cbb95b5576e33a6f8af093a6ca3bfd7Jens Axboe}
3638c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
3648c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboeint td_io_init(struct thread_data *td)
3658c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe{
366eeb121607c2a7f36b0fac17649cb8081d6fd853bJens Axboe	int ret = 0;
3678c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe
368eeb121607c2a7f36b0fac17649cb8081d6fd853bJens Axboe	if (td->io_ops->init) {
369eeb121607c2a7f36b0fac17649cb8081d6fd853bJens Axboe		ret = td->io_ops->init(td);
3705ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe		if (ret && td->o.iodepth > 1) {
3715ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe			log_err("fio: io engine init failed. Perhaps try"
3725ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe				" reducing io depth?\n");
3735ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe		}
3747c973896f9e97f7b551bf4881fc0338b748f308bJens Axboe		if (!td->error)
3757c973896f9e97f7b551bf4881fc0338b748f308bJens Axboe			td->error = ret;
376eeb121607c2a7f36b0fac17649cb8081d6fd853bJens Axboe	}
377eeb121607c2a7f36b0fac17649cb8081d6fd853bJens Axboe
378046395d7ab181288d14737c1d0041e98328f473fJens Axboe	if (!ret && (td->io_ops->flags & FIO_NOIO))
379046395d7ab181288d14737c1d0041e98328f473fJens Axboe		td->flags |= TD_F_NOIO;
380046395d7ab181288d14737c1d0041e98328f473fJens Axboe
381eeb121607c2a7f36b0fac17649cb8081d6fd853bJens Axboe	return ret;
3828c16d840377c1e6fb79f479ee60590a2da5b52eeJens Axboe}
383755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe
384755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboeint td_io_commit(struct thread_data *td)
385755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe{
386f3e11d0575df5b93cd09f8658964e1fb5d38a774Jens Axboe	int ret;
387f3e11d0575df5b93cd09f8658964e1fb5d38a774Jens Axboe
388ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe	dprint(FD_IO, "calling ->commit(), depth %d\n", td->cur_depth);
389ee56ad500f6692381e131cc37299d23fa910a24aJens Axboe
390d8005759746a2cb5c8269201911b1997aa714e80Jens Axboe	if (!td->cur_depth || !td->io_u_queued)
391e1161c325f7866bae879e686d1c673ca32ab09aeJens Axboe		return 0;
392cb5ab5121ac4fa62e0ca2612b359f19bfdd30f29Jens Axboe
3933fd9efbc3e986697c68975f5ee629040b35e8cd0Jens Axboe	io_u_mark_depth(td, td->io_u_queued);
394d8005759746a2cb5c8269201911b1997aa714e80Jens Axboe
395f3e11d0575df5b93cd09f8658964e1fb5d38a774Jens Axboe	if (td->io_ops->commit) {
396f3e11d0575df5b93cd09f8658964e1fb5d38a774Jens Axboe		ret = td->io_ops->commit(td);
397f3e11d0575df5b93cd09f8658964e1fb5d38a774Jens Axboe		if (ret)
398f3e11d0575df5b93cd09f8658964e1fb5d38a774Jens Axboe			td_verror(td, -ret, "io commit");
399f3e11d0575df5b93cd09f8658964e1fb5d38a774Jens Axboe	}
4003fd9efbc3e986697c68975f5ee629040b35e8cd0Jens Axboe
401422f9e4b57549ce1e163b9c1de71932d9ea24de4Ryan Marchand	/*
402422f9e4b57549ce1e163b9c1de71932d9ea24de4Ryan Marchand	 * Reflect that events were submitted as async IO requests.
403422f9e4b57549ce1e163b9c1de71932d9ea24de4Ryan Marchand	 */
404422f9e4b57549ce1e163b9c1de71932d9ea24de4Ryan Marchand	td->io_u_in_flight += td->io_u_queued;
405422f9e4b57549ce1e163b9c1de71932d9ea24de4Ryan Marchand	td->io_u_queued = 0;
406755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe
407755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe	return 0;
408755200a326a33e5e19b16dfd5e013dd98bcf1916Jens Axboe}
409b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
410b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboeint td_io_open_file(struct thread_data *td, struct fio_file *f)
411b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{
41222a57ba81de2c3f458797e9158da760c9e0ea435Jens Axboe	assert(!fio_file_open(f));
41322a57ba81de2c3f458797e9158da760c9e0ea435Jens Axboe	assert(f->fd == -1);
41422a57ba81de2c3f458797e9158da760c9e0ea435Jens Axboe
415413d669320995eaef092c58e67cdb7b500134551Jens Axboe	if (td->io_ops->open_file(td, f)) {
416413d669320995eaef092c58e67cdb7b500134551Jens Axboe		if (td->error == EINVAL && td->o.odirect)
417413d669320995eaef092c58e67cdb7b500134551Jens Axboe			log_err("fio: destination does not support O_DIRECT\n");
4185ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe		if (td->error == EMFILE) {
4195ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe			log_err("fio: try reducing/setting openfiles (failed"
4205ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe				" at %u of %u)\n", td->nr_open_files,
4215ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe							td->o.nr_files);
4225ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe		}
423413d669320995eaef092c58e67cdb7b500134551Jens Axboe
42422a57ba81de2c3f458797e9158da760c9e0ea435Jens Axboe		assert(f->fd == -1);
42522a57ba81de2c3f458797e9158da760c9e0ea435Jens Axboe		assert(!fio_file_open(f));
426413d669320995eaef092c58e67cdb7b500134551Jens Axboe		return 1;
427413d669320995eaef092c58e67cdb7b500134551Jens Axboe	}
428413d669320995eaef092c58e67cdb7b500134551Jens Axboe
42933c48814e08cf961801bf37f759da2748eb3431bJens Axboe	fio_file_reset(td, f);
430d6aed795f2e3e403828abf60874dd2d6e8342a1bJens Axboe	fio_file_set_open(f);
431d6aed795f2e3e403828abf60874dd2d6e8342a1bJens Axboe	fio_file_clear_closing(f);
432c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe	disk_util_inc(f->du);
433d5707a3565e958af566247e2c0acf09e031d8921Jens Axboe
434d5707a3565e958af566247e2c0acf09e031d8921Jens Axboe	td->nr_open_files++;
435d5707a3565e958af566247e2c0acf09e031d8921Jens Axboe	get_file(f);
436d5707a3565e958af566247e2c0acf09e031d8921Jens Axboe
437661598287ecc3b8987f312cf8403936552ce686aJens Axboe	if (f->filetype == FIO_TYPE_PIPE) {
438661598287ecc3b8987f312cf8403936552ce686aJens Axboe		if (td_random(td)) {
439661598287ecc3b8987f312cf8403936552ce686aJens Axboe			log_err("fio: can't seek on pipes (no random io)\n");
440661598287ecc3b8987f312cf8403936552ce686aJens Axboe			goto err;
441661598287ecc3b8987f312cf8403936552ce686aJens Axboe		}
442661598287ecc3b8987f312cf8403936552ce686aJens Axboe	}
443661598287ecc3b8987f312cf8403936552ce686aJens Axboe
444413d669320995eaef092c58e67cdb7b500134551Jens Axboe	if (td->io_ops->flags & FIO_DISKLESSIO)
445413d669320995eaef092c58e67cdb7b500134551Jens Axboe		goto done;
446413d669320995eaef092c58e67cdb7b500134551Jens Axboe
447413d669320995eaef092c58e67cdb7b500134551Jens Axboe	if (td->o.invalidate_cache && file_invalidate_cache(td, f))
448413d669320995eaef092c58e67cdb7b500134551Jens Axboe		goto err;
449413d669320995eaef092c58e67cdb7b500134551Jens Axboe
450661598287ecc3b8987f312cf8403936552ce686aJens Axboe	if (td->o.fadvise_hint &&
451661598287ecc3b8987f312cf8403936552ce686aJens Axboe	    (f->filetype == FIO_TYPE_BD || f->filetype == FIO_TYPE_FILE)) {
452413d669320995eaef092c58e67cdb7b500134551Jens Axboe		int flags;
453413d669320995eaef092c58e67cdb7b500134551Jens Axboe
454413d669320995eaef092c58e67cdb7b500134551Jens Axboe		if (td_random(td))
455413d669320995eaef092c58e67cdb7b500134551Jens Axboe			flags = POSIX_FADV_RANDOM;
456413d669320995eaef092c58e67cdb7b500134551Jens Axboe		else
457413d669320995eaef092c58e67cdb7b500134551Jens Axboe			flags = POSIX_FADV_SEQUENTIAL;
458413d669320995eaef092c58e67cdb7b500134551Jens Axboe
459ecc314ba7c5f02b7e90ac1dfbce1a74cd4e6d6feBruce Cran		if (posix_fadvise(f->fd, f->file_offset, f->io_size, flags) < 0) {
460413d669320995eaef092c58e67cdb7b500134551Jens Axboe			td_verror(td, errno, "fadvise");
461413d669320995eaef092c58e67cdb7b500134551Jens Axboe			goto err;
462413d669320995eaef092c58e67cdb7b500134551Jens Axboe		}
4637bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	}
464a978ba684deb758465a0ccb18a008797636e8054Jens Axboe
465e116f2b90f110334e77741227ad4e4600302c718Jens Axboe#ifdef FIO_OS_DIRECTIO
466e116f2b90f110334e77741227ad4e4600302c718Jens Axboe	/*
467e116f2b90f110334e77741227ad4e4600302c718Jens Axboe	 * Some OS's have a distinct call to mark the file non-buffered,
468e116f2b90f110334e77741227ad4e4600302c718Jens Axboe	 * instead of using O_DIRECT (Solaris)
469e116f2b90f110334e77741227ad4e4600302c718Jens Axboe	 */
470e116f2b90f110334e77741227ad4e4600302c718Jens Axboe	if (td->o.odirect) {
471e116f2b90f110334e77741227ad4e4600302c718Jens Axboe		int ret = fio_set_odirect(f->fd);
472e116f2b90f110334e77741227ad4e4600302c718Jens Axboe
473e116f2b90f110334e77741227ad4e4600302c718Jens Axboe		if (ret) {
474e116f2b90f110334e77741227ad4e4600302c718Jens Axboe			td_verror(td, ret, "fio_set_odirect");
47578e51c7279a93d3f6200d58a72a813c3ba852c2eJens Axboe			log_err("fio: the file system does not seem to support direct IO\n");
476e116f2b90f110334e77741227ad4e4600302c718Jens Axboe			goto err;
477e116f2b90f110334e77741227ad4e4600302c718Jens Axboe		}
478e116f2b90f110334e77741227ad4e4600302c718Jens Axboe	}
479e116f2b90f110334e77741227ad4e4600302c718Jens Axboe#endif
480e116f2b90f110334e77741227ad4e4600302c718Jens Axboe
481413d669320995eaef092c58e67cdb7b500134551Jens Axboedone:
482f29b25a370598d387e539c3dcae126274c6cbf4dJens Axboe	log_file(td, f, FIO_LOG_OPEN_FILE);
483413d669320995eaef092c58e67cdb7b500134551Jens Axboe	return 0;
484413d669320995eaef092c58e67cdb7b500134551Jens Axboeerr:
485c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe	disk_util_dec(f->du);
486b284075ab5414220496f396dff038003e57e3047Jens Axboe	if (td->io_ops->close_file)
487b284075ab5414220496f396dff038003e57e3047Jens Axboe		td->io_ops->close_file(td, f);
4887bb48f84ac78cac1f90e3e04d0220d90d6a64a6bJens Axboe	return 1;
489b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}
490b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe
4916977bcd0e4ee3faa7ffd8f208e4031bdf906ed88Jens Axboeint td_io_close_file(struct thread_data *td, struct fio_file *f)
492b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe{
493d6aed795f2e3e403828abf60874dd2d6e8342a1bJens Axboe	if (!fio_file_closing(f))
494f29b25a370598d387e539c3dcae126274c6cbf4dJens Axboe		log_file(td, f, FIO_LOG_CLOSE_FILE);
495f29b25a370598d387e539c3dcae126274c6cbf4dJens Axboe
4960ad920e7f85db1fdc26649be6bc7e584e8c7fdc9Jens Axboe	/*
4970ad920e7f85db1fdc26649be6bc7e584e8c7fdc9Jens Axboe	 * mark as closing, do real close when last io on it has completed
4980ad920e7f85db1fdc26649be6bc7e584e8c7fdc9Jens Axboe	 */
499d6aed795f2e3e403828abf60874dd2d6e8342a1bJens Axboe	fio_file_set_closing(f);
5000ad920e7f85db1fdc26649be6bc7e584e8c7fdc9Jens Axboe
501c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe	disk_util_dec(f->du);
502cba5243b2e61fb7215706bc6901ed1af0e4666a4Jens Axboe
503cba5243b2e61fb7215706bc6901ed1af0e4666a4Jens Axboe	if (td->o.file_lock_mode != FILE_LOCK_NONE)
504cba5243b2e61fb7215706bc6901ed1af0e4666a4Jens Axboe		unlock_file_all(td, f);
50529c1349f1840c3f60434c9da602074bc8fde4afeJens Axboe
5066977bcd0e4ee3faa7ffd8f208e4031bdf906ed88Jens Axboe	return put_file(td, f);
507b5af82930ccfd7dda6a1b11794efb452eb76d8dcJens Axboe}
508df9c26b10275a631e83e7cc92d5f7384998b2c49Jens Axboe
509df9c26b10275a631e83e7cc92d5f7384998b2c49Jens Axboeint td_io_get_file_size(struct thread_data *td, struct fio_file *f)
510df9c26b10275a631e83e7cc92d5f7384998b2c49Jens Axboe{
511df9c26b10275a631e83e7cc92d5f7384998b2c49Jens Axboe	if (!td->io_ops->get_file_size)
512df9c26b10275a631e83e7cc92d5f7384998b2c49Jens Axboe		return 0;
513df9c26b10275a631e83e7cc92d5f7384998b2c49Jens Axboe
514df9c26b10275a631e83e7cc92d5f7384998b2c49Jens Axboe	return td->io_ops->get_file_size(td, f);
515df9c26b10275a631e83e7cc92d5f7384998b2c49Jens Axboe}
51644f29692cfba246981bb3c1b894333a6d2209f51Jens Axboe
5170a28ecda80a78c9d70ae38ced58f3a2fa9c9529dJens Axboestatic int do_sync_file_range(struct thread_data *td, struct fio_file *f)
51844f29692cfba246981bb3c1b894333a6d2209f51Jens Axboe{
51944f29692cfba246981bb3c1b894333a6d2209f51Jens Axboe	off64_t offset, nbytes;
52044f29692cfba246981bb3c1b894333a6d2209f51Jens Axboe
52144f29692cfba246981bb3c1b894333a6d2209f51Jens Axboe	offset = f->first_write;
52244f29692cfba246981bb3c1b894333a6d2209f51Jens Axboe	nbytes = f->last_write - f->first_write;
52344f29692cfba246981bb3c1b894333a6d2209f51Jens Axboe
5243843deb322eb7b54d2d19d7b1ce19c5dc44d57ffJens Axboe	if (!nbytes)
5253843deb322eb7b54d2d19d7b1ce19c5dc44d57ffJens Axboe		return 0;
52644f29692cfba246981bb3c1b894333a6d2209f51Jens Axboe
5273843deb322eb7b54d2d19d7b1ce19c5dc44d57ffJens Axboe	return sync_file_range(f->fd, offset, nbytes, td->o.sync_file_range);
52844f29692cfba246981bb3c1b894333a6d2209f51Jens Axboe}
5290a28ecda80a78c9d70ae38ced58f3a2fa9c9529dJens Axboe
5300a28ecda80a78c9d70ae38ced58f3a2fa9c9529dJens Axboeint do_io_u_sync(struct thread_data *td, struct io_u *io_u)
5310a28ecda80a78c9d70ae38ced58f3a2fa9c9529dJens Axboe{
5320a28ecda80a78c9d70ae38ced58f3a2fa9c9529dJens Axboe	int ret;
5330a28ecda80a78c9d70ae38ced58f3a2fa9c9529dJens Axboe
5340a28ecda80a78c9d70ae38ced58f3a2fa9c9529dJens Axboe	if (io_u->ddir == DDIR_SYNC) {
5350a28ecda80a78c9d70ae38ced58f3a2fa9c9529dJens Axboe		ret = fsync(io_u->file->fd);
5360a28ecda80a78c9d70ae38ced58f3a2fa9c9529dJens Axboe	} else if (io_u->ddir == DDIR_DATASYNC) {
53767bf982340d95ca98098ea050b54b4c7adb116c0Jens Axboe#ifdef CONFIG_FDATASYNC
5380a28ecda80a78c9d70ae38ced58f3a2fa9c9529dJens Axboe		ret = fdatasync(io_u->file->fd);
5390a28ecda80a78c9d70ae38ced58f3a2fa9c9529dJens Axboe#else
5400a28ecda80a78c9d70ae38ced58f3a2fa9c9529dJens Axboe		ret = io_u->xfer_buflen;
5410a28ecda80a78c9d70ae38ced58f3a2fa9c9529dJens Axboe		io_u->error = EINVAL;
5420a28ecda80a78c9d70ae38ced58f3a2fa9c9529dJens Axboe#endif
5430a28ecda80a78c9d70ae38ced58f3a2fa9c9529dJens Axboe	} else if (io_u->ddir == DDIR_SYNC_FILE_RANGE)
5440a28ecda80a78c9d70ae38ced58f3a2fa9c9529dJens Axboe		ret = do_sync_file_range(td, io_u->file);
5450a28ecda80a78c9d70ae38ced58f3a2fa9c9529dJens Axboe	else {
5460a28ecda80a78c9d70ae38ced58f3a2fa9c9529dJens Axboe		ret = io_u->xfer_buflen;
5470a28ecda80a78c9d70ae38ced58f3a2fa9c9529dJens Axboe		io_u->error = EINVAL;
5480a28ecda80a78c9d70ae38ced58f3a2fa9c9529dJens Axboe	}
5490a28ecda80a78c9d70ae38ced58f3a2fa9c9529dJens Axboe
550cb849a795d2bfd99efdd66f5a3e475c9fb3edd86Jens Axboe	if (ret < 0)
551cb849a795d2bfd99efdd66f5a3e475c9fb3edd86Jens Axboe		io_u->error = errno;
552cb849a795d2bfd99efdd66f5a3e475c9fb3edd86Jens Axboe
5530a28ecda80a78c9d70ae38ced58f3a2fa9c9529dJens Axboe	return ret;
5540a28ecda80a78c9d70ae38ced58f3a2fa9c9529dJens Axboe}
555a5f3027cb0495dfe217b2626d248fcc054e7e878Jens Axboe
556a5f3027cb0495dfe217b2626d248fcc054e7e878Jens Axboeint do_io_u_trim(struct thread_data *td, struct io_u *io_u)
557a5f3027cb0495dfe217b2626d248fcc054e7e878Jens Axboe{
558a5f3027cb0495dfe217b2626d248fcc054e7e878Jens Axboe#ifndef FIO_HAVE_TRIM
559a5f3027cb0495dfe217b2626d248fcc054e7e878Jens Axboe	io_u->error = EINVAL;
560ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe	return 0;
561a5f3027cb0495dfe217b2626d248fcc054e7e878Jens Axboe#else
562a5f3027cb0495dfe217b2626d248fcc054e7e878Jens Axboe	struct fio_file *f = io_u->file;
563a5f3027cb0495dfe217b2626d248fcc054e7e878Jens Axboe	int ret;
564a5f3027cb0495dfe217b2626d248fcc054e7e878Jens Axboe
565c6404a44d139fb494202f9d968f7affe8c3d986fJens Axboe	ret = os_trim(f->fd, io_u->offset, io_u->xfer_buflen);
566a5f3027cb0495dfe217b2626d248fcc054e7e878Jens Axboe	if (!ret)
5673fd9efbc3e986697c68975f5ee629040b35e8cd0Jens Axboe		return io_u->xfer_buflen;
568a5f3027cb0495dfe217b2626d248fcc054e7e878Jens Axboe
569ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe	io_u->error = ret;
570ff58fcede39d16a2c642897cbe5a7f28b2da1950Jens Axboe	return 0;
571a5f3027cb0495dfe217b2626d248fcc054e7e878Jens Axboe#endif
572a5f3027cb0495dfe217b2626d248fcc054e7e878Jens Axboe}
573de890a1e48d40238dac69f302708dde8719de240Steven Lang
574de890a1e48d40238dac69f302708dde8719de240Steven Langint fio_show_ioengine_help(const char *engine)
575de890a1e48d40238dac69f302708dde8719de240Steven Lang{
576de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct flist_head *entry;
577de890a1e48d40238dac69f302708dde8719de240Steven Lang	struct thread_data td;
578de890a1e48d40238dac69f302708dde8719de240Steven Lang	char *sep;
579de890a1e48d40238dac69f302708dde8719de240Steven Lang	int ret = 1;
580de890a1e48d40238dac69f302708dde8719de240Steven Lang
581de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (!engine || !*engine) {
582de890a1e48d40238dac69f302708dde8719de240Steven Lang		log_info("Available IO engines:\n");
583de890a1e48d40238dac69f302708dde8719de240Steven Lang		flist_for_each(entry, &engine_list) {
584de890a1e48d40238dac69f302708dde8719de240Steven Lang			td.io_ops = flist_entry(entry, struct ioengine_ops,
585de890a1e48d40238dac69f302708dde8719de240Steven Lang						list);
586de890a1e48d40238dac69f302708dde8719de240Steven Lang			log_info("\t%s\n", td.io_ops->name);
587de890a1e48d40238dac69f302708dde8719de240Steven Lang		}
588de890a1e48d40238dac69f302708dde8719de240Steven Lang		return 0;
589de890a1e48d40238dac69f302708dde8719de240Steven Lang	}
590de890a1e48d40238dac69f302708dde8719de240Steven Lang	sep = strchr(engine, ',');
591de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (sep) {
592de890a1e48d40238dac69f302708dde8719de240Steven Lang		*sep = 0;
593de890a1e48d40238dac69f302708dde8719de240Steven Lang		sep++;
594de890a1e48d40238dac69f302708dde8719de240Steven Lang	}
595de890a1e48d40238dac69f302708dde8719de240Steven Lang
596de890a1e48d40238dac69f302708dde8719de240Steven Lang	memset(&td, 0, sizeof(td));
597de890a1e48d40238dac69f302708dde8719de240Steven Lang
598de890a1e48d40238dac69f302708dde8719de240Steven Lang	td.io_ops = load_ioengine(&td, engine);
599de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (!td.io_ops) {
600de890a1e48d40238dac69f302708dde8719de240Steven Lang		log_info("IO engine %s not found\n", engine);
601de890a1e48d40238dac69f302708dde8719de240Steven Lang		return 1;
602de890a1e48d40238dac69f302708dde8719de240Steven Lang	}
603de890a1e48d40238dac69f302708dde8719de240Steven Lang
604de890a1e48d40238dac69f302708dde8719de240Steven Lang	if (td.io_ops->options)
605de890a1e48d40238dac69f302708dde8719de240Steven Lang		ret = show_cmd_help(td.io_ops->options, sep);
606de890a1e48d40238dac69f302708dde8719de240Steven Lang	else
607de890a1e48d40238dac69f302708dde8719de240Steven Lang		log_info("IO engine %s has no options\n", td.io_ops->name);
608de890a1e48d40238dac69f302708dde8719de240Steven Lang
609de890a1e48d40238dac69f302708dde8719de240Steven Lang	free_ioengine(&td);
610de890a1e48d40238dac69f302708dde8719de240Steven Lang
611de890a1e48d40238dac69f302708dde8719de240Steven Lang	return ret;
612de890a1e48d40238dac69f302708dde8719de240Steven Lang}
613