/* 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 <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 <net/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);
size_t mntrdwr(int unused_int, struct chan *, void *, size_t, off64_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);  */
}

/*
 * 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;
	/* This assumes we're called from a syscall, which should always be true. */
	if (!current_kthread->sysc)
		warn("Kthread %s didn't have a syscall, current is %s",
		     current_kthread->name, current ? current->progname : NULL);
	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 mntparam *params = (struct mntparam *)muxattach;

	c = params->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 (params->authchan == NULL)
		r->request.afid = NOFID;
	else
		r->request.afid = params->authchan->fid;
	/* This assumes we're called from a syscall, which should always be true. */
	if (!current_kthread->sysc)
		warn("Kthread %s didn't have a syscall, current is %s",
		     current_kthread->name, current ? current->progname : NULL);
	r->request.uname = current->user.name;
	r->request.aname = params->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 */
	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,
							   unsigned 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 size_t mntstat(struct chan *c, uint8_t *dp, size_t 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);

	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,
                      char *ext)
{
	/* TODO: support extensions for e.g. symlinks */
	if (perm & DMSYMLINK)
		error(EINVAL, "#%s doesn't support symlinks", devname());
	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 size_t mntwstat(struct chan *c, uint8_t *dp, size_t 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 size_t mntread(struct chan *c, void *buf, size_t n, off64_t off)
{
	uint8_t *p, *e;
	int nc, dirlen;
	int numdirent = 0;


	p = buf;

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

	if (c->qid.type & QTDIR) {
		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 size_t mntwrite(struct chan *c, void *buf, size_t n, off64_t off)
{
	return mntrdwr(Twrite, c, buf, n, off);
}

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

	m = mntchk(c);
	uba = buf;
	cnt = 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);

		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;
			warn("mnt: mismatch from %s %s rep %p tag %d fid %d T%d R%d rp %d\n",
				 sn, cn, r, r->request.tag,
				 r->request.fid, r->request.type, r->reply.type, r->reply.tag);
			error(EPROTO, ERROR_FIXME);
	}
}

static bool kth_proc_is_dying(struct kthread *kth)
{
	return kth->proc ? proc_is_dying(kth->proc) : false;
}

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

	while (waserror()) {
		if (m->rip == current_kthread)
			mntgate(m);
		/* Syscall aborts are like Plan 9 Eintr.  For those, we need to change
		 * the old request to a flush (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.  We might not
		 * always have a process (RKM chan_release), but in that case we're fine
		 * - we're not preventing a process from dying. */
		if ((get_errno() != EINTR) || kth_proc_is_dying(current_kthread)) {
			/* 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_kthread;
	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,
};
