/*
 * The io parts of the fio tool, includes workers for sync and mmap'ed
 * io, as well as both posix and linux libaio support.
 *
 * sync io is implemented on top of aio.
 *
 * This is not really specific to fio, if the get_io_u/put_io_u and
 * structures was pulled into this as well it would be a perfectly
 * generic io engine that could be used for other projects.
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <assert.h>

#include "fio.h"
#include "diskutil.h"

static FLIST_HEAD(engine_list);

static int check_engine_ops(struct ioengine_ops *ops)
{
	if (ops->version != FIO_IOOPS_VERSION) {
		log_err("bad ioops version %d (want %d)\n", ops->version,
							FIO_IOOPS_VERSION);
		return 1;
	}

	if (!ops->queue) {
		log_err("%s: no queue handler\n", ops->name);
		return 1;
	}

	/*
	 * sync engines only need a ->queue()
	 */
	if (ops->flags & FIO_SYNCIO)
		return 0;

	if (!ops->event) {
		log_err("%s: no event handler\n", ops->name);
		return 1;
	}
	if (!ops->getevents) {
		log_err("%s: no getevents handler\n", ops->name);
		return 1;
	}
	if (!ops->queue) {
		log_err("%s: no queue handler\n", ops->name);
		return 1;
	}

	return 0;
}

void unregister_ioengine(struct ioengine_ops *ops)
{
	dprint(FD_IO, "ioengine %s unregistered\n", ops->name);
	flist_del(&ops->list);
	INIT_FLIST_HEAD(&ops->list);
}

void register_ioengine(struct ioengine_ops *ops)
{
	dprint(FD_IO, "ioengine %s registered\n", ops->name);
	INIT_FLIST_HEAD(&ops->list);
	flist_add_tail(&ops->list, &engine_list);
}

static struct ioengine_ops *find_ioengine(const char *name)
{
	struct ioengine_ops *ops;
	struct flist_head *entry;

	flist_for_each(entry, &engine_list) {
		ops = flist_entry(entry, struct ioengine_ops, list);
		if (!strcmp(name, ops->name))
			return ops;
	}

	return NULL;
}

static struct ioengine_ops *dlopen_ioengine(struct thread_data *td,
					    const char *engine_lib)
{
	struct ioengine_ops *ops;
	void *dlhandle;

	dprint(FD_IO, "dload engine %s\n", engine_lib);

	dlerror();
	dlhandle = dlopen(engine_lib, RTLD_LAZY);
	if (!dlhandle) {
		td_vmsg(td, -1, dlerror(), "dlopen");
		return NULL;
	}

	/*
	 * Unlike the included modules, external engines should have a
	 * non-static ioengine structure that we can reference.
	 */
	ops = dlsym(dlhandle, engine_lib);
	if (!ops)
		ops = dlsym(dlhandle, "ioengine");
	if (!ops) {
		td_vmsg(td, -1, dlerror(), "dlsym");
		dlclose(dlhandle);
		return NULL;
	}

	ops->dlhandle = dlhandle;
	return ops;
}

struct ioengine_ops *load_ioengine(struct thread_data *td, const char *name)
{
	struct ioengine_ops *ops, *ret;
	char engine[16];

	dprint(FD_IO, "load ioengine %s\n", name);

	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");

	ops = find_ioengine(engine);
	if (!ops)
		ops = dlopen_ioengine(td, name);

	if (!ops) {
		log_err("fio: engine %s not loadable\n", name);
		return NULL;
	}

	/*
	 * Check that the required methods are there.
	 */
	if (check_engine_ops(ops))
		return NULL;

	ret = malloc(sizeof(*ret));
	memcpy(ret, ops, sizeof(*ret));
	ret->data = NULL;

	return ret;
}

/*
 * For cleaning up an ioengine which never made it to init().
 */
void free_ioengine(struct thread_data *td)
{
	dprint(FD_IO, "free ioengine %s\n", td->io_ops->name);

	if (td->eo && td->io_ops->options) {
		options_free(td->io_ops->options, td->eo);
		free(td->eo);
		td->eo = NULL;
	}

	if (td->io_ops->dlhandle)
		dlclose(td->io_ops->dlhandle);

	free(td->io_ops);
	td->io_ops = NULL;
}

