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