/*
 * linux/fs/9p/mux.c
 *
 * Protocol Multiplexer
 *
 *  Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
 *  Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2
 *  as published by the Free Software Foundation.
 *
 *  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/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/kthread.h>
#include <linux/idr.h>
#include <linux/mutex.h>

#include "debug.h"
#include "v9fs.h"
#include "9p.h"
#include "conv.h"
#include "transport.h"
#include "mux.h"

#define ERREQFLUSH	1
#define SCHED_TIMEOUT	10
#define MAXPOLLWADDR	2

enum {
	Rworksched = 1,		/* read work scheduled or running */
	Rpending = 2,		/* can read */
	Wworksched = 4,		/* write work scheduled or running */
	Wpending = 8,		/* can write */
};

enum {
	None,
	Flushing,
	Flushed,
};

struct v9fs_mux_poll_task;

struct v9fs_req {
	spinlock_t lock;
	int tag;
	struct v9fs_fcall *tcall;
	struct v9fs_fcall *rcall;
	int err;
	v9fs_mux_req_callback cb;
	void *cba;
	int flush;
	struct list_head req_list;
};

struct v9fs_mux_data {
	spinlock_t lock;
	struct list_head mux_list;
	struct v9fs_mux_poll_task *poll_task;
	int msize;
	unsigned char *extended;
	struct v9fs_transport *trans;
	struct v9fs_idpool tagpool;
	int err;
	wait_queue_head_t equeue;
	struct list_head req_list;
	struct list_head unsent_req_list;
	struct v9fs_fcall *rcall;
	int rpos;
	char *rbuf;
	int wpos;
	int wsize;
	char *wbuf;
	wait_queue_t poll_wait[MAXPOLLWADDR];
	wait_queue_head_t *poll_waddr[MAXPOLLWADDR];
	poll_table pt;
	struct work_struct rq;
	struct work_struct wq;
	unsigned long wsched;
};

struct v9fs_mux_poll_task {
	struct task_struct *task;
	struct list_head mux_list;
	int muxnum;
};

struct v9fs_mux_rpc {
	struct v9fs_mux_data *m;
	int err;
	struct v9fs_fcall *tcall;
	struct v9fs_fcall *rcall;
	wait_queue_head_t wqueue;
};

static int v9fs_poll_proc(void *);
static void v9fs_read_work(struct work_struct *work);
static void v9fs_write_work(struct work_struct *work);
static void v9fs_pollwait(struct file *filp, wait_queue_head_t * wait_address,
			  poll_table * p);
static u16 v9fs_mux_get_tag(struct v9fs_mux_data *);
static void v9fs_mux_put_tag(struct v9fs_mux_data *, u16);

static DEFINE_MUTEX(v9fs_mux_task_lock);
static struct workqueue_struct *v9fs_mux_wq;

static int v9fs_mux_num;
static int v9fs_mux_poll_task_num;
static struct v9fs_mux_poll_task v9fs_mux_poll_tasks[100];

int v9fs_mux_global_init(void)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(v9fs_mux_poll_tasks); i++)
		v9fs_mux_poll_tasks[i].task = NULL;

	v9fs_mux_wq = create_workqueue("v9fs");
	if (!v9fs_mux_wq) {
		printk(KERN_WARNING "v9fs: mux: creating workqueue failed\n");
		return -ENOMEM;
	}

	return 0;
}

void v9fs_mux_global_exit(void)
{
	destroy_workqueue(v9fs_mux_wq);
}

/**
 * v9fs_mux_calc_poll_procs - calculates the number of polling procs
 * based on the number of mounted v9fs filesystems.
 *
 * The current implementation returns sqrt of the number of mounts.
 */
static int v9fs_mux_calc_poll_procs(int muxnum)
{
	int n;

	if (v9fs_mux_poll_task_num)
		n = muxnum / v9fs_mux_poll_task_num +
		    (muxnum % v9fs_mux_poll_task_num ? 1 : 0);
	else
		n = 1;

	if (n > ARRAY_SIZE(v9fs_mux_poll_tasks))
		n = ARRAY_SIZE(v9fs_mux_poll_tasks);

	return n;
}

