/*
 * ioe_e4defrag:  ioengine for git://git.kernel.dk/fio.git
 *
 * IO engine that does regular EXT4_IOC_MOVE_EXT ioctls to simulate
 * defragment activity
 *
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/uio.h>
#include <errno.h>
#include <assert.h>
#include <fcntl.h>

#include "../fio.h"
#include "../optgroup.h"

#ifndef EXT4_IOC_MOVE_EXT
#define EXT4_IOC_MOVE_EXT               _IOWR('f', 15, struct move_extent)
struct move_extent {
	__u32 reserved;         /* should be zero */
	__u32 donor_fd;         /* donor file descriptor */
	__u64 orig_start;       /* logical start offset in block for orig */
	__u64 donor_start;      /* logical start offset in block for donor */
	__u64 len;              /* block length to be moved */
	__u64 moved_len;        /* moved block length */
};
#endif

struct e4defrag_data {
	int donor_fd;
	int bsz;
};

struct e4defrag_options {
	void *pad;
	unsigned int inplace;
	char * donor_name;
};

static struct fio_option options[] = {
	{
		.name	= "donorname",
		.lname	= "Donor Name",
		.type	= FIO_OPT_STR_STORE,
		.off1	= offsetof(struct e4defrag_options, donor_name),
		.help	= "File used as a block donor",
		.category = FIO_OPT_C_ENGINE,
		.group	= FIO_OPT_G_E4DEFRAG,
	},
	{
		.name	= "inplace",
		.lname	= "In Place",
		.type	= FIO_OPT_INT,
		.off1	= offsetof(struct e4defrag_options, inplace),
		.minval	= 0,
		.maxval	= 1,
		.help	= "Alloc and free space inside defrag event",
		.category = FIO_OPT_C_ENGINE,
		.group	= FIO_OPT_G_E4DEFRAG,
	},
	{
		.name	= NULL,
	},
};

static int fio_e4defrag_init(struct thread_data *td)
{
	int r, len = 0;
	struct e4defrag_options *o = td->eo;
	struct e4defrag_data *ed;
	struct stat stub;
	char donor_name[PATH_MAX];

	if (!strlen(o->donor_name)) {
		log_err("'donorname' options required\n");
		return 1;
	}

	ed = malloc(sizeof(*ed));
	if (!ed) {
		td_verror(td, ENOMEM, "io_queue_init");
		return 1;
	}
	memset(ed, 0 ,sizeof(*ed));

	if (td->o.directory)
		len = sprintf(donor_name, "%s/", td->o.directory);
	sprintf(donor_name + len, "%s", o->donor_name);

	ed->donor_fd = open(donor_name, O_CREAT|O_WRONLY, 0644);
	if (ed->donor_fd < 0) {
		td_verror(td, errno, "io_queue_init");
		log_err("Can't open donor file %s err:%d\n", donor_name, ed->donor_fd);
		free(ed);
		return 1;
	}

	if (!o->inplace) {
		long long __len = td->o.file_size_high - td->o.start_offset;
		r = fallocate(ed->donor_fd, 0, td->o.start_offset, __len);
		if (r)
			goto err;
	}
	r = fstat(ed->donor_fd, &stub);
	if (r)
		goto err;

	ed->bsz = stub.st_blksize;
	td->io_ops_data = ed;
	return 0;
err:
	td_verror(td, errno, "io_queue_init");
	close(ed->donor_fd);
	free(ed);
	return 1;
}

static void fio_e4defrag_cleanup(struct thread_data *td)
{
	struct e4defrag_data *ed = td->io_ops_data;
	if (ed) {
		if (ed->donor_fd >= 0)
			close(ed->donor_fd);
		free(ed);
	}
}


static int fio_e4defrag_queue(struct thread_data *td, struct io_u *io_u)
{

	int ret;
	unsigned long long len;
	struct move_extent me;
	struct fio_file *f = io_u->file;
	struct e4defrag_data *ed = td->io_ops_data;
	struct e4defrag_options *o = td->eo;

	fio_ro_check(td, io_u);

	/* Theoretically defragmentation should not change data, but it
	 * changes data layout. So this function handle only DDIR_WRITE
	 * in order to satisfy strict read only access pattern
	 */
	if (io_u->ddir != DDIR_WRITE) {
		io_u->error = EINVAL;
		return FIO_Q_COMPLETED;
	}

	if (o->inplace) {
		ret = fallocate(ed->donor_fd, 0, io_u->offset, io_u->xfer_buflen);
		if (ret)
			goto out;
	}

	memset(&me, 0, sizeof(me));
	me.donor_fd = ed->donor_fd;
	me.orig_start = io_u->offset / ed->bsz;
	me.donor_start = me.orig_start;
	len = (io_u->offset + io_u->xfer_buflen + ed->bsz -1);
	me.len = len / ed->bsz - me.orig_start;

	ret = ioctl(f->fd, EXT4_IOC_MOVE_EXT, &me);
	len = me.moved_len * ed->bsz;

	if (len > io_u->xfer_buflen)
		len = io_u->xfer_buflen;

	if (len != io_u->xfer_buflen) {
		if (len) {
			io_u->resid = io_u->xfer_buflen - len;
			io_u->error = 0;
		} else {
			/* access beyond i_size */
			io_u->error = EINVAL;
		}
	}
	if (ret)
		io_u->error = errno;

	if (o->inplace)
		ret = ftruncate(ed->donor_fd, 0);
out:
	if (ret && !io_u->error)
		io_u->error = errno;

	return FIO_Q_COMPLETED;
}

static struct ioengine_ops ioengine = {
	.name			= "e4defrag",
	.version		= FIO_IOOPS_VERSION,
	.init			= fio_e4defrag_init,
	.queue			= fio_e4defrag_queue,
	.open_file		= generic_open_file,
	.close_file		= generic_close_file,
	.get_file_size		= generic_get_file_size,
	.flags			= FIO_SYNCIO,
	.cleanup		= fio_e4defrag_cleanup,
	.options		= options,
	.option_struct_size	= sizeof(struct e4defrag_options),

};

static void fio_init fio_syncio_register(void)
{
	register_ioengine(&ioengine);
}

static void fio_exit fio_syncio_unregister(void)
{
	unregister_ioengine(&ioengine);
}
