X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=ioengines.c;h=0c631e85e98806921568900f564295fa1e6e4a6e;hp=95013d1daaaa07d9bd26ed2899a81d7fd1b45244;hb=81647a9a229b92635062e0a1ee570997634b7848;hpb=f70afaca743f2971312d9928f069a9ea7daeccf7 diff --git a/ioengines.c b/ioengines.c index 95013d1d..0c631e85 100644 --- a/ioengines.c +++ b/ioengines.c @@ -123,25 +123,31 @@ static struct ioengine_ops *dlopen_ioengine(struct thread_data *td, return ops; } -struct ioengine_ops *load_ioengine(struct thread_data *td, const char *name) +struct ioengine_ops *load_ioengine(struct thread_data *td) { - struct ioengine_ops *ops; - char engine[64]; + struct ioengine_ops *ops = NULL; + const char *name = NULL; - dprint(FD_IO, "load ioengine %s\n", name); + if (strcmp(td->o.ioengine, "external")) { + char engine[64]; - engine[sizeof(engine) - 1] = '\0'; - strncpy(engine, name, sizeof(engine) - 1); + name = td->o.ioengine; + engine[sizeof(engine) - 1] = '\0'; + strncpy(engine, name, sizeof(engine) - 1); - /* - * linux libaio has alias names, so convert to what we want - */ - if (!strncmp(engine, "linuxaio", 8) || !strncmp(engine, "aio", 3)) - strcpy(engine, "libaio"); + /* + * linux libaio has alias names, so convert to what we want + */ + if (!strncmp(engine, "linuxaio", 8) || !strncmp(engine, "aio", 3)) + strcpy(engine, "libaio"); - ops = find_ioengine(engine); - if (!ops) + dprint(FD_IO, "load ioengine %s\n", engine); + ops = find_ioengine(engine); + } else if (td->o.ioengine_so_path) { + name = td->o.ioengine_so_path; ops = dlopen_ioengine(td, name); + } else + log_err("fio: missing external ioengine path\n"); if (!ops) { log_err("fio: engine %s not loadable\n", name); @@ -281,7 +287,7 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u) */ if (td->o.read_iolog_file) memcpy(&td->last_issue, &io_u->issue_time, - sizeof(struct timeval)); + sizeof(io_u->issue_time)); } if (ddir_rw(ddir)) { @@ -356,7 +362,7 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u) */ if (td->o.read_iolog_file) memcpy(&td->last_issue, &io_u->issue_time, - sizeof(struct timeval)); + sizeof(io_u->issue_time)); } return ret; @@ -368,17 +374,17 @@ int td_io_init(struct thread_data *td) if (td->io_ops->init) { ret = td->io_ops->init(td); - if (ret && td->o.iodepth > 1) { - log_err("fio: io engine init failed. Perhaps try" - " reducing io depth?\n"); - } + if (ret) + log_err("fio: io engine %s init failed.%s\n", + td->io_ops->name, + td->o.iodepth > 1 ? + " Perhaps try reducing io depth?" : ""); + else + td->io_ops_init = 1; if (!td->error) td->error = ret; } - if (!ret && td_ioengine_flagged(td, FIO_NOIO)) - td->flags |= TD_F_NOIO; - return ret; } @@ -472,39 +478,32 @@ int td_io_open_file(struct thread_data *td, struct fio_file *f) goto err; } } -#ifdef FIO_HAVE_STREAMID - if (td->o.fadvise_stream && +#ifdef FIO_HAVE_WRITE_HINT + if (fio_option_is_set(&td->o, write_hint) && (f->filetype == FIO_TYPE_BLOCK || f->filetype == FIO_TYPE_FILE)) { - off_t stream = td->o.fadvise_stream; + uint64_t hint = td->o.write_hint; + int cmd; - if (posix_fadvise(f->fd, stream, f->io_size, POSIX_FADV_STREAMID) < 0) { - td_verror(td, errno, "fadvise streamid"); - goto err; - } - } -#endif - -#ifdef FIO_OS_DIRECTIO - /* - * Some OS's have a distinct call to mark the file non-buffered, - * instead of using O_DIRECT (Solaris) - */ - if (td->o.odirect) { - int ret = fio_set_odirect(f->fd); - - if (ret) { - td_verror(td, ret, "fio_set_odirect"); - if (ret == ENOTTY) { /* ENOTTY suggests RAW device or ZFS */ - log_err("fio: doing directIO to RAW devices or ZFS not supported\n"); - } else { - log_err("fio: the file system does not seem to support direct IO\n"); - } + /* + * For direct IO, we just need/want to set the hint on + * the file descriptor. For buffered IO, we need to set + * it on the inode. + */ + if (td->o.odirect) + cmd = F_SET_FILE_RW_HINT; + else + cmd = F_SET_RW_HINT; + if (fcntl(f->fd, cmd, &hint) < 0) { + td_verror(td, errno, "fcntl write hint"); goto err; } } #endif + if (td->o.odirect && !OS_O_DIRECT && fio_set_directio(td, f)) + goto err; + done: log_file(td, f, FIO_LOG_OPEN_FILE); return 0; @@ -556,64 +555,6 @@ int td_io_get_file_size(struct thread_data *td, struct fio_file *f) return td->io_ops->get_file_size(td, f); } -static int do_sync_file_range(const struct thread_data *td, - struct fio_file *f) -{ - off64_t offset, nbytes; - - offset = f->first_write; - nbytes = f->last_write - f->first_write; - - if (!nbytes) - return 0; - - return sync_file_range(f->fd, offset, nbytes, td->o.sync_file_range); -} - -int do_io_u_sync(const struct thread_data *td, struct io_u *io_u) -{ - int ret; - - if (io_u->ddir == DDIR_SYNC) { - ret = fsync(io_u->file->fd); - } else if (io_u->ddir == DDIR_DATASYNC) { -#ifdef CONFIG_FDATASYNC - ret = fdatasync(io_u->file->fd); -#else - ret = io_u->xfer_buflen; - io_u->error = EINVAL; -#endif - } else if (io_u->ddir == DDIR_SYNC_FILE_RANGE) - ret = do_sync_file_range(td, io_u->file); - else { - ret = io_u->xfer_buflen; - io_u->error = EINVAL; - } - - if (ret < 0) - io_u->error = errno; - - return ret; -} - -int do_io_u_trim(const struct thread_data *td, struct io_u *io_u) -{ -#ifndef FIO_HAVE_TRIM - io_u->error = EINVAL; - return 0; -#else - struct fio_file *f = io_u->file; - int ret; - - ret = os_trim(f->fd, io_u->offset, io_u->xfer_buflen); - if (!ret) - return io_u->xfer_buflen; - - io_u->error = ret; - return 0; -#endif -} - int fio_show_ioengine_help(const char *engine) { struct flist_head *entry; @@ -638,7 +579,8 @@ int fio_show_ioengine_help(const char *engine) memset(&td, 0, sizeof(td)); - io_ops = load_ioengine(&td, engine); + td.o.ioengine = (char *)engine; + io_ops = load_ioengine(&td); if (!io_ops) { log_info("IO engine %s not found\n", engine); return 1;