#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 <plan9.h>
#include <fcall.h>

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

/* practical data limit: maxioatomic - IOHDRSZ */
#define MAXRPC (IOHDRSZ+6*8192)

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

enum
{
	TAGSHIFT = 5,			/* uint32_t has to be 32 bits */
	TAGMASK = (1<<TAGSHIFT)-1,
	NMASK = (64*1024)>>TAGSHIFT,
};

struct mntalloc
{
	spinlock_t lock;
	struct mnt*	list;		/* Mount devices in use */
	struct mnt*	mntfree;	/* Free list */
	struct mntrpc*	rpcfree;
	int	nrpcfree;
	int	nrpcused;
	unsigned int	id;
	uint32_t	tagmask[NMASK];
}mntalloc;

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);

char	Esbadstat[] = "invalid directory entry received from server";
char	Enoversion[] = "version not established for mount channel";


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

static void
mntreset(void)
{
	mntalloc.id = 1;
	mntalloc.tagmask[0] = 1;			/* don't allow 0 as a tag */
	mntalloc.tagmask[NMASK-1] = 0x80000000UL;	/* don't allow NOTAG */
	spinlock_init(&mntalloc.lock);
	//fmtinstall('F', fcallfmt);
	//fmtinstall('D', dirfmt);
/* We can't install %M since eipfmt does and is used in the kernel [sape] */
	/* no caching. 
	if(mfcinit != NULL)
		mfcinit();
	*/
}

/*
 * Version is not multiplexed: message sent only once per connection.
 */
unsigned long
mntversion(struct chan *c, uint32_t msize, char *version, unsigned long returnlen)
{
	ERRSTACK(2);
	struct fcall f;
	uint8_t *msg;
	struct mnt *mnt;
	char *v;
	long l, n;
	unsigned long k;
	int64_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("bad iounit in version call");
	if(strncmp(v, VERSION9P, strlen(VERSION9P)) != 0)
		error("bad 9P version specification");

	mnt = c->mux;

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

//		strecpy(buf, buf+sizeof buf, mnt->version);
		strncpy(buf, mnt->version, sizeof(buf));
		k = strlen(buf);
		if(strncmp(buf, v, k) != 0){
			snprintf(buf, sizeof buf, "incompatible 9P versions %s %s", mnt->version, v);
			error(buf);
		}
		if(returnlen != 0){
			if(returnlen < k)
				error(Eshort);
			memmove(version, buf, k);
		}
		return k;
	}

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

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

	l = c->dev->write(c, msg, k, oo);

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

	/* message sent; receive and decode reply */
	n = c->dev->read(c, msg, MAXRPC, c->offset);
	if(n <= 0)
		error("EOF receiving fversion reply");

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

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

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

	if(returnlen != 0){
		if(returnlen < k)
			error(Eshort);
		memmove(version, f.version, k);
	}

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

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

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

	poperror();	/* c */
	qunlock(&c->umqlock);

	return k;
}

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

	mnt = c->mux;

	if(mnt == NULL){
		mntversion(c, MAXRPC, VERSION9P, 0);
		mnt = c->mux;
		if(mnt == NULL)
			error(Enoversion);
	}

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

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

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

	r->request.type = Tauth;
	r->request.afid = c->fid;
	r->request.uname = "eve";//up->user;
	r->request.aname = spec;
	mountrpc(mnt, r);

	c->qid = r->reply.aqid;
	c->mchan = mnt->c;
	kref_get(&mnt->c->ref, 1);
	c->mqid = c->qid;
	c->mode = ORDWR;

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

	poperror();	/* c */

	return c;

}