static int v9fs_mux_poll_start(struct v9fs_mux_data *m)
{
	int i, n;
	struct v9fs_mux_poll_task *vpt, *vptlast;
	struct task_struct *pproc;

	dprintk(DEBUG_MUX, "mux %p muxnum %d procnum %d\n", m, v9fs_mux_num,
		v9fs_mux_poll_task_num);
	mutex_lock(&v9fs_mux_task_lock);

	n = v9fs_mux_calc_poll_procs(v9fs_mux_num + 1);
	if (n > v9fs_mux_poll_task_num) {
		for (i = 0; i < ARRAY_SIZE(v9fs_mux_poll_tasks); i++) {
			if (v9fs_mux_poll_tasks[i].task == NULL) {
				vpt = &v9fs_mux_poll_tasks[i];
				dprintk(DEBUG_MUX, "create proc %p\n", vpt);
				pproc = kthread_create(v9fs_poll_proc, vpt,
						   "v9fs-poll");

				if (!IS_ERR(pproc)) {
					vpt->task = pproc;
					INIT_LIST_HEAD(&vpt->mux_list);
					vpt->muxnum = 0;
					v9fs_mux_poll_task_num++;
					wake_up_process(vpt->task);
				}
				break;
			}
		}

		if (i >= ARRAY_SIZE(v9fs_mux_poll_tasks))
			dprintk(DEBUG_ERROR, "warning: no free poll slots\n");
	}

	n = (v9fs_mux_num + 1) / v9fs_mux_poll_task_num +
	    ((v9fs_mux_num + 1) % v9fs_mux_poll_task_num ? 1 : 0);

	vptlast = NULL;
	for (i = 0; i < ARRAY_SIZE(v9fs_mux_poll_tasks); i++) {
		vpt = &v9fs_mux_poll_tasks[i];
		if (vpt->task != NULL) {
			vptlast = vpt;
			if (vpt->muxnum < n) {
				dprintk(DEBUG_MUX, "put in proc %d\n", i);
				list_add(&m->mux_list, &vpt->mux_list);
				vpt->muxnum++;
				m->poll_task = vpt;
				memset(&m->poll_waddr, 0, sizeof(m->poll_waddr));
				init_poll_funcptr(&m->pt, v9fs_pollwait);
				break;
			}
		}
	}

	if (i >= ARRAY_SIZE(v9fs_mux_poll_tasks)) {
		if (vptlast == NULL)
			return -ENOMEM;

		dprintk(DEBUG_MUX, "put in proc %d\n", i);
		list_add(&m->mux_list, &vptlast->mux_list);
		vptlast->muxnum++;
		m->poll_task = vptlast;
		memset(&m->poll_waddr, 0, sizeof(m->poll_waddr));
		init_poll_funcptr(&m->pt, v9fs_pollwait);
	}

	v9fs_mux_num++;
	mutex_unlock(&v9fs_mux_task_lock);

	return 0;
}

static void v9fs_mux_poll_stop(struct v9fs_mux_data *m)
{
	int i;
	struct v9fs_mux_poll_task *vpt;

	mutex_lock(&v9fs_mux_task_lock);
	vpt = m->poll_task;
	list_del(&m->mux_list);
	for(i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) {
		if (m->poll_waddr[i] != NULL) {
			remove_wait_queue(m->poll_waddr[i], &m->poll_wait[i]);
			m->poll_waddr[i] = NULL;
		}
	}
	vpt->muxnum--;
	if (!vpt->muxnum) {
		dprintk(DEBUG_MUX, "destroy proc %p\n", vpt);
		send_sig(SIGKILL, vpt->task, 1);
		vpt->task = NULL;
		v9fs_mux_poll_task_num--;
	}
	v9fs_mux_num--;
	mutex_unlock(&v9fs_mux_task_lock);
}

