/* Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
 * Portions Copyright © 1997-1999 Vita Nuova Limited
 * Portions Copyright © 2000-2007 Vita Nuova Holdings Limited
 *                                (www.vitanuova.com)
 * Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
 *
 * Modified for the Akaros operating system:
 * Copyright (c) 2013-2014 The Regents of the University of California
 * Copyright (c) 2013-2015 Google Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE. */

#include <vfs.h>
#include <kfs.h>
#include <slab.h>
#include <kmalloc.h>
#include <kref.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <error.h>
#include <cpio.h>
#include <pmap.h>
#include <smp.h>
#include <ip.h>
#include <smallidpool.h>

struct dev mntdevtab;

static char *devname(void)
{
	return mntdevtab.name;
}

/*
 * References are managed as follows:
 * The channel to the server - a network connection or pipe - has one
 * reference for every Chan open on the server.  The server channel has
 * c->mux set to the Mnt used for muxing control to that server.  Mnts
 * have no reference count; they go away when c goes away.
 * Each channel derived from the mount point has mchan set to c,
 * and increfs/decrefs mchan to manage references on the server
 * connection.
 */

#define MAXRPC (IOHDRSZ+8192)
#define MAXTAG MAX_U16_POOL_SZ

static __inline int isxdigit(int c)
{
	if ((c >= '0') && (c <= '9'))
		return 1;
	if ((c >= 'a') && (c <= 'f'))
		return 1;
	if ((c >= 'A') && (c <= 'F'))
		return 1;
	return 0;
}

struct mntrpc {
	struct chan *c;				/* Channel for whom we are working */
	struct mntrpc *list;		/* Free/pending list */
	struct fcall request;		/* Outgoing file system protocol message */
	struct fcall reply;			/* Incoming reply */
	struct mnt *m;				/* Mount device during rpc */
	struct rendez r;			/* Place to hang out */
	uint8_t *rpc;				/* I/O Data buffer */
	unsigned int rpclen;		/* len of buffer */
	struct block *b;			/* reply blocks */
	char done;					/* Rpc completed */
	uint64_t stime;				/* start time for mnt statistics */
	uint32_t reqlen;			/* request length for mnt statistics */
	uint32_t replen;			/* reply length for mnt statistics */
	struct mntrpc *flushed;		/* message this one flushes */
};

/* Our TRUNC and remove on close differ from 9ps, so we'll need to translate.
 * I got these flags from http://man.cat-v.org/plan_9/5/open */
#define MNT_9P_OPEN_OTRUNC		0x10
#define MNT_9P_OPEN_ORCLOSE		0x40

struct Mntalloc {
	spinlock_t l;
	struct mnt *list;			/* Mount devices in use */
	struct mnt *mntfree;		/* Free list */
	struct mntrpc *rpcfree;
	int nrpcfree;
	int nrpcused;
	uint32_t id;
	struct u16_pool *tags;
} mntalloc;

void mattach(struct mnt *, struct chan *, char *unused_char_p_t);
struct mnt *mntchk(struct chan *);
void mntdirfix(uint8_t * unused_uint8_p_t, struct chan *);
struct mntrpc *mntflushalloc(struct mntrpc *, uint32_t);
void mntflushfree(struct mnt *, struct mntrpc *);
void mntfree(struct mntrpc *);
void mntgate(struct mnt *);
void mntpntfree(struct mnt *);
void mntqrm(struct mnt *, struct mntrpc *);
struct mntrpc *mntralloc(struct chan *, uint32_t);
long mntrdwr(int unused_int, struct chan *, void *, long, int64_t);
int mntrpcread(struct mnt *, struct mntrpc *);
void mountio(struct mnt *, struct mntrpc *);
void mountmux(struct mnt *, struct mntrpc *);
void mountrpc(struct mnt *, struct mntrpc *);
int rpcattn(void *);
struct chan *mntchan(void);

void (*mntstats) (int unused_int, struct chan *, uint64_t, uint32_t);

static void mntinit(void)
{
	mntalloc.id = 1;
	mntalloc.tags = create_u16_pool(MAXTAG);
	(void) get_u16(mntalloc.tags);	/* don't allow 0 as a tag */
	//fmtinstall('F', fcallfmt);
/*	fmtinstall('D', dirfmt); */
/*	fmtinstall('M', dirmodefmt);  */

	cinit();
}

/*
 * Version is not multiplexed: message sent only once per connection.
 */