static struct chan*
mntattach(char *muxattach)
{
	ERRSTACK(2);
	struct mnt *mnt;
	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;

	mnt = c->mux;

	if(mnt == NULL){
		mntversion(c, 0, NULL, 0);
		mnt = c->mux;
		if(mnt == NULL)
			error(Enoversion);
	}

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

	r = mntralloc(0, mnt->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 = "eve"; //up->user;
	r->request.aname = bogus.spec;
	mountrpc(mnt, r);

	c->qid = r->reply.qid;
	c->mchan = mnt->c;
	kref_get(&mnt->c->ref, 1);
	c->mqid = c->qid;

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

	poperror();	/* c */
/*
	if((bogus.flags & MCACHE) && mfcinit != NULL)
		c->flag |= CCACHE;
*/
	return c;
}

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

	c = devattach('M', "");
	spin_lock(&(&mntalloc)->lock);
	c->devno = mntalloc.id++;
	spin_unlock(&(&mntalloc)->lock);

	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);
	int i, alloc;
	struct mnt *mnt;
	struct mntrpc *r;
	struct walkqid *wq;

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

	alloc = 0;
	mnt = mntchk(c);
	r = mntralloc(c, mnt->msize);
	if(nc == NULL){
		nc = devclone(c);
		/*
		 * Until the other side accepts this fid,
		 * we can't mntclose it.
		 * nc->dev remains NULL for now.
		 */
		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(mnt, r);

	if(r->reply.nwqid > nname)
		error("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->dev = c->dev;
			//if(wq->clone->dev != NULL)	//XDYNX
			//	devtabincr(wq->clone->dev);
			wq->clone->mchan = c->mchan;
			kref_get(&c->mchan->ref, 1);
		}
		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 long
mntstat(struct chan *c, uint8_t *dp, long n)
{
	ERRSTACK(1);
	struct mnt *mnt;
	struct mntrpc *r;
	unsigned long nstat;

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

	if(r->reply.nstat > n){
		nstat = BIT16SZ;
		PBIT16(dp, r->reply.nstat-2);
	}else{
		nstat = r->reply.nstat;
		memmove(dp, r->reply.stat, nstat);
		validstat(dp, nstat);
		mntdirfix(dp, c);
	}
	poperror();
	mntfree(r);

	return nstat;
}

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

	mnt = mntchk(c);
	r = mntralloc(c, mnt->msize);
	if(waserror()) {
		mntfree(r);
		nexterror();
	}
	r->request.type = type;
	r->request.fid = c->fid;
	r->request.mode = omode;
	if(type == Tcreate){
		r->request.perm = perm;
		r->request.name = name;
	}
	mountrpc(mnt, r);

	c->qid = r->reply.qid;
	c->offset = 0;
	c->mode = openmode(omode);
	c->iounit = r->reply.iounit;
	if(c->iounit == 0 || c->iounit > mnt->msize-IOHDRSZ)
		c->iounit = mnt->msize-IOHDRSZ;
	c->flag |= COPEN;
	poperror();
	mntfree(r);
/*
	if(c->flag & CCACHE)
		mfcopen(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, int perm)
{
	mntopencreate(Tcreate, c, name, omode, perm);
}

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

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

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

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

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

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

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

	qfree(q);
}

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

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

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

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

static long
mntread(struct chan *c, void *buf, long n, int64_t off)
{
	uint8_t *p, *e;
	int nc, cache, isdir;
	unsigned long dirlen;

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

	p = buf;
#if 0
	if(cache) {
		nc = mfcread(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);
		mfcupdate(c, p, n, off);
		return n + nc;
	}
#endif
	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);
			mntdirfix(p, c);
		}
		if(p != e)
			error(Esbadstat);
	}
	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 *mnt;
 	struct mntrpc *r;
	char *uba;
	int cache;
	uint32_t cnt, nr, nreq;

	mnt = mntchk(c);
	uba = buf;
	cnt = 0;
	cache = c->flag & CCACHE;
	if(c->qid.type & QTDIR)
		cache = 0;
	for(;;) {
		r = mntralloc(c, mnt->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 > mnt->msize-IOHDRSZ)
			nr = mnt->msize-IOHDRSZ;
		r->request.count = nr;
		mountrpc(mnt, 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);
#if 0
		else if(cache)
			mfcwrite(c, ( uint8_t *)uba, nr, off);
#endif

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

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

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

	mountio(mnt, r);

	t = r->reply.type;
	switch(t) {
	case Rerror:
		error(r->reply.ename);
	case Rflush:
		error(Eintr);
	default:
		if(t == r->request.type+1)
			break;
		sn = "?";
		if(mnt->c->path != NULL)
			sn = mnt->c->path->s;
		cn = "?";
		if(r->c != NULL && r->c->path != NULL)
			cn = r->c->path->s;
		printd("mnt: proc %s %d: mismatch from %s %s rep %#p tag %d fid %d T%d R%d rp %d\n",
			up->text, up->pid, sn, cn,
			r, r->request.tag, r->request.fid, r->request.type,
			r->reply.type, r->reply.tag);
		error(Emountrpc);
	}
}

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

	/* holy crap, while waserror! */
	while(waserror()) {
		if(mnt->rip == current)
			mntgate(mnt);
		if(/*strcmp(up->errstr, Eintr) != 0*/1){
			mntflushfree(mnt, r);
			nexterror();
		}
		r = mntflushalloc(r, mnt->msize);
		/* match the waserror, for each loop */
		poperror();
	}

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

	/* Transmit a file system rpc */
	if(mnt->msize == 0)
		panic("msize");
	n = convS2M(&r->request, r->rpc, mnt->msize);
	if(n < 0)
		panic("bad message type in mountio");
	if(mnt->c->dev->write(mnt->c, r->rpc, n, 0) != n)
		error(Emountrpc);
	r->stime = read_tsc_serialized();//fastticks(NULL);
	r->reqlen = n;

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

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

	while(qlen(mnt->q) < len){
		b = mnt->c->dev->bread(mnt->c, mnt->msize, 0);
		if(b == NULL)
			return -1;
		if(blocklen(b) == 0){
			freeblist(b);
			return -1;
		}
		qaddlist(mnt->q, b);
	}
	return 0;
}