/**
 * v9fs_mux_init - allocate and initialize the per-session mux data
 * Creates the polling task if this is the first session.
 *
 * @trans - transport structure
 * @msize - maximum message size
 * @extended - pointer to the extended flag
 */
struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize,
				    unsigned char *extended)
{
	int i, n;
	struct v9fs_mux_data *m, *mtmp;

	dprintk(DEBUG_MUX, "transport %p msize %d\n", trans, msize);
	m = kmalloc(sizeof(struct v9fs_mux_data), GFP_KERNEL);
	if (!m)
		return ERR_PTR(-ENOMEM);

	spin_lock_init(&m->lock);
	INIT_LIST_HEAD(&m->mux_list);
	m->msize = msize;
	m->extended = extended;
	m->trans = trans;
	idr_init(&m->tagpool.pool);
	init_MUTEX(&m->tagpool.lock);
	m->err = 0;
	init_waitqueue_head(&m->equeue);
	INIT_LIST_HEAD(&m->req_list);
	INIT_LIST_HEAD(&m->unsent_req_list);
	m->rcall = NULL;
	m->rpos = 0;
	m->rbuf = NULL;
	m->wpos = m->wsize = 0;
	m->wbuf = NULL;
	INIT_WORK(&m->rq, v9fs_read_work);
	INIT_WORK(&m->wq, v9fs_write_work);
	m->wsched = 0;
	memset(&m->poll_waddr, 0, sizeof(m->poll_waddr));
	m->poll_task = NULL;
	n = v9fs_mux_poll_start(m);
	if (n)
		return ERR_PTR(n);

	n = trans->poll(trans, &m->pt);
	if (n & POLLIN) {
		dprintk(DEBUG_MUX, "mux %p can read\n", m);
		set_bit(Rpending, &m->wsched);
	}

	if (n & POLLOUT) {
		dprintk(DEBUG_MUX, "mux %p can write\n", m);
		set_bit(Wpending, &m->wsched);
	}

	for(i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) {
		if (IS_ERR(m->poll_waddr[i])) {
			v9fs_mux_poll_stop(m);
			mtmp = (void *)m->poll_waddr;	/* the error code */
			kfree(m);
			m = mtmp;
			break;
		}
	}

	return m;
}

/**
 * v9fs_mux_destroy - cancels all pending requests and frees mux resources
 */
void v9fs_mux_destroy(struct v9fs_mux_data *m)
{
	dprintk(DEBUG_MUX, "mux %p prev %p next %p\n", m,
		m->mux_list.prev, m->mux_list.next);
	v9fs_mux_cancel(m, -ECONNRESET);

	if (!list_empty(&m->req_list)) {
		/* wait until all processes waiting on this session exit */
		dprintk(DEBUG_MUX, "mux %p waiting for empty request queue\n",
			m);
		wait_event_timeout(m->equeue, (list_empty(&m->req_list)), 5000);
		dprintk(DEBUG_MUX, "mux %p request queue empty: %d\n", m,
			list_empty(&m->req_list));
	}

	v9fs_mux_poll_stop(m);
	m->trans = NULL;

	kfree(m);
}

/**
 * v9fs_pollwait - called by files poll operation to add v9fs-poll task
 * 	to files wait queue
 */
static void
v9fs_pollwait(struct file *filp, wait_queue_head_t * wait_address,
	      poll_table * p)
{
	int i;
	struct v9fs_mux_data *m;

	m = container_of(p, struct v9fs_mux_data, pt);
	for(i = 0; i < ARRAY_SIZE(m->poll_waddr); i++)
		if (m->poll_waddr[i] == NULL)
			break;

	if (i >= ARRAY_SIZE(m->poll_waddr)) {
		dprintk(DEBUG_ERROR, "not enough wait_address slots\n");
		return;
	}

	m->poll_waddr[i] = wait_address;

	if (!wait_address) {
		dprintk(DEBUG_ERROR, "no wait_address\n");
		m->poll_waddr[i] = ERR_PTR(-EIO);
		return;
	}

	init_waitqueue_entry(&m->poll_wait[i], m->poll_task->task);
	add_wait_queue(wait_address, &m->poll_wait[i]);
}

