~kris/9p

9hist

e55fcb9d82497bf80d4ec37ec8d3d78d05d070b8 — David du Colombier 36 years ago c3c8be8
Plan 9 from Bell Labs 1990-05-11
7 files changed, 218 insertions(+), 102 deletions(-)

M gnot/devmnt.c
M gnot/trap.c
M port/devdk.c
M port/devmnt.c
M port/stream.c
M port/sturp.c
M power/trap.c
M gnot/devmnt.c => gnot/devmnt.c +66 -28
@@ 555,7 555,6 @@ mntxmit(Mnt *m, Mnthdr *mh)
	ulong n;
	Mntbuf *mbr, *mbw;
	Chan *mntpt, *msg;
	int isbit;

	mbr = mballoc();
	mbw = mballoc();


@@ 565,35 564,21 @@ mntxmit(Mnt *m, Mnthdr *mh)
		nexterror();
	}
	n = convS2M(&mh->thdr, mbw->buf);
	isbit = 0;
	if(devchar[m->msg->type] == '3')
		isbit = 1;
	/*
	 * Avoid qlock for bit, to maximize parallelism
	 * Bit3 does its own multiplexing.  (Well, the file server does.)
	 * The code is different enough that it's broken out separately here.
	 */
	if(isbit){
		lock(&m->use);		/* spin rather than sleep */
		if((msg = m->msg) == 0){
			unlock(&m->use);
			error(0, Eshutdown);
		}
		incref(msg);
	if(devchar[m->msg->type] != '3')
		goto Normal;
	lock(&m->use);		/* spin rather than sleep */
	if((msg = m->msg) == 0){
		unlock(&m->use);
	}else{
		qlock(m);
		if((msg = m->msg) == 0){
			qunlock(m);
			error(0, Eshutdown);
		}
		qlock(msg);
		error(0, Eshutdown);
	}
	incref(msg);
	unlock(&m->use);
	if(waserror()){
		if(isbit)
			close(msg);
		else{
			qunlock(m);
			qunlock(msg);
		}
		close(msg);
		nexterror();
	}
	if((*devtab[msg->type].write)(msg, mbw->buf, n) != n){


@@ 605,12 590,65 @@ mntxmit(Mnt *m, Mnthdr *mh)
	 * Read response
	 */
	n = (*devtab[msg->type].read)(msg, mbr->buf, BUFSIZE);
	if(isbit)
		close(msg);
	else{
	close(msg);
	poperror();

	if(convM2S(mbr->buf, &mh->rhdr, n) == 0){
		pprint("format error in mntxmit\n");
		error(0, Egreg);
	}

	/*
	 * Various checks
	 */
	if(mh->rhdr.type != mh->thdr.type+1){
		pprint("type mismatch %d %d\n", mh->rhdr.type, mh->thdr.type+1);
		error(0, Egreg);
	}
	if(mh->rhdr.fid != mh->thdr.fid){
		pprint("fid mismatch %d %d type %d\n", mh->rhdr.fid, mh->thdr.fid, mh->rhdr.type);
		error(0, Egreg);
	}
	if(mh->rhdr.err){
		mntpt = m->mntpt;	/* unsafe, but Errors are unsafe anyway */
		if(mntpt)
			error(mntpt, mh->rhdr.err);
		error(0, Eshutdown);
	}

	/*
	 * Copy out on read
	 */
	if(mh->thdr.type == Tread)
		memcpy(mh->thdr.data, mh->rhdr.data, mh->rhdr.count);
	mbfree(mbr);
	mbfree(mbw);
	poperror();
	return;

    Normal:
	qlock(m);
	if((msg = m->msg) == 0){
		qunlock(m);
		error(0, Eshutdown);
	}
	qlock(msg);
	if(waserror()){
		qunlock(m);
		qunlock(msg);
		nexterror();
	}
	if((*devtab[msg->type].write)(msg, mbw->buf, n) != n){
		pprint("short write in mntxmit\n");
		error(0, Egreg);
	}

	/*
	 * Read response
	 */
	n = (*devtab[msg->type].read)(msg, mbr->buf, BUFSIZE);
	qunlock(m);
	qunlock(msg);
	poperror();

	if(convM2S(mbr->buf, &mh->rhdr, n) == 0){

M gnot/trap.c => gnot/trap.c +17 -9
@@ 259,18 259,26 @@ syscall(Ureg *aur)
#endif
	r0 = ur->r0;
	sp = ur->usp;
	if(r0 >= sizeof systab/BY2WD)
		panic("syscall %d\n", r0);
	if(sp & (BY2WD-1))
		panic("syscall odd sp");
	if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-4*BY2WD))
		validaddr(sp, 4*BY2WD, 0);

	u->nerrlab = 0;
	ret = -1;
	if(!waserror())
		ret = (*systab[r0])((ulong*)(sp+BY2WD));
/* else print("syscall %d err %d %d\n", r0, u->error.type, u->error.code); /**/
	if(!waserror()){
		if(r1 >= sizeof systab/BY2WD){
			pprint("bad sys call number %d pc %lux\n", r1, ((Ureg*)UREGADDR)->pc);
			msg = "bad sys call";
	    Bad:
			postnote(u->p, 1, msg, NDebug);
			error(0, Ebadarg);
		}
		if(sp & (BY2WD-1)){
			pprint("odd sp in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp);
			msg = "odd stack";
			goto Bad;
		}
		if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-4*BY2WD))
			validaddr(ur->sp, 4*BY2WD, 0);
		ret = (*systab[r1])((ulong*)(sp+2*BY2WD));
	}
	u->nerrlab = 0;
	u->p->insyscall = 0;
	if(r0 == NOTED)	/* ugly hack */

M port/devdk.c => port/devdk.c +6 -3
@@ 329,6 329,8 @@ dkstopen(Queue *q, Stream *s)
	q->other->ptr = q->ptr = lp = &dp->line[s->id];
	lp->dp = dp;
	lp->rq = q;
	if(lp->state == Lclosed)
		lp->state = Lopened;
}

