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

	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,
};