/**
 * v9fs_poll_mux - polls a mux and schedules read or write works if necessary
 */
static void v9fs_poll_mux(struct v9fs_mux_data *m)
{
	int n;

	if (m->err < 0)
		return;

	n = m->trans->poll(m->trans, NULL);
	if (n < 0 || n & (POLLERR | POLLHUP | POLLNVAL)) {
		dprintk(DEBUG_MUX, "error mux %p err %d\n", m, n);
		if (n >= 0)
			n = -ECONNRESET;
		v9fs_mux_cancel(m, n);
	}

	if (n & POLLIN) {
		set_bit(Rpending, &m->wsched);
		dprintk(DEBUG_MUX, "mux %p can read\n", m);
		if (!test_and_set_bit(Rworksched, &m->wsched)) {
			dprintk(DEBUG_MUX, "schedule read work mux %p\n", m);
			queue_work(v9fs_mux_wq, &m->rq);
		}
	}

	if (n & POLLOUT) {
		set_bit(Wpending, &m->wsched);
		dprintk(DEBUG_MUX, "mux %p can write\n", m);
		if ((m->wsize || !list_empty(&m->unsent_req_list))
		    && !test_and_set_bit(Wworksched, &m->wsched)) {
			dprintk(DEBUG_MUX, "schedule write work mux %p\n", m);
			queue_work(v9fs_mux_wq, &m->wq);
		}
	}
}

/**
 * v9fs_poll_proc - polls all v9fs transports for new events and queues
 * 	the appropriate work to the work queue
 */
static int v9fs_poll_proc(void *a)
{
	struct v9fs_mux_data *m, *mtmp;
	struct v9fs_mux_poll_task *vpt;

	vpt = a;
	dprintk(DEBUG_MUX, "start %p %p\n", current, vpt);
	allow_signal(SIGKILL);
	while (!kthread_should_stop()) {
		set_current_state(TASK_INTERRUPTIBLE);
		if (signal_pending(current))
			break;

		list_for_each_entry_safe(m, mtmp, &vpt->mux_list, mux_list) {
			v9fs_poll_mux(m);
		}

		dprintk(DEBUG_MUX, "sleeping...\n");
		schedule_timeout(SCHED_TIMEOUT * HZ);
	}

	__set_current_state(TASK_RUNNING);
	dprintk(DEBUG_MUX, "finish\n");
	return 0;
}

/**
 * v9fs_write_work - called when a transport can send some data
 */
static void v9fs_write_work(struct work_struct *work)
{
	int n, err;
	struct v9fs_mux_data *m;
	struct v9fs_req *req;

	m = container_of(work, struct v9fs_mux_data, wq);

	if (m->err < 0) {
		clear_bit(Wworksched, &m->wsched);
		return;
	}

	if (!m->wsize) {
		if (list_empty(&m->unsent_req_list)) {
			clear_bit(Wworksched, &m->wsched);
			return;
		}

		spin_lock(&m->lock);
again:
		req = list_entry(m->unsent_req_list.next, struct v9fs_req,
			       req_list);
		list_move_tail(&req->req_list, &m->req_list);
		if (req->err == ERREQFLUSH)
			goto again;

		m->wbuf = req->tcall->sdata;
		m->wsize = req->tcall->size;
		m->wpos = 0;
		dump_data(m->wbuf, m->wsize);
		spin_unlock(&m->lock);
	}

	dprintk(DEBUG_MUX, "mux %p pos %d size %d\n", m, m->wpos, m->wsize);
	clear_bit(Wpending, &m->wsched);
	err = m->trans->write(m->trans, m->wbuf + m->wpos, m->wsize - m->wpos);
	dprintk(DEBUG_MUX, "mux %p sent %d bytes\n", m, err);
	if (err == -EAGAIN) {
		clear_bit(Wworksched, &m->wsched);
		return;
	}

	if (err <= 0)
		goto error;

	m->wpos += err;
	if (m->wpos == m->wsize)
		m->wpos = m->wsize = 0;

	if (m->wsize == 0 && !list_empty(&m->unsent_req_list)) {
		if (test_and_clear_bit(Wpending, &m->wsched))
			n = POLLOUT;
		else
			n = m->trans->poll(m->trans, NULL);

		if (n & POLLOUT) {
			dprintk(DEBUG_MUX, "schedule write work mux %p\n", m);
			queue_work(v9fs_mux_wq, &m->wq);
		} else
			clear_bit(Wworksched, &m->wsched);
	} else
		clear_bit(Wworksched, &m->wsched);

	return;

      error:
	v9fs_mux_cancel(m, err);
	clear_bit(Wworksched, &m->wsched);
}