/*


@@ 670,7 672,6 @@ dkopen(Chan *c, int omode)
					continue;
				}
				c->qid = STREAMQID(lp-dp->line, Sctlqid);
				qunlock(lp);
				break;
			}
		}


@@ 678,6 679,7 @@ dkopen(Chan *c, int omode)
			error(0, Enodev);
		streamopen(c, &dkinfo);
		pushq(c->stream, &urpinfo);
		qunlock(lp);
		break;
	case Dlistenqid:
		/*


@@ 727,7 729,7 @@ dkclose(Chan *c)
{
	Dk *dp;

	/* real closing happens in lancestclose */
	/* real closing happens in dkstclose */
	if(c->stream)
		streamclose(c);



@@ 899,7 901,7 @@ dkcall(int type, Chan *c, char *addr, char *nuser, char *machine)
	/*
	 *  only dial on virgin lines
	 */
	if(lp->state != Lclosed)
	if(lp->state != Lopened)
		error(0, Ebadarg);

	DPRINT("dkcall(line=%d, type=%d, dest=%s)\n", line, type, addr);


@@ 1202,6 1204,7 @@ dklisten(Chan *c)
		DPRINT("dklisten returns %d\n", lineno);
		return lineno;
	}
	panic("dklisten terminates strangely\n");
}