long mntversion(struct chan *c, char *version, int msize, int returnlen)
{
	ERRSTACK(2);
	struct fcall f;
	uint8_t *msg;
	struct mnt *m;
	char *v;
	long k, l;
	uint64_t oo;
	char buf[128];

	qlock(&c->umqlock);	/* make sure no one else does this until we've established ourselves */
	if (waserror()) {
		qunlock(&c->umqlock);
		nexterror();
	}

	/* defaults */
	if (msize == 0)
		msize = MAXRPC;
	if (msize > c->iounit && c->iounit != 0)
		msize = c->iounit;
	v = version;
	if (v == NULL || v[0] == '\0')
		v = VERSION9P;

	/* validity */
	if (msize < 0)
		error(EFAIL, "bad iounit in version call");
	if (strncmp(v, VERSION9P, strlen(VERSION9P)) != 0)
		error(EFAIL, "bad 9P version specification");

	m = c->mux;

	if (m != NULL) {
		qunlock(&c->umqlock);
		poperror();

		strlcpy(buf, m->version, sizeof(buf));
		k = strlen(buf);
		if (strncmp(buf, v, k) != 0) {
			snprintf(buf, sizeof buf, "incompatible 9P versions %s %s",
					 m->version, v);
			error(EFAIL, buf);
		}
		if (returnlen > 0) {
			if (returnlen < k)
				error(ENAMETOOLONG, ERROR_FIXME);
			memmove(version, buf, k);
		}
		return k;
	}

	f.type = Tversion;
	f.tag = NOTAG;
	f.msize = msize;
	f.version = v;
	msg = kzmalloc(8192 + IOHDRSZ, 0);
	if (msg == NULL)
		exhausted("version memory");
	if (waserror()) {
		kfree(msg);
		nexterror();
	}
	k = convS2M(&f, msg, 8192 + IOHDRSZ);
	if (k == 0)
		error(EFAIL, "bad fversion conversion on send");

	spin_lock(&c->lock);
	oo = c->offset;
	c->offset += k;
	spin_unlock(&c->lock);

	l = devtab[c->type].write(c, msg, k, oo);

	if (l < k) {
		spin_lock(&c->lock);
		c->offset -= k - l;
		spin_unlock(&c->lock);
		error(EFAIL, "short write in fversion");
	}

	/* message sent; receive and decode reply */
	k = devtab[c->type].read(c, msg, 8192 + IOHDRSZ, c->offset);
	if (k <= 0)
		error(EFAIL, "EOF receiving fversion reply");

	spin_lock(&c->lock);
	c->offset += k;
	spin_unlock(&c->lock);

	l = convM2S(msg, k, &f);
	if (l != k)
		error(EFAIL, "bad fversion conversion on reply");
	if (f.type != Rversion) {
		if (f.type == Rerror)
			error(EFAIL, f.ename);
		error(EFAIL, "unexpected reply type in fversion");
	}
	if (f.msize > msize)
		error(EFAIL, "server tries to increase msize in fversion");
	if (f.msize < 256 || f.msize > 1024 * 1024)
		error(EFAIL, "nonsense value of msize in fversion");
	if (strncmp(f.version, v, strlen(f.version)) != 0)
		error(EFAIL, "bad 9P version returned from server");

	/* now build Mnt associated with this connection */
	spin_lock(&mntalloc.l);
	m = mntalloc.mntfree;
	if (m != 0)
		mntalloc.mntfree = m->list;
	else {
		m = kzmalloc(sizeof(struct mnt), 0);
		if (m == 0) {
			spin_unlock(&mntalloc.l);
			exhausted("mount devices");
		}
	}
	m->list = mntalloc.list;
	mntalloc.list = m;
	m->version = NULL;
	kstrdup(&m->version, f.version);
	m->id = mntalloc.id++;
	m->q = qopen(10 * MAXRPC, 0, NULL, NULL);
	m->msize = f.msize;
	spin_unlock(&mntalloc.l);

	poperror();	/* msg */
	kfree(msg);

	spin_lock(&m->lock);
	m->queue = 0;
	m->rip = 0;

	c->flag |= CMSG;
	c->mux = m;
	m->c = c;
	spin_unlock(&m->lock);

	poperror();	/* c */
	qunlock(&c->umqlock);
	k = strlen(f.version);
	if (returnlen > 0) {
		if (returnlen < k)
			error(ENAMETOOLONG, ERROR_FIXME);
		memmove(version, f.version, k);
	}

	return k;
}