static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req)
{
	int ecode;
	struct v9fs_str *ename;

	if (!req->err && req->rcall->id == RERROR) {
		ecode = req->rcall->params.rerror.errno;
		ename = &req->rcall->params.rerror.error;

		dprintk(DEBUG_MUX, "Rerror %.*s\n", ename->len, ename->str);

		if (*m->extended)
			req->err = -ecode;

		if (!req->err) {
			req->err = v9fs_errstr2errno(ename->str, ename->len);

			if (!req->err) {	/* string match failed */
				PRINT_FCALL_ERROR("unknown error", req->rcall);
			}

			if (!req->err)
				req->err = -ESERVERFAULT;
		}
	} else if (req->tcall && req->rcall->id != req->tcall->id + 1) {
		dprintk(DEBUG_ERROR, "fcall mismatch: expected %d, got %d\n",
			req->tcall->id + 1, req->rcall->id);
		if (!req->err)
			req->err = -EIO;
	}
}

/**
 * v9fs_read_work - called when there is some data to be read from a transport
 */
static void v9fs_read_work(struct work_struct *work)
{
	int n, err;
	struct v9fs_mux_data *m;
	struct v9fs_req *req, *rptr, *rreq;
	struct v9fs_fcall *rcall;
	char *rbuf;

	m = container_of(work, struct v9fs_mux_data, rq);

	if (m->err < 0)
		return;

	rcall = NULL;
	dprintk(DEBUG_MUX, "start mux %p pos %d\n", m, m->rpos);

	if (!m->rcall) {
		m->rcall =
		    kmalloc(sizeof(struct v9fs_fcall) + m->msize, GFP_KERNEL);
		if (!m->rcall) {
			err = -ENOMEM;
			goto error;
		}

		m->rbuf = (char *)m->rcall + sizeof(struct v9fs_fcall);
		m->rpos = 0;
	}

	clear_bit(Rpending, &m->wsched);
	err = m->trans->read(m->trans, m->rbuf + m->rpos, m->msize - m->rpos);
	dprintk(DEBUG_MUX, "mux %p got %d bytes\n", m, err);
	if (err == -EAGAIN) {
		clear_bit(Rworksched, &m->wsched);
		return;
	}

	if (err <= 0)
		goto error;

	m->rpos += err;
	while (m->rpos > 4) {
		n = le32_to_cpu(*(__le32 *) m->rbuf);
		if (n >= m->msize) {
			dprintk(DEBUG_ERROR,
				"requested packet size too big: %d\n", n);
			err = -EIO;
			goto error;
		}

		if (m->rpos < n)
			break;

		dump_data(m->rbuf, n);
		err =
		    v9fs_deserialize_fcall(m->rbuf, n, m->rcall, *m->extended);
		if (err < 0) {
			goto error;
		}

		if ((v9fs_debug_level&DEBUG_FCALL) == DEBUG_FCALL) {
			char buf[150];

			v9fs_printfcall(buf, sizeof(buf), m->rcall,
				*m->extended);
			printk(KERN_NOTICE ">>> %p %s\n", m, buf);
		}

		rcall = m->rcall;
		rbuf = m->rbuf;
		if (m->rpos > n) {
			m->rcall = kmalloc(sizeof(struct v9fs_fcall) + m->msize,
					   GFP_KERNEL);
			if (!m->rcall) {
				err = -ENOMEM;
				goto error;
			}

			m->rbuf = (char *)m->rcall + sizeof(struct v9fs_fcall);
			memmove(m->rbuf, rbuf + n, m->rpos - n);
			m->rpos -= n;
		} else {
			m->rcall = NULL;
			m->rbuf = NULL;
			m->rpos = 0;
		}

		dprintk(DEBUG_MUX, "mux %p fcall id %d tag %d\n", m, rcall->id,
			rcall->tag);

		req = NULL;
		spin_lock(&m->lock);
		list_for_each_entry_safe(rreq, rptr, &m->req_list, req_list) {
			if (rreq->tag == rcall->tag) {
				req = rreq;
				if (req->flush != Flushing)
					list_del(&req->req_list);
				break;
			}
		}
		spin_unlock(&m->lock);

		if (req) {
			req->rcall = rcall;
			process_request(m, req);

			if (req->flush != Flushing) {
				if (req->cb)
					(*req->cb) (req, req->cba);
				else
					kfree(req->rcall);

				wake_up(&m->equeue);
			}
		} else {
			if (err >= 0 && rcall->id != RFLUSH)
				dprintk(DEBUG_ERROR,
					"unexpected response mux %p id %d tag %d\n",
					m, rcall->id, rcall->tag);
			kfree(rcall);
		}
	}

	if (!list_empty(&m->req_list)) {
		if (test_and_clear_bit(Rpending, &m->wsched))
			n = POLLIN;
		else
			n = m->trans->poll(m->trans, NULL);

		if (n & POLLIN) {
			dprintk(DEBUG_MUX, "schedule read work mux %p\n", m);
			queue_work(v9fs_mux_wq, &m->rq);
		} else
			clear_bit(Rworksched, &m->wsched);
	} else
		clear_bit(Rworksched, &m->wsched);

	return;

      error:
	v9fs_mux_cancel(m, err);
	clear_bit(Rworksched, &m->wsched);
}