void close_ioengine(struct thread_data *td)
{
	dprint(FD_IO, "close ioengine %s\n", td->io_ops->name);

	if (td->io_ops->cleanup) {
		td->io_ops->cleanup(td);
		td->io_ops->data = NULL;
	}

	free_ioengine(td);
}

int td_io_prep(struct thread_data *td, struct io_u *io_u)
{
	dprint_io_u(io_u, "prep");
	fio_ro_check(td, io_u);

	lock_file(td, io_u->file, io_u->ddir);

	if (td->io_ops->prep) {
		int ret = td->io_ops->prep(td, io_u);

		dprint(FD_IO, "->prep(%p)=%d\n", io_u, ret);
		if (ret)
			unlock_file(td, io_u->file);
		return ret;
	}

	return 0;
}

int td_io_getevents(struct thread_data *td, unsigned int min, unsigned int max,
		    struct timespec *t)
{
	int r = 0;

	/*
	 * For ioengine=rdma one side operation RDMA_WRITE or RDMA_READ,
	 * server side gets a message from the client
	 * side that the task is finished, and
	 * td->done is set to 1 after td_io_commit(). In this case,
	 * there is no need to reap complete event in server side.
	 */
	if (td->done)
		return 0;

	if (min > 0 && td->io_ops->commit) {
		r = td->io_ops->commit(td);
		if (r < 0)
			goto out;
	}
	if (max > td->cur_depth)
		max = td->cur_depth;
	if (min > max)
		max = min;

	r = 0;
	if (max && td->io_ops->getevents)
		r = td->io_ops->getevents(td, min, max, t);
out:
	if (r >= 0) {
		/*
 		 * Reflect that our submitted requests were retrieved with
		 * whatever OS async calls are in the underlying engine.
		 */
		td->io_u_in_flight -= r;
		io_u_mark_complete(td, r);
	} else
		td_verror(td, r, "get_events");

	dprint(FD_IO, "getevents: %d\n", r);
	return r;
}

int td_io_queue(struct thread_data *td, struct io_u *io_u)
{
	int ret;

	dprint_io_u(io_u, "queue");
	fio_ro_check(td, io_u);

	assert((io_u->flags & IO_U_F_FLIGHT) == 0);
	io_u->flags |= IO_U_F_FLIGHT;

	assert(fio_file_open(io_u->file));

	io_u->error = 0;
	io_u->resid = 0;

	if (td->io_ops->flags & FIO_SYNCIO) {
		if (fio_fill_issue_time(td))
			fio_gettime(&io_u->issue_time, NULL);

		/*
		 * only used for iolog
		 */
		if (td->o.read_iolog_file)
			memcpy(&td->last_issue, &io_u->issue_time,
					sizeof(struct timeval));
	}

	if (ddir_rw(io_u->ddir))
		td->io_issues[io_u->ddir]++;

	ret = td->io_ops->queue(td, io_u);

	unlock_file(td, io_u->file);

	/*
	 * Add warning for O_DIRECT so that users have an easier time
	 * spotting potentially bad alignment. If this triggers for the first
	 * IO, then it's likely an alignment problem or because the host fs
	 * does not support O_DIRECT
	 */
	if (io_u->error == EINVAL && td->io_issues[io_u->ddir & 1] == 1 &&
	    td->o.odirect) {

		log_info("fio: first direct IO errored. File system may not "
			 "support direct IO, or iomem_align= is bad.\n");
	}

	if (!td->io_ops->commit || ddir_trim(io_u->ddir)) {
		io_u_mark_submit(td, 1);
		io_u_mark_complete(td, 1);
	}

	if (ret == FIO_Q_COMPLETED) {
		if (ddir_rw(io_u->ddir)) {
			io_u_mark_depth(td, 1);
			td->ts.total_io_u[io_u->ddir]++;
		}
	} else if (ret == FIO_Q_QUEUED) {
		int r;

		if (ddir_rw(io_u->ddir)) {
			td->io_u_queued++;
			td->ts.total_io_u[io_u->ddir]++;
		}

		if (td->io_u_queued >= td->o.iodepth_batch) {
			r = td_io_commit(td);
			if (r < 0)
				return r;
		}
	}

	if ((td->io_ops->flags & FIO_SYNCIO) == 0) {
		if (fio_fill_issue_time(td))
			fio_gettime(&io_u->issue_time, NULL);

		/*
		 * only used for iolog
		 */
		if (td->o.read_iolog_file)
			memcpy(&td->last_issue, &io_u->issue_time,
					sizeof(struct timeval));
	}

	return ret;
}