struct chan *mntauth(struct chan *c, char *spec)
{
	ERRSTACK(2);
	struct mnt *m;
	struct mntrpc *r;

	m = c->mux;

	if (m == NULL) {
		mntversion(c, VERSION9P, MAXRPC, 0);
		m = c->mux;
		if (m == NULL)
			error(EINVAL, ERROR_FIXME);
	}

	c = mntchan();
	if (waserror()) {
		/* Close must not be called since it will
		 * call mnt recursively
		 */
		chanfree(c);
		nexterror();
	}

	r = mntralloc(0, m->msize);

	if (waserror()) {
		mntfree(r);
		nexterror();
	}

	r->request.type = Tauth;
	r->request.afid = c->fid;
	r->request.uname = current->user.name;
	r->request.aname = spec;
	mountrpc(m, r);

	c->qid = r->reply.aqid;
	c->mchan = m->c;
	chan_incref(m->c);
	c->mqid = c->qid;
	c->mode = O_RDWR;

	poperror();	/* r */
	mntfree(r);

	poperror();	/* c */

	return c;

}

static struct chan *mntattach(char *muxattach)
{
	ERRSTACK(2);
	struct mnt *m;
	struct chan *c;
	struct mntrpc *r;
	struct bogus {
		struct chan *chan;
		struct chan *authchan;
		char *spec;
		int flags;
	} bogus;

	bogus = *((struct bogus *)muxattach);
	c = bogus.chan;

	m = c->mux;

	if (m == NULL) {
		mntversion(c, NULL, 0, 0);
		m = c->mux;
		if (m == NULL)
			error(EINVAL, ERROR_FIXME);
	}

	c = mntchan();
	if (waserror()) {
		/* Close must not be called since it will
		 * call mnt recursively
		 */
		chanfree(c);
		nexterror();
	}

	r = mntralloc(0, m->msize);

	if (waserror()) {
		mntfree(r);
		nexterror();
	}

	r->request.type = Tattach;
	r->request.fid = c->fid;
	if (bogus.authchan == NULL)
		r->request.afid = NOFID;
	else
		r->request.afid = bogus.authchan->fid;
	r->request.uname = current->user.name;
	r->request.aname = bogus.spec;
	mountrpc(m, r);

	c->qid = r->reply.qid;
	c->mchan = m->c;
	chan_incref(m->c);
	c->mqid = c->qid;

	poperror();	/* r */
	mntfree(r);

	poperror();	/* c */

	if (bogus.flags & MCACHE)
		c->flag |= CCACHE;
	return c;
}

struct chan *mntchan(void)
{
	struct chan *c;

	c = devattach(devname(), 0);
	spin_lock(&mntalloc.l);
	c->dev = mntalloc.id++;
	spin_unlock(&mntalloc.l);

	if (c->mchan)
		panic("mntchan non-zero %p", c->mchan);
	return c;
}

static struct walkqid *mntwalk(struct chan *c, struct chan *nc, char **name,
							   int nname)
{
	ERRSTACK(2);
	volatile int alloc;
	int i;
	struct mnt *m;
	struct mntrpc *r;
	struct walkqid *wq;

	if (nc != NULL)
		printd("mntwalk: nc != NULL\n");
	if (nname > MAXWELEM)
		error(EFAIL, "devmnt: too many name elements");
	alloc = 0;
	wq = kzmalloc(sizeof(struct walkqid) + nname * sizeof(struct qid),
				  MEM_WAIT);
	if (waserror()) {
		if (alloc && wq->clone != NULL)
			cclose(wq->clone);
		kfree(wq);
		poperror();
		return NULL;
	}

	alloc = 0;
	m = mntchk(c);
	r = mntralloc(c, m->msize);
	if (nc == NULL) {
		nc = devclone(c);
		/* Until the other side accepts this fid, we can't mntclose it.
		 * Therefore set type to -1 for now.  inferno was setting this to 0,
		 * assuming it was devroot.  lining up with chanrelease and newchan */
		nc->type = -1;
		alloc = 1;
	}
	wq->clone = nc;

	if (waserror()) {
		mntfree(r);
		nexterror();
	}
	r->request.type = Twalk;
	r->request.fid = c->fid;
	r->request.newfid = nc->fid;
	r->request.nwname = nname;
	memmove(r->request.wname, name, nname * sizeof(char *));

	mountrpc(m, r);

	if (r->reply.nwqid > nname)
		error(EFAIL, "too many QIDs returned by walk");
	if (r->reply.nwqid < nname) {
		if (alloc)
			cclose(nc);
		wq->clone = NULL;
		if (r->reply.nwqid == 0) {
			kfree(wq);
			wq = NULL;
			goto Return;
		}
	}

	/* move new fid onto mnt device and update its qid */
	if (wq->clone != NULL) {
		if (wq->clone != c) {
			wq->clone->type = c->type;
			wq->clone->mchan = c->mchan;
			chan_incref(c->mchan);
		}
		if (r->reply.nwqid > 0)
			wq->clone->qid = r->reply.wqid[r->reply.nwqid - 1];
	}
	wq->nqid = r->reply.nwqid;
	for (i = 0; i < wq->nqid; i++)
		wq->qid[i] = r->reply.wqid[i];

Return:
	poperror();
	mntfree(r);
	poperror();
	return wq;
}