/**
 * v9fs_send_request - send 9P request
 * The function can sleep until the request is scheduled for sending.
 * The function can be interrupted. Return from the function is not
 * a guarantee that the request is sent successfully. Can return errors
 * that can be retrieved by PTR_ERR macros.
 *
 * @m: mux data
 * @tc: request to be sent
 * @cb: callback function to call when response is received
 * @cba: parameter to pass to the callback function
 */
static struct v9fs_req *v9fs_send_request(struct v9fs_mux_data *m,
					  struct v9fs_fcall *tc,
					  v9fs_mux_req_callback cb, void *cba)
{
	int n;
	struct v9fs_req *req;

	dprintk(DEBUG_MUX, "mux %p task %p tcall %p id %d\n", m, current,
		tc, tc->id);
	if (m->err < 0)
		return ERR_PTR(m->err);

	req = kmalloc(sizeof(struct v9fs_req), GFP_KERNEL);
	if (!req)
		return ERR_PTR(-ENOMEM);

	if (tc->id == TVERSION)
		n = V9FS_NOTAG;
	else
		n = v9fs_mux_get_tag(m);

	if (n < 0)
		return ERR_PTR(-ENOMEM);

	v9fs_set_tag(tc, n);
	if ((v9fs_debug_level&DEBUG_FCALL) == DEBUG_FCALL) {
		char buf[150];

		v9fs_printfcall(buf, sizeof(buf), tc, *m->extended);
		printk(KERN_NOTICE "<<< %p %s\n", m, buf);
	}

	spin_lock_init(&req->lock);
	req->tag = n;
	req->tcall = tc;
	req->rcall = NULL;
	req->err = 0;
	req->cb = cb;
	req->cba = cba;
	req->flush = None;

	spin_lock(&m->lock);
	list_add_tail(&req->req_list, &m->unsent_req_list);
	spin_unlock(&m->lock);

	if (test_and_clear_bit(Wpending, &m->wsched))
		n = POLLOUT;
	else
		n = m->trans->poll(m->trans, NULL);

	if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched))
		queue_work(v9fs_mux_wq, &m->wq);

	return req;
}