int
mntrpcread(struct mnt *mnt, 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(mnt, BIT32SZ+BIT8SZ+BIT16SZ) < 0)
		return -1;
	nb = pullupqueue(mnt->q, BIT32SZ+BIT8SZ+BIT16SZ);

	/* read in the rest of the message, avoid ridiculous (for now) message sizes */
	len = GBIT32(nb->rp);
	if(len > mnt->msize){
		qdiscard(mnt->q, qlen(mnt->q));
		return -1;
	}
	if(doread(mnt, 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(mnt->q, hlen);

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

	/* hang the data off of the fcall struct */
	l = &r->b;
	*l = NULL;
	do {
		b = qremove(mnt->q);
		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 = allocb(i-len);
			memmove(nb->wp, b->rp+len, i-len);
			b->wp = b->rp+len;
			nb->wp += i-len;
			qputback(mnt->q, nb);
			*l = b;
			return 0;
		}
	}while(len > 0);

	return 0;
}

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

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

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

	spin_lock(&mnt->lock);
	l = &mnt->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;
			if(mntstats != NULL)
				(*mntstats)(q->request.type,
					mnt->c, q->stime,
					q->reqlen + r->replen);
			if(q != r)
				rendez_wakeup(&q->r);
			spin_unlock(&mnt->lock);
			return;
		}
		l = &q->list;
	}
	spin_unlock(&mnt->lock);
	printd("unexpected reply tag %ud; 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 *mnt, struct mntrpc *r)
{
	struct mntrpc *fr;

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

int
alloctag(void)
{
	int i, j;
	uint32_t v;

	for(i = 0; i < NMASK; i++){
		v = mntalloc.tagmask[i];
		if(v == ~0UL)
			continue;
		for(j = 0; j < 1<<TAGSHIFT; j++)
			if((v & (1<<j)) == 0){
				mntalloc.tagmask[i] |= 1<<j;
				return (i<<TAGSHIFT) + j;
			}
	}
	panic("no friggin tags left");
	return NOTAG;
}

void
freetag(int t)
{
	mntalloc.tagmask[t>>TAGSHIFT] &= ~(1<<(t&TAGMASK));
}

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

	spin_lock(&(&mntalloc)->lock);
	new = mntalloc.rpcfree;
	if(new == NULL){
		new = kzmalloc(sizeof(struct mntrpc), 0);
		if(new == NULL) {
			spin_unlock(&(&mntalloc)->lock);
			panic/*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, KMALLOC_WAIT);
		if(new->rpc == NULL){
			kfree(new);
			spin_unlock(&(&mntalloc)->lock);
			panic/*exhausted*/("mount rpc buffer");
		}
		new->rpclen = msize;
		new->request.tag = alloctag();
	}
	else {
		mntalloc.rpcfree = new->list;
		mntalloc.nrpcfree--;
		if(new->rpclen < msize){
			kfree(new->rpc);
			new->rpc = kzmalloc(msize, 0);
			if(new->rpc == NULL){
				kfree(new);
				mntalloc.nrpcused--;
				spin_unlock(&(&mntalloc)->lock);
				panic/*exhausted*/("mount rpc buffer");
			}
			new->rpclen = msize;
		}
	}
	mntalloc.nrpcused++;
	spin_unlock(&(&mntalloc)->lock);
	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)->lock);
	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)->lock);
}

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

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

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

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

	/* 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", chanpath(c));

	mnt = c->mchan->mux;

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

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

	return mnt;
}

/*
 * 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)
{
	unsigned int r;

	r = c->dev->dc;
	dirbuf += BIT16SZ;	/* skip count */
	PBIT16(dirbuf, r);
	dirbuf += BIT16SZ;
	PBIT32(dirbuf, c->devno);
}

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

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

struct dev mntdevtab = {
	'M',
	"mnt",

	mntreset,
	devinit,
	devshutdown,
	mntattach,
	mntwalk,
	mntstat,
	mntopen,
	mntcreate,
	mntclose,
	mntread,
	devbread,
	mntwrite,
	devbwrite,
	mntremove,
	mntwstat,
	devpower,
	devconfig,
	devchaninfo,
};