static int mntstat(struct chan *c, uint8_t * dp, int n)
{
	ERRSTACK(1);
	struct mnt *m;
	struct mntrpc *r;

	if (n < BIT16SZ)
		error(EINVAL, ERROR_FIXME);
	m = mntchk(c);
	r = mntralloc(c, m->msize);
	if (waserror()) {
		mntfree(r);
		nexterror();
	}
	r->request.type = Tstat;
	r->request.fid = c->fid;
	mountrpc(m, r);

	if (r->reply.nstat > n) {
		/* doesn't fit; just patch the count and return */
		PBIT16((uint8_t *) dp, r->reply.nstat);
		n = BIT16SZ;
	} else {
		n = r->reply.nstat;
		memmove(dp, r->reply.stat, n);
		validstat(dp, n, 0);
		mntdirfix(dp, c);
	}
	poperror();
	mntfree(r);
	return n;
}

static struct chan *mntopencreate(int type, struct chan *c, char *name,
								  int omode, uint32_t perm)
{
	ERRSTACK(1);
	struct mnt *m;
	struct mntrpc *r;

	m = mntchk(c);
	r = mntralloc(c, m->msize);
	if (waserror()) {
		mntfree(r);
		nexterror();
	}
	r->request.type = type;
	r->request.fid = c->fid;
	r->request.mode = omode_to_9p_accmode(omode);
	if (omode & O_TRUNC)
		r->request.mode |= MNT_9P_OPEN_OTRUNC;
	if (omode & O_REMCLO)
		r->request.mode |= MNT_9P_OPEN_ORCLOSE;
	if (type == Tcreate) {
		r->request.perm = perm;
		r->request.name = name;
	}
	mountrpc(m, r);

	c->qid = r->reply.qid;
	c->offset = 0;
	c->mode = openmode(omode);
	c->iounit = r->reply.iounit;
	if (c->iounit == 0 || c->iounit > m->msize - IOHDRSZ)
		c->iounit = m->msize - IOHDRSZ;
	c->flag |= COPEN;
	poperror();
	mntfree(r);

	if (c->flag & CCACHE)
		copen(c);

	return c;
}

static struct chan *mntopen(struct chan *c, int omode)
{
	return mntopencreate(Topen, c, NULL, omode, 0);
}

static void mntcreate(struct chan *c, char *name, int omode, uint32_t perm)
{
	mntopencreate(Tcreate, c, name, omode, perm);
}

static void mntclunk(struct chan *c, int t)
{
	ERRSTACK(1);
	struct mnt *m;
	struct mntrpc *r;

	m = mntchk(c);
	r = mntralloc(c, m->msize);
	if (waserror()) {
		mntfree(r);
		nexterror();
	}

	r->request.type = t;
	r->request.fid = c->fid;
	mountrpc(m, r);
	mntfree(r);
	poperror();
}

void muxclose(struct mnt *m)
{
	struct mntrpc *q, *r;

	for (q = m->queue; q; q = r) {
		r = q->list;
		mntfree(q);
	}
	m->id = 0;
	kfree(m->version);
	m->version = NULL;
	mntpntfree(m);
}

void mntpntfree(struct mnt *m)
{
	struct mnt *f, **l;
	struct queue *q;

	spin_lock(&mntalloc.l);
	l = &mntalloc.list;
	for (f = *l; f; f = f->list) {
		if (f == m) {
			*l = m->list;
			break;
		}
		l = &f->list;
	}
	m->list = mntalloc.mntfree;
	mntalloc.mntfree = m;
	q = m->q;
	spin_unlock(&mntalloc.l);

	qfree(q);
}