static void v9fs_mux_free_request(struct v9fs_mux_data *m, struct v9fs_req *req)
{
	v9fs_mux_put_tag(m, req->tag);
	kfree(req);
}

static void v9fs_mux_flush_cb(struct v9fs_req *freq, void *a)
{
	v9fs_mux_req_callback cb;
	int tag;
	struct v9fs_mux_data *m;
	struct v9fs_req *req, *rreq, *rptr;

	m = a;
	dprintk(DEBUG_MUX, "mux %p tc %p rc %p err %d oldtag %d\n", m,
		freq->tcall, freq->rcall, freq->err,
		freq->tcall->params.tflush.oldtag);

	spin_lock(&m->lock);
	cb = NULL;
	tag = freq->tcall->params.tflush.oldtag;
	req = NULL;
	list_for_each_entry_safe(rreq, rptr, &m->req_list, req_list) {
		if (rreq->tag == tag) {
			req = rreq;
			list_del(&req->req_list);
			break;
		}
	}
	spin_unlock(&m->lock);

	if (req) {
		spin_lock(&req->lock);
		req->flush = Flushed;
		spin_unlock(&req->lock);

		if (req->cb)
			(*req->cb) (req, req->cba);
		else
			kfree(req->rcall);

		wake_up(&m->equeue);
	}

	kfree(freq->tcall);
	kfree(freq->rcall);
	v9fs_mux_free_request(m, freq);
}

static int
v9fs_mux_flush_request(struct v9fs_mux_data *m, struct v9fs_req *req)
{
	struct v9fs_fcall *fc;
	struct v9fs_req *rreq, *rptr;

	dprintk(DEBUG_MUX, "mux %p req %p tag %d\n", m, req, req->tag);

	/* if a response was received for a request, do nothing */
	spin_lock(&req->lock);
	if (req->rcall || req->err) {
		spin_unlock(&req->lock);
		dprintk(DEBUG_MUX, "mux %p req %p response already received\n", m, req);
		return 0;
	}

	req->flush = Flushing;
	spin_unlock(&req->lock);

	spin_lock(&m->lock);
	/* if the request is not sent yet, just remove it from the list */
	list_for_each_entry_safe(rreq, rptr, &m->unsent_req_list, req_list) {
		if (rreq->tag == req->tag) {
			dprintk(DEBUG_MUX, "mux %p req %p request is not sent yet\n", m, req);
			list_del(&rreq->req_list);
			req->flush = Flushed;
			spin_unlock(&m->lock);
			if (req->cb)
				(*req->cb) (req, req->cba);
			return 0;
		}
	}
	spin_unlock(&m->lock);

	clear_thread_flag(TIF_SIGPENDING);
	fc = v9fs_create_tflush(req->tag);
	v9fs_send_request(m, fc, v9fs_mux_flush_cb, m);
	return 1;
}

static void
v9fs_mux_rpc_cb(struct v9fs_req *req, void *a)
{
	struct v9fs_mux_rpc *r;

	dprintk(DEBUG_MUX, "req %p r %p\n", req, a);
	r = a;
	r->rcall = req->rcall;
	r->err = req->err;

	if (req->flush!=None && !req->err)
		r->err = -ERESTARTSYS;

	wake_up(&r->wqueue);
}

/**
 * v9fs_mux_rpc - sends 9P request and waits until a response is available.
 *	The function can be interrupted.
 * @m: mux data
 * @tc: request to be sent
 * @rc: pointer where a pointer to the response is stored
 */
int
v9fs_mux_rpc(struct v9fs_mux_data *m, struct v9fs_fcall *tc,
	     struct v9fs_fcall **rc)
{
	int err, sigpending;
	unsigned long flags;
	struct v9fs_req *req;
	struct v9fs_mux_rpc r;