int td_io_init(struct thread_data *td)
{
	int ret = 0;

	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 (!td->error)
			td->error = ret;
	}

	return ret;
}

int td_io_commit(struct thread_data *td)
{
	int ret;

	dprint(FD_IO, "calling ->commit(), depth %d\n", td->cur_depth);

	if (!td->cur_depth || !td->io_u_queued)
		return 0;

	io_u_mark_depth(td, td->io_u_queued);	

	if (td->io_ops->commit) {
		ret = td->io_ops->commit(td);
		if (ret)
			td_verror(td, -ret, "io commit");
	}
	
	/*
	 * Reflect that events were submitted as async IO requests.
	 */
	td->io_u_in_flight += td->io_u_queued;
	td->io_u_queued = 0;

	return 0;
}

int td_io_open_file(struct thread_data *td, struct fio_file *f)
{
	assert(!fio_file_open(f));
	assert(f->fd == -1);

	if (td->io_ops->open_file(td, f)) {
		if (td->error == EINVAL && td->o.odirect)
			log_err("fio: destination does not support O_DIRECT\n");
		if (td->error == EMFILE) {
			log_err("fio: try reducing/setting openfiles (failed"
				" at %u of %u)\n", td->nr_open_files,
							td->o.nr_files);
		}

		assert(f->fd == -1);
		assert(!fio_file_open(f));
		return 1;
	}

	fio_file_reset(f);
	fio_file_set_open(f);
	fio_file_clear_closing(f);
	disk_util_inc(f->du);

	td->nr_open_files++;
	get_file(f);

	if (f->filetype == FIO_TYPE_PIPE) {
		if (td_random(td)) {
			log_err("fio: can't seek on pipes (no random io)\n");
			goto err;
		}
	}

	if (td->io_ops->flags & FIO_DISKLESSIO)
		goto done;

	if (td->o.invalidate_cache && file_invalidate_cache(td, f))
		goto err;

	if (td->o.fadvise_hint &&
	    (f->filetype == FIO_TYPE_BD || f->filetype == FIO_TYPE_FILE)) {
		int flags;

		if (td_random(td))
			flags = POSIX_FADV_RANDOM;
		else
			flags = POSIX_FADV_SEQUENTIAL;

		if (posix_fadvise(f->fd, f->file_offset, f->io_size, flags) < 0) {
			td_verror(td, errno, "fadvise");
			goto err;
		}
	}

#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");
			log_err("fio: the file system does not seem to support direct IO\n");
			goto err;
		}
	}
#endif

done:
	log_file(td, f, FIO_LOG_OPEN_FILE);
	return 0;
err:
	disk_util_dec(f->du);
	if (td->io_ops->close_file)
		td->io_ops->close_file(td, f);
	return 1;
}

int td_io_close_file(struct thread_data *td, struct fio_file *f)
{
	if (!fio_file_closing(f))
		log_file(td, f, FIO_LOG_CLOSE_FILE);

	/*
	 * mark as closing, do real close when last io on it has completed
	 */
	fio_file_set_closing(f);

	disk_util_dec(f->du);
	unlock_file_all(td, f);

	return put_file(td, f);
}

int td_io_get_file_size(struct thread_data *td, struct fio_file *f)
{
	if (!td->io_ops->get_file_size)
		return 0;

	return td->io_ops->get_file_size(td, f);
}

static int do_sync_file_range(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(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 FIO_HAVE_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(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;
	struct thread_data td;
	char *sep;
	int ret = 1;

	if (!engine || !*engine) {
		log_info("Available IO engines:\n");
		flist_for_each(entry, &engine_list) {
			td.io_ops = flist_entry(entry, struct ioengine_ops,
						list);
			log_info("\t%s\n", td.io_ops->name);
		}
		return 0;
	}
	sep = strchr(engine, ',');
	if (sep) {
		*sep = 0;
		sep++;
	}

	memset(&td, 0, sizeof(td));

	td.io_ops = load_ioengine(&td, engine);
	if (!td.io_ops) {
		log_info("IO engine %s not found\n", engine);
		return 1;
	}

	if (td.io_ops->options)
		ret = show_cmd_help(td.io_ops->options, sep);
	else
		log_info("IO engine %s has no options\n", td.io_ops->name);

	free_ioengine(&td);

	return ret;
}