static void mntclose(struct chan *c)
{
	mntclunk(c, Tclunk);
}

static void mntremove(struct chan *c)
{
	mntclunk(c, Tremove);
}

static int mntwstat(struct chan *c, uint8_t * dp, int n)
{
	ERRSTACK(1);
	struct mnt *m;
	struct mntrpc *r;

	m = mntchk(c);
	r = mntralloc(c, m->msize);
	if (waserror()) {
		mntfree(r);
		nexterror();
	}
	r->request.type = Twstat;
	r->request.fid = c->fid;
	r->request.nstat = n;
	r->request.stat = dp;
	mountrpc(m, r);
	poperror();
	mntfree(r);
	return n;
}

/* the servers should either return units of whole directory entries
 * OR support seeking to an arbitrary place. One or other.
 * Both are fine, but at least one is a minimum.
 * If the return a partial result, but more than one result,
 * we'll return a shorter read and the next offset will be aligned
 */
static long mntread(struct chan *c, void *buf, long n, int64_t off)
{
	uint8_t *p, *e;
	int nc, cache, isdir, dirlen;
	int numdirent = 0;

	isdir = 0;
	cache = c->flag & CCACHE;
	if (c->qid.type & QTDIR) {
		cache = 0;
		isdir = 1;
	}

	p = buf;
	if (cache) {
		nc = cread(c, buf, n, off);
		if (nc > 0) {
			n -= nc;
			if (n == 0)
				return nc;
			p += nc;
			off += nc;
		}
		n = mntrdwr(Tread, c, p, n, off);
		cupdate(c, p, n, off);
		return n + nc;
	}

	n = mntrdwr(Tread, c, buf, n, off);

	if (isdir) {
		for (e = &p[n]; p + BIT16SZ < e; p += dirlen) {
			dirlen = BIT16SZ + GBIT16(p);
			if (p + dirlen > e){
				break;
			}
			validstat(p, dirlen, 0);
			mntdirfix(p, c);
			numdirent += dirlen;
		}
		if (p != e) {
			//error(Esbadstat);
			/* not really. Maybe the server supports
			 * arbitrary seek like go9p now does.
			 */
			n = numdirent;
		}
	}
	return n;
}

static long mntwrite(struct chan *c, void *buf, long n, int64_t off)
{
	return mntrdwr(Twrite, c, buf, n, off);
}

long mntrdwr(int type, struct chan *c, void *buf, long n, int64_t off)
{
	ERRSTACK(1);
	struct mnt *m;
	struct mntrpc *r;			/* TO DO: volatile struct { Mntrpc *r; } r; */
	char *uba;
	int cache;
	uint32_t cnt, nr, nreq;

	m = mntchk(c);
	uba = buf;
	cnt = 0;
	cache = c->flag & CCACHE;
	if (c->qid.type & QTDIR)
		cache = 0;
	for (;;) {
		r = mntralloc(c, m->msize);
		if (waserror()) {
			mntfree(r);
			nexterror();
		}
		r->request.type = type;
		r->request.fid = c->fid;
		r->request.offset = off;
		r->request.data = uba;
		nr = n;
		if (nr > m->msize - IOHDRSZ)
			nr = m->msize - IOHDRSZ;
		r->request.count = nr;
		mountrpc(m, r);
		nreq = r->request.count;
		nr = r->reply.count;
		if (nr > nreq)
			nr = nreq;

		if (type == Tread)
			r->b = bl2mem((uint8_t *) uba, r->b, nr);
		else if (cache)
			cwrite(c, (uint8_t *) uba, nr, off);

		poperror();
		mntfree(r);
		off += nr;
		uba += nr;
		cnt += nr;
		n -= nr;
		if (nr != nreq || n == 0 /*|| current->killed */ )
			break;
	}
	return cnt;
}

