/*
 * 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"

#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",
		.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",
		.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", 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) {
		io_u->resid = io_u->xfer_buflen - len;
		io_u->error = 0;
	}
	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);
}
