/*
 * linux/fs/9p/trans_fd.c
 *
 * File Descriptor Transport Layer
 *
 *  Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net>
 *  Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to:
 *  Free Software Foundation
 *  51 Franklin Street, Fifth Floor
 *  Boston, MA  02111-1301  USA
 *
 */

#include <linux/config.h>
#include <linux/module.h>
#include <linux/net.h>
#include <linux/ipv6.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/un.h>
#include <asm/uaccess.h>
#include <linux/inet.h>
#include <linux/idr.h>
#include <linux/file.h>

#include "debug.h"
#include "v9fs.h"
#include "transport.h"

struct v9fs_trans_fd {
	struct file *in_file;
	struct file *out_file;
};

/**
 * v9fs_fd_recv - receive from a socket
 * @v9ses: session information
 * @v: buffer to receive data into
 * @len: size of receive buffer
 *
 */

static int v9fs_fd_recv(struct v9fs_transport *trans, void *v, int len)
{
	struct v9fs_trans_fd *ts = trans ? trans->priv : NULL;

	if (!trans || trans->status != Connected || !ts)
		return -EIO;

	return kernel_read(ts->in_file, ts->in_file->f_pos, v, len);
}

/**
 * v9fs_fd_send - send to a socket
 * @v9ses: session information
 * @v: buffer to send data from
 * @len: size of send buffer
 *
 */

static int v9fs_fd_send(struct v9fs_transport *trans, void *v, int len)
{
	struct v9fs_trans_fd *ts = trans ? trans->priv : NULL;
	mm_segment_t oldfs = get_fs();
	int ret = 0;

	if (!trans || trans->status != Connected || !ts)
		return -EIO;

	oldfs = get_fs();
	set_fs(get_ds());
	/* The cast to a user pointer is valid due to the set_fs() */
	ret = vfs_write(ts->out_file, (void __user *)v, len, &ts->out_file->f_pos);
	set_fs(oldfs);

	return ret;
}

/**
 * v9fs_fd_init - initialize file descriptor transport
 * @v9ses: session information
 * @addr: address of server to mount
 * @data: mount options
 *
 */

static int
v9fs_fd_init(struct v9fs_session_info *v9ses, const char *addr, char *data)
{
	struct v9fs_trans_fd *ts = NULL;
	struct v9fs_transport *trans = v9ses->transport;

	if((v9ses->wfdno == ~0) || (v9ses->rfdno == ~0)) {
		printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n");
		return -ENOPROTOOPT;
	}

	ts = kmalloc(sizeof(struct v9fs_trans_fd), GFP_KERNEL);

	if (!ts)
		return -ENOMEM;

	ts->in_file = fget( v9ses->rfdno );
	ts->out_file = fget( v9ses->wfdno );

	if (!ts->in_file || !ts->out_file) {
		if (ts->in_file)
			fput(ts->in_file);

		if (ts->out_file)
			fput(ts->out_file);

		kfree(ts);
		return -EIO;
	}

	trans->priv = ts;
	trans->status = Connected;

	return 0;
}


/**
 * v9fs_fd_close - shutdown file descriptor
 * @trans: private socket structure
 *
 */

static void v9fs_fd_close(struct v9fs_transport *trans)
{
	struct v9fs_trans_fd *ts;

	if (!trans)
		return;

	ts = xchg(&trans->priv, NULL);

	if (!ts)
		return;

	trans->status = Disconnected;
	if (ts->in_file)
		fput(ts->in_file);

	if (ts->out_file)
		fput(ts->out_file);

	kfree(ts);
}

static unsigned int
v9fs_fd_poll(struct v9fs_transport *trans, struct poll_table_struct *pt)
{
	int ret, n;
	struct v9fs_trans_fd *ts;
	mm_segment_t oldfs;

	if (!trans)
		return -EIO;

	ts = trans->priv;
	if (trans->status != Connected || !ts)
		return -EIO;

	oldfs = get_fs();
	set_fs(get_ds());

	if (!ts->in_file->f_op || !ts->in_file->f_op->poll) {
		ret = -EIO;
		goto end;
	}

	ret = ts->in_file->f_op->poll(ts->in_file, pt);

	if (ts->out_file != ts->in_file) {
		if (!ts->out_file->f_op || !ts->out_file->f_op->poll) {
			ret = -EIO;
			goto end;
		}

		n = ts->out_file->f_op->poll(ts->out_file, pt);

		ret &= ~POLLOUT;
		n &= ~POLLIN;

		ret |= n;
	}

end:
	set_fs(oldfs);
	return ret;
}


struct v9fs_transport v9fs_trans_fd = {
	.init = v9fs_fd_init,
	.write = v9fs_fd_send,
	.read = v9fs_fd_recv,
	.close = v9fs_fd_close,
	.poll = v9fs_fd_poll,
};