void mountrpc(struct mnt *m, struct mntrpc *r)
{
	char *sn, *cn;
	int t;
	char *e;

	r->reply.tag = 0;
	r->reply.type = Tmax;	/* can't ever be a valid message type */

	mountio(m, r);

	t = r->reply.type;
	switch (t) {
		case Rerror:
			/* in Akaros mode, first four characters
			 * are errno.
			 */
			e = r->reply.ename;
			/* If it is in the format "XXXX <at least one char>" */
			if ((strlen(e) > 5) && isxdigit(e[0]) &&
				isxdigit(e[1]) &&
				isxdigit(e[2]) &&
				isxdigit(e[3])) {

				int errno = strtoul(e, NULL, 16);

				error(errno, &r->reply.ename[5]);
			} else
				error(EFAIL, r->reply.ename);
		case Rflush:
			error(EINTR, ERROR_FIXME);
		default:
			if (t == r->request.type + 1)
				break;
			sn = "?";
			if (m->c->name != NULL)
				sn = m->c->name->s;
			cn = "?";
			if (r->c != NULL && r->c->name != NULL)
				cn = r->c->name->s;
			printk
				("mnt: proc %s %lu: mismatch from %s %s rep 0x%p tag %d fid %d T%d R%d rp %d\n",
				 "current->text", "current->pid", sn, cn, r, r->request.tag,
				 r->request.fid, r->request.type, r->reply.type, r->reply.tag);
			error(EPROTO, ERROR_FIXME);
	}
}

void mountio(struct mnt *m, struct mntrpc *r)
{
	ERRSTACK(1);
	int n;

	while (waserror()) {
		if (m->rip == current)
			mntgate(m);
		/* Syscall aborts are like Plan 9 Eintr.  For those, we need to change
		 * the old request to a flsh (mntflushalloc) and try again.  We'll
		 * always try to flush, and you can't get out until the flush either
		 * succeeds or errors out with a non-abort/Eintr error.
		 *
		 * This all means that regular aborts cannot break us out of here!  We
		 * can consider that policy in the future, if we need to.  Regardless,
		 * if the process is dying, we really do need to abort. */
		if ((get_errno() != EINTR) || proc_is_dying(current)) {
			/* all other errors or dying, bail out! */
			mntflushfree(m, r);
			nexterror();
		}
		/* try again.  this is where you can get the "rpc tags" errstr. */
		r = mntflushalloc(r, m->msize);
		/* need one for every waserror call (so this plus one outside) */
		poperror();
	}

	spin_lock(&m->lock);
	r->m = m;
	r->list = m->queue;
	m->queue = r;
	spin_unlock(&m->lock);

	/* Transmit a file system rpc */
	if (m->msize == 0)
		panic("msize");
	n = convS2M(&r->request, r->rpc, m->msize);
	if (n < 0)
		panic("bad message type in mountio");
	if (devtab[m->c->type].write(m->c, r->rpc, n, 0) != n)
		error(EIO, ERROR_FIXME);
/*	r->stime = fastticks(NULL); */
	r->reqlen = n;

	/* Gate readers onto the mount point one at a time */
	for (;;) {
		spin_lock(&m->lock);
		if (m->rip == 0)
			break;
		spin_unlock(&m->lock);
		rendez_sleep(&r->r, rpcattn, r);
		if (r->done) {
			poperror();
			mntflushfree(m, r);
			return;
		}
	}
	m->rip = current;
	spin_unlock(&m->lock);
	while (r->done == 0) {
		if (mntrpcread(m, r) < 0)
			error(EIO, ERROR_FIXME);
		mountmux(m, r);
	}
	mntgate(m);
	poperror();
	mntflushfree(m, r);
}

static int doread(struct mnt *m, int len)
{
	struct block *b;

	while (qlen(m->q) < len) {
		b = devtab[m->c->type].bread(m->c, m->msize, 0);
		if (b == NULL)
			return -1;
		if (blocklen(b) == 0) {
			freeblist(b);
			return -1;
		}
		qaddlist(m->q, b);
	}
	return 0;
}

