/*
 * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
 * Licensed under the GPL
 */

#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <sched.h>
#include <sys/syscall.h>
#include "os.h"
#include "helper.h"
#include "aio.h"
#include "init.h"
#include "user.h"
#include "mode.h"

static int aio_req_fd_r = -1;
static int aio_req_fd_w = -1;

static int update_aio(struct aio_context *aio, int res)
{
        if(res < 0)
                aio->len = res;
        else if((res == 0) && (aio->type == AIO_READ)){
                /* This is the EOF case - we have hit the end of the file
                 * and it ends in a partial block, so we fill the end of
                 * the block with zeros and claim success.
                 */
                memset(aio->data, 0, aio->len);
                aio->len = 0;
        }
        else if(res > 0){
                aio->len -= res;
                aio->data += res;
                aio->offset += res;
                return aio->len;
        }

        return 0;
}

#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, struct aio_context *aio)
{
        struct iocb iocb, *iocbp = &iocb;
        char c;
        int err;

        iocb = ((struct iocb) { .aio_data 	= (unsigned long) aio,
                                .aio_reqprio	= 0,
                                .aio_fildes	= aio->fd,
                                .aio_buf	= (unsigned long) aio->data,
                                .aio_nbytes	= aio->len,
                                .aio_offset	= aio->offset,
                                .aio_reserved1	= 0,
                                .aio_reserved2	= 0,
                                .aio_reserved3	= 0 });

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

        err = io_submit(ctx, 1, &iocbp);
        if(err > 0)
                err = 0;

 out:
        return err;
}

static aio_context_t ctx = 0;

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

        signal(SIGWINCH, SIG_IGN);

        while(1){
                n = io_getevents(ctx, 1, 1, &event, NULL);
                if(n < 0){
                        if(errno == EINTR)
                                continue;
                        printk("aio_thread - io_getevents failed, "
                               "errno = %d\n", errno);
                }
                else {
			aio = (struct aio_context *) event.data;
			if(update_aio(aio, event.res)){
				do_aio(ctx, aio);
				continue;
			}

                        reply = ((struct aio_thread_reply)
				{ .data = aio,
				  .err	= aio->len });
			err = os_write_file(aio->reply_fd, &reply,
					    sizeof(reply));
                        if(err != sizeof(reply))
				printk("aio_thread - write failed, "
				       "fd = %d, err = %d\n", aio->reply_fd,
				       -err);
                }
        }
        return 0;
}

#endif

static int do_not_aio(struct aio_context *aio)
{
        char c;
        int err;

        switch(aio->type){
        case AIO_READ:
                err = os_seek_file(aio->fd, aio->offset);
                if(err)
                        goto out;

                err = os_read_file(aio->fd, aio->data, aio->len);
                break;
        case AIO_WRITE:
                err = os_seek_file(aio->fd, aio->offset);
                if(err)
                        goto out;

                err = os_write_file(aio->fd, aio->data, aio->len);
                break;
        case AIO_MMAP:
                err = os_seek_file(aio->fd, aio->offset);
                if(err)
                        goto out;

                err = os_read_file(aio->fd, &c, sizeof(c));
                break;
        default:
                printk("do_not_aio - bad request type : %d\n", aio->type);
                err = -EINVAL;
                break;
        }

 out:
        return err;
}

static int not_aio_thread(void *arg)
{
        struct aio_context *aio;
        struct aio_thread_reply reply;
        int err;

        signal(SIGWINCH, SIG_IGN);
        while(1){
                err = os_read_file(aio_req_fd_r, &aio, sizeof(aio));
                if(err != sizeof(aio)){
                        if(err < 0)
                                printk("not_aio_thread - read failed, "
                                       "fd = %d, err = %d\n", aio_req_fd_r,
                                       -err);
                        else {
                                printk("not_aio_thread - short read, fd = %d, "
                                       "length = %d\n", aio_req_fd_r, err);
                        }
                        continue;
                }
 again:
                err = do_not_aio(aio);

                if(update_aio(aio, err))
                        goto again;

                reply = ((struct aio_thread_reply) { .data 	= aio,
                                                     .err	= aio->len });
                err = os_write_file(aio->reply_fd, &reply, sizeof(reply));
                if(err != sizeof(reply))
                        printk("not_aio_thread - write failed, fd = %d, "
                               "err = %d\n", aio_req_fd_r, -err);
        }
}

static int submit_aio_24(struct aio_context *aio)
{
        int err;

        err = os_write_file(aio_req_fd_w, &aio, sizeof(aio));
        if(err == sizeof(aio))
                err = 0;

        return err;
}

static int aio_pid = -1;
static int (*submit_proc)(struct aio_context *aio);

static int init_aio_24(void)
{
        unsigned long stack;
        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 = run_helper_thread(not_aio_thread, NULL,
                                CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0);
        if(err < 0)
                goto out_close_pipe;

        aio_pid = err;
        goto out;

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

	submit_proc = submit_aio_24;

        return 0;
}

#ifdef HAVE_AIO_ABI
#define DEFAULT_24_AIO 0
static int submit_aio_26(struct aio_context *aio)
{
	struct aio_thread_reply reply;
	int err;

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

	return err;
}

static int init_aio_26(void)
{
        unsigned long stack;
        int err;

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

        err = run_helper_thread(aio_thread, NULL,
                                CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0);
        if(err < 0)
                return -errno;

        aio_pid = err;

	printk("Using 2.6 host AIO\n");

	submit_proc = submit_aio_26;

        return 0;
}

#else
#define DEFAULT_24_AIO 1
static int submit_aio_26(struct aio_context *aio)
{
        return -ENOSYS;
}

static int init_aio_26(void)
{
	submit_proc = submit_aio_26;
        return -ENOSYS;
}
#endif

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;

        CHOOSE_MODE(({
                if(!aio_24){
                        printk("Disabling 2.6 AIO in tt mode\n");
                        aio_24 = 1;
                } }), (void) 0);

        if(!aio_24){
                err = init_aio_26();
                if(err && (errno == ENOSYS)){
                        printk("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);
}

__uml_exitcall(exit_aio);

int submit_aio(struct aio_context *aio)
{
	return (*submit_proc)(aio);
}