	r.err = 0;
	r.tcall = tc;
	r.rcall = NULL;
	r.m = m;
	init_waitqueue_head(&r.wqueue);

	if (rc)
		*rc = NULL;

	sigpending = 0;
	if (signal_pending(current)) {
		sigpending = 1;
		clear_thread_flag(TIF_SIGPENDING);
	}

	req = v9fs_send_request(m, tc, v9fs_mux_rpc_cb, &r);
	if (IS_ERR(req)) {
		err = PTR_ERR(req);
		dprintk(DEBUG_MUX, "error %d\n", err);
		return err;
	}

	err = wait_event_interruptible(r.wqueue, r.rcall != NULL || r.err < 0);
	if (r.err < 0)
		err = r.err;

	if (err == -ERESTARTSYS && m->trans->status == Connected && m->err == 0) {
		if (v9fs_mux_flush_request(m, req)) {
			/* wait until we get response of the flush message */
			do {
				clear_thread_flag(TIF_SIGPENDING);
				err = wait_event_interruptible(r.wqueue,
					r.rcall || r.err);
			} while (!r.rcall && !r.err && err==-ERESTARTSYS &&
				m->trans->status==Connected && !m->err);

			err = -ERESTARTSYS;
		}
		sigpending = 1;
	}

	if (sigpending) {
		spin_lock_irqsave(&current->sighand->siglock, flags);
		recalc_sigpending();
		spin_unlock_irqrestore(&current->sighand->siglock, flags);
	}

	if (rc)
		*rc = r.rcall;
	else
		kfree(r.rcall);

	v9fs_mux_free_request(m, req);
	if (err > 0)
		err = -EIO;

	return err;
}

#if 0
/**
 * v9fs_mux_rpcnb - sends 9P request without waiting for response.
 * @m: mux data
 * @tc: request to be sent
 * @cb: callback function to be called when response arrives
 * @cba: value to pass to the callback function
 */
int v9fs_mux_rpcnb(struct v9fs_mux_data *m, struct v9fs_fcall *tc,
		   v9fs_mux_req_callback cb, void *a)
{
	int err;
	struct v9fs_req *req;

	req = v9fs_send_request(m, tc, cb, a);
	if (IS_ERR(req)) {
		err = PTR_ERR(req);
		dprintk(DEBUG_MUX, "error %d\n", err);
		return PTR_ERR(req);
	}

	dprintk(DEBUG_MUX, "mux %p tc %p tag %d\n", m, tc, req->tag);
	return 0;
}
#endif  /*  0  */

/**
 * v9fs_mux_cancel - cancel all pending requests with error
 * @m: mux data
 * @err: error code
 */
void v9fs_mux_cancel(struct v9fs_mux_data *m, int err)
{
	struct v9fs_req *req, *rtmp;
	LIST_HEAD(cancel_list);

	dprintk(DEBUG_ERROR, "mux %p err %d\n", m, err);
	m->err = err;
	spin_lock(&m->lock);
	list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) {
		list_move(&req->req_list, &cancel_list);
	}
	list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) {
		list_move(&req->req_list, &cancel_list);
	}
	spin_unlock(&m->lock);

	list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) {
		list_del(&req->req_list);
		if (!req->err)
			req->err = err;

		if (req->cb)
			(*req->cb) (req, req->cba);
		else
			kfree(req->rcall);
	}

	wake_up(&m->equeue);
}

static u16 v9fs_mux_get_tag(struct v9fs_mux_data *m)
{
	int tag;

	tag = v9fs_get_idpool(&m->tagpool);
	if (tag < 0)
		return V9FS_NOTAG;
	else
		return (u16) tag;
}

static void v9fs_mux_put_tag(struct v9fs_mux_data *m, u16 tag)
{
	if (tag != V9FS_NOTAG && v9fs_check_idpool(tag, &m->tagpool))
		v9fs_put_idpool(tag, &m->tagpool);
}