int mntrpcread(struct mnt *m, struct mntrpc *r)
{
	int i, t, len, hlen;
	struct block *b, **l, *nb;

	r->reply.type = 0;
	r->reply.tag = 0;

	/* read at least length, type, and tag and pullup to a single block */
	if (doread(m, BIT32SZ + BIT8SZ + BIT16SZ) < 0)
		return -1;
	nb = pullupqueue(m->q, BIT32SZ + BIT8SZ + BIT16SZ);

	/* read in the rest of the message, avoid ridiculous (for now) message sizes */
	len = GBIT32(nb->rp);
	if (len > m->msize) {
		qdiscard(m->q, qlen(m->q));
		return -1;
	}
	if (doread(m, len) < 0)
		return -1;

	/* pullup the header (i.e. everything except data) */
	t = nb->rp[BIT32SZ];
	switch (t) {
		case Rread:
			hlen = BIT32SZ + BIT8SZ + BIT16SZ + BIT32SZ;
			break;
		default:
			hlen = len;
			break;
	}
	nb = pullupqueue(m->q, hlen);

	if (convM2S(nb->rp, len, &r->reply) <= 0) {
		/* bad message, dump it */
		printd("mntrpcread: convM2S failed\n");
		qdiscard(m->q, len);
		return -1;
	}

	/* TODO: this should use a qio helper directly.  qputback should have the
	 * qlocked, but I guess we assume we're the only one using it. */

	/* hang the data off of the fcall struct */
	l = &r->b;
	*l = NULL;
	do {
		b = qget(m->q);
		/* TODO: have better block helpers for this and the memmove below */
		b = linearizeblock(b);
		if (hlen > 0) {
			b->rp += hlen;
			len -= hlen;
			hlen = 0;
		}
		i = BLEN(b);
		if (i <= len) {
			len -= i;
			*l = b;
			l = &(b->next);
		} else {
			/* split block and put unused bit back */
			nb = block_alloc(i - len, MEM_WAIT);
			memmove(nb->wp, b->rp + len, i - len);
			b->wp = b->rp + len;
			nb->wp += i - len;
			qputback(m->q, nb);
			*l = b;
			return 0;
		}
	} while (len > 0);

	return 0;
}

void mntgate(struct mnt *m)
{
	struct mntrpc *q;

	spin_lock(&m->lock);
	m->rip = 0;
	for (q = m->queue; q; q = q->list) {
		if (q->done == 0)
			if (rendez_wakeup(&q->r))
				break;
	}
	spin_unlock(&m->lock);
}

void mountmux(struct mnt *m, struct mntrpc *r)
{
	struct mntrpc **l, *q;

	spin_lock(&m->lock);
	l = &m->queue;
	for (q = *l; q; q = q->list) {
		/* look for a reply to a message */
		if (q->request.tag == r->reply.tag) {
			*l = q->list;
			if (q != r) {
				/*
				 * Completed someone else.
				 * Trade pointers to receive buffer.
				 */
				q->reply = r->reply;
				q->b = r->b;
				r->b = NULL;
			}
			q->done = 1;
			spin_unlock(&m->lock);
			if (mntstats != NULL)
				(*mntstats) (q->request.type,
							 m->c, q->stime, q->reqlen + r->replen);
			if (q != r)
				rendez_wakeup(&q->r);
			return;
		}
		l = &q->list;
	}
	spin_unlock(&m->lock);
	if (r->reply.type == Rerror) {
		printd("unexpected reply tag %u; type %d (error %q)\n", r->reply.tag,
			   r->reply.type, r->reply.ename);
	} else {
		printd("unexpected reply tag %u; type %d\n", r->reply.tag,
			   r->reply.type);
	}
}

/*
 * Create a new flush request and chain the previous
 * requests from it
 */
struct mntrpc *mntflushalloc(struct mntrpc *r, uint32_t iounit)
{
	struct mntrpc *fr;

	fr = mntralloc(0, iounit);

	fr->request.type = Tflush;
	if (r->request.type == Tflush)
		fr->request.oldtag = r->request.oldtag;
	else
		fr->request.oldtag = r->request.tag;
	fr->flushed = r;

	return fr;
}

/*
 *  Free a chain of flushes.  Remove each unanswered
 *  flush and the original message from the unanswered
 *  request queue.  Mark the original message as done
 *  and if it hasn't been answered set the reply to to
 *  Rflush.
 */
void mntflushfree(struct mnt *m, struct mntrpc *r)
{
	struct mntrpc *fr;

	while (r) {
		fr = r->flushed;
		if (!r->done) {
			r->reply.type = Rflush;
			mntqrm(m, r);
		}
		if (fr)
			mntfree(r);
		r = fr;
	}
}

static int alloctag(void)
{
	return get_u16(mntalloc.tags);
}

static void freetag(int t)
{
	put_u16(mntalloc.tags, t);
}

struct mntrpc *mntralloc(struct chan *c, uint32_t msize)
{
	struct mntrpc *new;

