/*
 * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
 * Licensed under the GPL
 */

#include <unistd.h>
#include <sched.h>
#include <signal.h>
#include <errno.h>
#include <sys/time.h>
#include <asm/unistd.h>
#include "aio.h"
#include "init.h"
#include "kern_constants.h"
#include "kern_util.h"
#include "os.h"
#include "user.h"

struct aio_thread_req {
	enum aio_type type;
	int io_fd;
	unsigned long long offset;
	char *buf;
	int len;
	struct aio_context *aio;
};

#if defined(HAVE_AIO_ABI)
#include <linux/aio_abi.h>

/*
 * If we have the headers, we are going to build with AIO enabled.
 * If we don't have aio in libc, we define the necessary stubs here.
 */

#if !defined(HAVE_AIO_LIBC)

static long io_setup(int n, aio_context_t *ctxp)
{
	return syscall(__NR_io_setup, n, ctxp);
}

static long io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp)
{
	return syscall(__NR_io_submit, ctx, nr, iocbpp);
}

static long io_getevents(aio_context_t ctx_id, long min_nr, long nr,
			 struct io_event *events, struct timespec *timeout)
{
	return syscall(__NR_io_getevents, ctx_id, min_nr, nr, events, timeout);
}

#endif

/*
 * The AIO_MMAP cases force the mmapped page into memory here
 * rather than in whatever place first touches the data.  I used
 * to do this by touching the page, but that's delicate because
 * gcc is prone to optimizing that away.  So, what's done here
 * is we read from the descriptor from which the page was
 * mapped.  The caller is required to pass an offset which is
 * inside the page that was mapped.  Thus, when the read
 * returns, we know that the page is in the page cache, and
 * that it now backs the mmapped area.
 */

static int do_aio(aio_context_t ctx, enum aio_type type, int fd, char *buf,
		  int len, unsigned long long offset, struct aio_context *aio)
{
	struct iocb *iocbp = & ((struct iocb) {
				    .aio_data       = (unsigned long) aio,
				    .aio_fildes     = fd,
				    .aio_buf        = (unsigned long) buf,
				    .aio_nbytes     = len,
				    .aio_offset     = offset
			     });
	char c;

	switch (type) {
	case AIO_READ:
		iocbp->aio_lio_opcode = IOCB_CMD_PREAD;
		break;
	case AIO_WRITE:
		iocbp->aio_lio_opcode = IOCB_CMD_PWRITE;
		break;
	case AIO_MMAP:
		iocbp->aio_lio_opcode = IOCB_CMD_PREAD;
		iocbp->aio_buf = (unsigned long) &c;
		iocbp->aio_nbytes = sizeof(c);
		break;
	default:
		printk(UM_KERN_ERR "Bogus op in do_aio - %d\n", type);
		return -EINVAL;
	}

	return (io_submit(ctx, 1, &iocbp) > 0) ? 0 : -errno;
}

/* Initialized in an initcall and unchanged thereafter */
static aio_context_t ctx = 0;

static int aio_thread(void *arg)
{
	struct aio_thread_reply reply;
	struct io_event event;
	int err, n, reply_fd;

	signal(SIGWINCH, SIG_IGN);

	while (1) {
		n = io_getevents(ctx, 1, 1, &event, NULL);
		if (n < 0) {
			if (errno == EINTR)
				continue;
			printk(UM_KERN_ERR "aio_thread - io_getevents failed, "
			       "errno = %d\n", errno);
		}
		else {
			reply = ((struct aio_thread_reply)
				{ .data = (void *) (long) event.data,
						.err	= event.res });
			reply_fd = ((struct aio_context *) reply.data)->reply_fd;
			err = write(reply_fd, &reply, sizeof(reply));
			if (err != sizeof(reply))
				printk(UM_KERN_ERR "aio_thread - write failed, "
				       "fd = %d, err = %d\n", reply_fd, errno);
		}
	}
	return 0;
}

#endif

static int do_not_aio(struct aio_thread_req *req)
{
	char c;
	unsigned long long actual;
	int n;

	actual = lseek64(req->io_fd, req->offset, SEEK_SET);
	if (actual != req->offset)
		return -errno;

	switch(req->type) {
	case AIO_READ:
		n = read(req->io_fd, req->buf, req->len);
		break;
	case AIO_WRITE:
		n = write(req->io_fd, req->buf, req->len);
		break;
	case AIO_MMAP:
		n = read(req->io_fd, &c, sizeof(c));
		break;
	default:
		printk(UM_KERN_ERR "do_not_aio - bad request type : %d\n",
		       req->type);
		return -EINVAL;
	}

	if (n < 0)
		return -errno;
	return 0;
}

/* These are initialized in initcalls and not changed */
static int aio_req_fd_r = -1;
static int aio_req_fd_w = -1;
static int aio_pid = -1;
static unsigned long aio_stack;

static int not_aio_thread(void *arg)
{
	struct aio_thread_req req;
	struct aio_thread_reply reply;
	int err;

	signal(SIGWINCH, SIG_IGN);
	while (1) {
		err = read(aio_req_fd_r, &req, sizeof(req));
		if (err != sizeof(req)) {
			if (err < 0)
				printk(UM_KERN_ERR "not_aio_thread - "
				       "read failed, fd = %d, err = %d\n",
				       aio_req_fd_r,
				       errno);
			else {
				printk(UM_KERN_ERR "not_aio_thread - short "
				       "read, fd = %d, length = %d\n",
				       aio_req_fd_r, err);
			}
			continue;
		}
		err = do_not_aio(&req);
		reply = ((struct aio_thread_reply) { .data 	= req.aio,
						     .err	= err });
		err = write(req.aio->reply_fd, &reply, sizeof(reply));
		if (err != sizeof(reply))
			printk(UM_KERN_ERR "not_aio_thread - write failed, "
			       "fd = %d, err = %d\n", req.aio->reply_fd, errno);
	}

	return 0;
}