/*

M port/devmnt.c => port/devmnt.c +66 -28
@@ 555,7 555,6 @@ mntxmit(Mnt *m, Mnthdr *mh)
	ulong n;
	Mntbuf *mbr, *mbw;
	Chan *mntpt, *msg;
	int isbit;

	mbr = mballoc();
	mbw = mballoc();


@@ 565,35 564,21 @@ mntxmit(Mnt *m, Mnthdr *mh)
		nexterror();
	}
	n = convS2M(&mh->thdr, mbw->buf);
	isbit = 0;
	if(devchar[m->msg->type] == '3')
		isbit = 1;
	/*
	 * Avoid qlock for bit, to maximize parallelism
	 * Bit3 does its own multiplexing.  (Well, the file server does.)
	 * The code is different enough that it's broken out separately here.
	 */
	if(isbit){
		lock(&m->use);		/* spin rather than sleep */
		if((msg = m->msg) == 0){
			unlock(&m->use);
			error(0, Eshutdown);
		}
		incref(msg);
	if(devchar[m->msg->type] != '3')
		goto Normal;
	lock(&m->use);		/* spin rather than sleep */
	if((msg = m->msg) == 0){
		unlock(&m->use);
	}else{
		qlock(m);
		if((msg = m->msg) == 0){
			qunlock(m);
			error(0, Eshutdown);
		}
		qlock(msg);
		error(0, Eshutdown);
	}
	incref(msg);
	unlock(&m->use);
	if(waserror()){
		if(isbit)
			close(msg);
		else{
			qunlock(m);
			qunlock(msg);
		}
		close(msg);
		nexterror();
	}
	if((*devtab[msg->type].write)(msg, mbw->buf, n) != n){


@@ 605,12 590,65 @@ mntxmit(Mnt *m, Mnthdr *mh)
	 * Read response
	 */
	n = (*devtab[msg->type].read)(msg, mbr->buf, BUFSIZE);
	if(isbit)
		close(msg);
	else{
	close(msg);
	poperror();

	if(convM2S(mbr->buf, &mh->rhdr, n) == 0){
		pprint("format error in mntxmit\n");
		error(0, Egreg);
	}

	/*
	 * Various checks
	 */
	if(mh->rhdr.type != mh->thdr.type+1){
		pprint("type mismatch %d %d\n", mh->rhdr.type, mh->thdr.type+1);
		error(0, Egreg);
	}
	if(mh->rhdr.fid != mh->thdr.fid){
		pprint("fid mismatch %d %d type %d\n", mh->rhdr.fid, mh->thdr.fid, mh->rhdr.type);
		error(0, Egreg);
	}
	if(mh->rhdr.err){
		mntpt = m->mntpt;	/* unsafe, but Errors are unsafe anyway */
		if(mntpt)
			error(mntpt, mh->rhdr.err);
		error(0, Eshutdown);
	}

	/*
	 * Copy out on read
	 */
	if(mh->thdr.type == Tread)
		memcpy(mh->thdr.data, mh->rhdr.data, mh->rhdr.count);
	mbfree(mbr);
	mbfree(mbw);
	poperror();
	return;

    Normal:
	qlock(m);
	if((msg = m->msg) == 0){
		qunlock(m);
		error(0, Eshutdown);
	}
	qlock(msg);
	if(waserror()){
		qunlock(m);
		qunlock(msg);
		nexterror();
	}
	if((*devtab[msg->type].write)(msg, mbw->buf, n) != n){
		pprint("short write in mntxmit\n");
		error(0, Egreg);
	}

	/*
	 * Read response
	 */
	n = (*devtab[msg->type].read)(msg, mbr->buf, BUFSIZE);
	qunlock(m);
	qunlock(msg);
	poperror();

	if(convM2S(mbr->buf, &mh->rhdr, n) == 0){

M port/stream.c => port/stream.c +4 -3
@@ 78,13 78,14 @@ dumpqueues(void)
			continue;
		for(count = 0, bp = q->first; bp; bp = bp->next)
			count++;
		print("%s %ux  RD count %d len %d", q->info->name, q, count, q->len);
		print("%s %ux  R c %d l %d f %ux", q->info->name, q, count,
			q->len, q->flag);
		for(count = 0, bp = WR(q)->first; bp; bp = bp->next)
			count++;
		print("  WR count %d len %d\n", count, WR(q)->len);
		print("  W c %d l %d f %ux\n", count, WR(q)->len, WR(q)->flag);
	}
	print("\n");
	for(bcp=bclass; bcp<&bclass[Nclass-1]; bcp++){
	for(bcp=bclass; bcp<&bclass[Nclass]; bcp++){
		lock(bcp);
		for(count = 0, bp = bcp->first; bp; count++, bp = bp->next)
			;

M port/sturp.c => port/sturp.c +41 -23
@@ 48,7 48,6 @@ struct Urp {
	int	blocks;

	/* output */

	QLock	xmit;		/* output lock, only one process at a time */
	Queue	*wq;		/* output queue */
	int	maxout;		/* maximum outstanding unacked blocks */


@@ 60,6 59,7 @@ struct Urp {
	Block	*xb[8];		/* the xmit window buffer */
	QLock	xl[8];
	ulong	timer;		/* timeout for xmit */
	int	rexmit;

	int	kstarted;
};


@@ 168,14 168,6 @@ isflushed(void *a)
	up = (Urp *)a;
	return (up->state&HUNGUP) || (up->unechoed==up->nxb && up->wq->len==0);
}
static int
isdead(void *a)
{
	Urp *up;

	up = (Urp *)a;
	return up->kstarted == 0;
}
static void
urpclose(Queue *q)
{


@@ 219,8 211,10 @@ urpclose(Queue *q)
		}
	qunlock(&up->xmit);

	if(up->kstarted == 0)
	if(up->kstarted == 0){
		DPRINT("urpclose %ux\n", up);
		up->state = 0;
	}
}

/*


@@ 471,6 465,10 @@ urpiput(Queue *q, Block *bp)
			urpstat.rjseq++;
			sendrej(up);
			break;
		} else if(q->next->len > (3*Streamhi)/2
			|| q->next->nb > (3*Streambhi)/2) {
			flushinput(up);
			break;
		}

		/*


@@ 559,6 557,7 @@ output(Urp *up)
	ulong now;
	Queue *q;
	int n;
	int i;

	if(!canqlock(&up->xmit))
		return;


@@ 607,8 606,7 @@ output(Urp *up)
	/*
	 *  if a retransmit time has elapsed since a transmit, send an ENQ
	 */
	if(up->unechoed != up->next && NOW > up->timer){
		DPRINT("sENQ\n");
	if(up->unechoed!=up->next && NOW>up->timer){
		up->timer = NOW + MSrexmit;
		up->state &= ~REJECTING;
		sendctl(up, ENQ);


@@ 620,11 618,21 @@ output(Urp *up)
	/*
	 *  if there's a window open, push some blocks out
	 */
	while(WINDOW(up)>0 && up->xb[up->next]!=0 && canqlock(&up->xl[up->next])){
		if(up->xb[up->next])
			sendblock(up, up->next);
		qunlock(&up->xl[up->next]);
	if(up->rexmit){
		up->rexmit = 0;
		up->next = up->unechoed;
	}
	while(WINDOW(up)>0 && up->xb[up->next]!=0){
		i = up->next;
		qlock(&up->xl[i]);
		if(waserror()){
			qunlock(&up->xl[i]);
			nexterror();
		}
		sendblock(up, i);
		qunlock(&up->xl[i]);
		up->next = NEXT(up->next);
		poperror();
	}
	qunlock(&up->xmit);
	poperror();


@@ 745,6 753,7 @@ rcvack(Urp *up, int msg)
{
	int seqno;
	int next;
	int i;

	seqno = msg&Nmask;
	next = NEXT(seqno);


@@ 754,11 763,12 @@ rcvack(Urp *up, int msg)
	 */
	if(IN(seqno, up->unacked, up->next)){
		for(; up->unacked != next; up->unacked = NEXT(up->unacked)){
			qlock(&up->xl[up->unacked]);
			if(up->xb[up->unacked])
				freeb(up->xb[up->unacked]);
			up->xb[up->unacked] = 0;
			qunlock(&up->xl[up->unacked]);
			i = up->unacked;
			qlock(&up->xl[i]);
			if(up->xb[i])
				freeb(up->xb[i]);
			up->xb[i] = 0;
			qunlock(&up->xl[i]);
		}
	}



@@ 786,7 796,7 @@ rcvack(Urp *up, int msg)
		 */
		if(up->unechoed==next && !(up->state & REJECTING)){
			up->state |= REJECTING;
			up->next = next;
			up->rexmit = 1;
		}
		break;
	}


@@ 831,6 841,7 @@ initoutput(Urp *up, int window)
	up->unacked = 1;
	up->next = 1;
	up->nxb = 1;
	up->rexmit = 0;

	/*
	 *  free any outstanding blocks


@@ 886,6 897,7 @@ urpkproc(void *arg)
	up = (Urp *)arg;

	if(waserror()){
		print("urpkproc error %ux\n", up);
		up->state = 0;
		up->kstarted = 0;
		wakeup(&up->r);


@@ 898,10 910,16 @@ urpkproc(void *arg)
			if(up->state & HUNGUP)
				break;
		}
		sendack(up);
		if(up->state == 0){
			DPRINT("urpkproc: %ux->state == 0\n", up);
			break;
		}
		if(!QFULL(up->rq->next))
			sendack(up);
		output(up);
		tsleep(&up->rq->r, todo, up, MSrexmit/2);
	}
	up->state = 0;
	up->kstarted = 0;
	DPRINT("urpkproc %ux\n", up);
}

M power/trap.c => power/trap.c +18 -8
@@ 5,6 5,7 @@
#include	"fns.h"
#include	"ureg.h"
#include	"io.h"
#include	"errno.h"

/*
 *  vme interrupt routines


@@ 418,6 419,7 @@ syscall(Ureg *aur)
	ulong sp;
	ulong r1;
	Ureg *ur;
	char *msg;

	u->p->insyscall = 1;
	ur = aur;


@@ 433,17 435,25 @@ syscall(Ureg *aur)
	spllo();
	r1 = ur->r1;
	sp = ur->sp;
	if(r1 >= sizeof systab/BY2WD)
		panic("syscall %d\n", r1);
	if(sp & (BY2WD-1))
		panic("syscall odd sp");
	if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-4*BY2WD))
		validaddr(ur->sp, 4*BY2WD, 0);

	u->nerrlab = 0;
	ret = -1;
	if(!waserror())
	if(!waserror()){
		if(r1 >= sizeof systab/BY2WD){
			pprint("bad sys call number %d pc %lux\n", r1, ((Ureg*)UREGADDR)->pc);
			msg = "bad sys call";
	    Bad:
			postnote(u->p, 1, msg, NDebug);
			error(0, Ebadarg);
		}
		if(sp & (BY2WD-1)){
			pprint("odd sp in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp);
			msg = "odd stack";
			goto Bad;
		}
		if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-4*BY2WD))
			validaddr(ur->sp, 4*BY2WD, 0);
		ret = (*systab[r1])((ulong*)(sp+2*BY2WD));
	}
	ur->pc += 4;
	u->nerrlab = 0;
	splhi();