	spin_lock(&mntalloc.l);
	new = mntalloc.rpcfree;
	if (new == NULL) {
		new = kzmalloc(sizeof(struct mntrpc), 0);
		if (new == NULL) {
			spin_unlock(&mntalloc.l);
			exhausted("mount rpc header");
		}
		rendez_init(&new->r);
		/*
		 * The header is split from the data buffer as
		 * mountmux may swap the buffer with another header.
		 */
		new->rpc = kzmalloc(msize, MEM_WAIT);
		if (new->rpc == NULL) {
			kfree(new);
			spin_unlock(&mntalloc.l);
			exhausted("mount rpc buffer");
		}
		new->rpclen = msize;
		new->request.tag = alloctag();
		if (new->request.tag == NOTAG) {
			kfree(new);
			spin_unlock(&mntalloc.l);
			exhausted("rpc tags");
		}
	} else {
		mntalloc.rpcfree = new->list;
		mntalloc.nrpcfree--;
		if (new->rpclen < msize) {
			kfree(new->rpc);
			new->rpc = kzmalloc(msize, MEM_WAIT);
			if (new->rpc == NULL) {
				kfree(new);
				mntalloc.nrpcused--;
				spin_unlock(&mntalloc.l);
				exhausted("mount rpc buffer");
			}
			new->rpclen = msize;
		}
	}
	mntalloc.nrpcused++;
	spin_unlock(&mntalloc.l);
	new->c = c;
	new->done = 0;
	new->flushed = NULL;
	new->b = NULL;
	return new;
}

void mntfree(struct mntrpc *r)
{
	if (r->b != NULL)
		freeblist(r->b);
	spin_lock(&mntalloc.l);
	if (mntalloc.nrpcfree >= 10) {
		kfree(r->rpc);
		freetag(r->request.tag);
		kfree(r);
	} else {
		r->list = mntalloc.rpcfree;
		mntalloc.rpcfree = r;
		mntalloc.nrpcfree++;
	}
	mntalloc.nrpcused--;
	spin_unlock(&mntalloc.l);
}

void mntqrm(struct mnt *m, struct mntrpc *r)
{
	struct mntrpc **l, *f;

	spin_lock(&m->lock);
	r->done = 1;

	l = &m->queue;
	for (f = *l; f; f = f->list) {
		if (f == r) {
			*l = r->list;
			break;
		}
		l = &f->list;
	}
	spin_unlock(&m->lock);
}

struct mnt *mntchk(struct chan *c)
{
	struct mnt *m;

	/* This routine is mostly vestiges of prior lives; now it's just sanity checking */

	if (c->mchan == NULL)
		panic("mntchk 1: NULL mchan c %s\n", /*c2name(c) */ "channame?");

	m = c->mchan->mux;

	if (m == NULL)
		printd("mntchk 2: NULL mux c %s c->mchan %s \n", c2name(c),
			   c2name(c->mchan));

	/*
	 * Was it closed and reused (was error(Eshutdown); now, it can't happen)
	 */
	if (m->id == 0 || m->id >= c->dev)
		panic("mntchk 3: can't happen");

	return m;
}

/*
 * Rewrite channel type and dev for in-flight data to
 * reflect local values.  These entries are known to be
 * the first two in the Dir encoding after the count.
 */
void mntdirfix(uint8_t * dirbuf, struct chan *c)
{
	/* TODO: We used to use the device's char (dc), instead of the type.  not
	 * sure about the effects one way or the other.  This might be the type[2]
	 * and dev[4] in a D (struct dir, see 9p's stat
	 * (http://man.cat-v.org/plan_9/5/stat).  In which case, those should be for
	 * the kernel's use.  Hopefully our kernel. */
	dirbuf += BIT16SZ;	/* skip count */
	PBIT16(dirbuf, c->type);
	dirbuf += BIT16SZ;
	PBIT32(dirbuf, c->dev);
}

int rpcattn(void *v)
{
	struct mntrpc *r;

	r = v;
	return r->done || r->m->rip == 0;
}

struct dev mntdevtab __devtab = {
	.name = "mnt",

	.reset = devreset,
	.init = mntinit,
	.shutdown = devshutdown,
	.attach = mntattach,
	.walk = mntwalk,
	.stat = mntstat,
	.open = mntopen,
	.create = mntcreate,
	.close = mntclose,
	.read = mntread,
	.bread = devbread,
	.write = mntwrite,
	.bwrite = devbwrite,
	.remove = mntremove,
	.wstat = mntwstat,
	.power = devpower,
	.chaninfo = devchaninfo,
};