static int init_aio_24(void)
{
	int fds[2], err;

	err = os_pipe(fds, 1, 1);
	if (err)
		goto out;

	aio_req_fd_w = fds[0];
	aio_req_fd_r = fds[1];

	err = os_set_fd_block(aio_req_fd_w, 0);
	if (err)
		goto out_close_pipe;

	err = run_helper_thread(not_aio_thread, NULL,
				CLONE_FILES | CLONE_VM, &aio_stack);
	if (err < 0)
		goto out_close_pipe;

	aio_pid = err;
	goto out;

out_close_pipe:
	close(fds[0]);
	close(fds[1]);
	aio_req_fd_w = -1;
	aio_req_fd_r = -1;
out:
#ifndef HAVE_AIO_ABI
	printk(UM_KERN_INFO "/usr/include/linux/aio_abi.h not present during "
	       "build\n");
#endif
	printk(UM_KERN_INFO "2.6 host AIO support not used - falling back to "
	       "I/O thread\n");
	return 0;
}

#ifdef HAVE_AIO_ABI
#define DEFAULT_24_AIO 0
static int init_aio_26(void)
{
	int err;

	if (io_setup(256, &ctx)) {
		err = -errno;
		printk(UM_KERN_ERR "aio_thread failed to initialize context, "
		       "err = %d\n", errno);
		return err;
	}

	err = run_helper_thread(aio_thread, NULL,
				CLONE_FILES | CLONE_VM, &aio_stack);
	if (err < 0)
		return err;

	aio_pid = err;

	printk(UM_KERN_INFO "Using 2.6 host AIO\n");
	return 0;
}

static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
			 unsigned long long offset, struct aio_context *aio)
{
	struct aio_thread_reply reply;
	int err;

	err = do_aio(ctx, type, io_fd, buf, len, offset, aio);
	if (err) {
		reply = ((struct aio_thread_reply) { .data = aio,
					 .err  = err });
		err = write(aio->reply_fd, &reply, sizeof(reply));
		if (err != sizeof(reply)) {
			err = -errno;
			printk(UM_KERN_ERR "submit_aio_26 - write failed, "
			       "fd = %d, err = %d\n", aio->reply_fd, -err);
		}
		else err = 0;
	}

	return err;
}

#else
#define DEFAULT_24_AIO 1
static int init_aio_26(void)
{
	return -ENOSYS;
}

static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
			 unsigned long long offset, struct aio_context *aio)
{
	return -ENOSYS;
}
#endif

/* Initialized in an initcall and unchanged thereafter */
static int aio_24 = DEFAULT_24_AIO;

static int __init set_aio_24(char *name, int *add)
{
	aio_24 = 1;
	return 0;
}

__uml_setup("aio=2.4", set_aio_24,
"aio=2.4\n"
"    This is used to force UML to use 2.4-style AIO even when 2.6 AIO is\n"
"    available.  2.4 AIO is a single thread that handles one request at a\n"
"    time, synchronously.  2.6 AIO is a thread which uses the 2.6 AIO \n"
"    interface to handle an arbitrary number of pending requests.  2.6 AIO \n"
"    is not available in tt mode, on 2.4 hosts, or when UML is built with\n"
"    /usr/include/linux/aio_abi.h not available.  Many distributions don't\n"
"    include aio_abi.h, so you will need to copy it from a kernel tree to\n"
"    your /usr/include/linux in order to build an AIO-capable UML\n\n"
);

static int init_aio(void)
{
	int err;

	if (!aio_24) {
		err = init_aio_26();
		if (err && (errno == ENOSYS)) {
			printk(UM_KERN_INFO "2.6 AIO not supported on the "
			       "host - reverting to 2.4 AIO\n");
			aio_24 = 1;
		}
		else return err;
	}

	if (aio_24)
		return init_aio_24();

	return 0;
}

/*
 * The reason for the __initcall/__uml_exitcall asymmetry is that init_aio
 * needs to be called when the kernel is running because it calls run_helper,
 * which needs get_free_page.  exit_aio is a __uml_exitcall because the generic
 * kernel does not run __exitcalls on shutdown, and can't because many of them
 * break when called outside of module unloading.
 */
__initcall(init_aio);

static void exit_aio(void)
{
	if (aio_pid != -1) {
		os_kill_process(aio_pid, 1);
		free_stack(aio_stack, 0);
	}
}

__uml_exitcall(exit_aio);

static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len,
			 unsigned long long offset, struct aio_context *aio)
{
	struct aio_thread_req req = { .type 		= type,
				      .io_fd		= io_fd,
				      .offset		= offset,
				      .buf		= buf,
				      .len		= len,
				      .aio		= aio,
	};
	int err;

	err = write(aio_req_fd_w, &req, sizeof(req));
	if (err == sizeof(req))
		err = 0;
	else err = -errno;

	return err;
}

int submit_aio(enum aio_type type, int io_fd, char *buf, int len,
	       unsigned long long offset, int reply_fd,
	       struct aio_context *aio)
{
	aio->reply_fd = reply_fd;
	if (aio_24)
		return submit_aio_24(type, io_fd, buf, len, offset, aio);
	else
		return submit_aio_26(type, io_fd, buf, len, offset, aio);
}
