~kris/9p

9hist

50dc394bd51f80f9e93e730e301958a8e03a0926 — David du Colombier 36 years ago 6b920f7
Plan 9 from Bell Labs 1990-06-17
M gnot/devcons.c => gnot/devcons.c +6 -0
@@ 188,6 188,8 @@ echo(int c)
		return;
	if(c == 0x15)
		putstrn("^U\n", 3);
	if(c == 0x16)
		dumpqueues();
	else{
		ch = c;
		putstrn(&ch, 1);


@@ 399,6 401,10 @@ consread(Chan *c, void *buf, long n)
	case Qrcons:
	case Qcons:
		qlock(&kbdq);
		if(waserror()){
			qunlock(&kbdq);
			nexterror();
		}
		while(!cangetc(&lineq)){
			sleep(&kbdq.r, (int(*)(void*))isbrkc, &kbdq);
			do{

M gnot/devdk.c => gnot/devdk.c +10 -2
@@ 66,7 66,7 @@ struct Dkmsg {
#define	  D_OK		1		/* not used */
#define	  D_OPEN	2		/* (dkmux to host) connection established */
#define	  D_FAIL	3		/* (dkmux to host) connection failed */
#define	T_CHG	3		/* linege the status of a connection */
#define	T_CHG	3		/* change the status of a connection */
#define	  D_CLOSE	1		/* close the connection */
#define	  D_ISCLOSED	2		/* (dkmux to host) confirm a close */
#define	  D_CLOSEALL	3		/* (dkmux to host) close all connections */


@@ 1003,7 1003,7 @@ dkcall(int type, Chan *c, char *addr, char *nuser, char *machine)
	}

	/*
	 *  linege state if serving
	 *  change state if serving
	 */
	if(type == D_SERV){
		lp->state = Llistening;


@@ 1075,7 1075,9 @@ dklisten(Chan *c)
		n = streamread(dc, dialstr, sizeof(dialstr)-1);
		DPRINT("returns %d\n", n);
		if(n <= 0)
{print("bad n\n");
			error(0, Eio);
}
		dialstr[n] = 0;
		DPRINT("dialstr = %s\n", dialstr);



@@ 1085,6 1087,7 @@ dklisten(Chan *c)
		n = getfields(dialstr, line, 12, '\n');
		if (n < 2) {
			DPRINT("bad dialstr from dk (1 line)\n");
print("bad dialstr %d '%s'\n", n, dialstr);
			error(0, Eio);
		}



@@ 1291,6 1294,11 @@ dkcsckproc(void *a)
	dp = (Dk *)a;

	/*
	 *  tell datakit we've rebooted. It should close all channels.
	 */
	dkmesg(dp, T_CHG, D_CLOSEALL, 0, 0);

	/*
	 *  loop forever listening
	 */
	for(;;){

M gnot/devmnt.c => gnot/devmnt.c +12 -14
@@ 65,6 65,7 @@ struct
struct
{
	Lock;
	QLock;
	MntQ	*arena;
	MntQ	*free;
}mntqalloc;


@@ 141,22 142,21 @@ mhfree(Mnthdr *mh)
}

MntQ*
mqalloc(void)
mqalloc(Chan *msg)	/* mntqalloc is qlocked */
{
	MntQ *q;

	lock(&mntqalloc);
	if(q = mntqalloc.free){		/* assign = */
		mntqalloc.free = q->next;
		unlock(&mntqalloc);
		lock(q);
		q->ref = 1;
		q->msg = msg;
		unlock(q);
		incref(msg);
		q->writer = 0;
		q->reader = 0;
		unlock(q);
		return q;
	}
	unlock(&mntqalloc);
	panic("no mntqs\n");			/* there MUST be enough */
}



@@ 167,7 167,7 @@ mqfree(MntQ *mq)

	lock(mq);
	if(--mq->ref == 0){
print("mqfree\n");
print("mqfree %lux %lux\n", mq->reader, mq->writer);
		msg = mq->msg;
		mq->msg = 0;
		lock(&mntqalloc);


@@ 272,6 272,7 @@ mntattach(char *spec)
	 * Look for queue to same msg channel
	 */
	q = mntqalloc.arena;
	qlock(&mntqalloc);
	for(i=0; i<conf.nmntdev; i++,q++)
		if(q->msg==cm){
			lock(q);


@@ 283,11 284,10 @@ mntattach(char *spec)
			}
			unlock(q);
		}
	m->q = mqalloc();
	m->q->msg = cm;
	incref(cm);
	m->q = mqalloc(cm);

    out:
	qunlock(&mntqalloc);
	mh = mhalloc();
	if(waserror()){
		mhfree(mh);


@@ 645,7 645,6 @@ mnterrdequeue(MntQ *q, Mnthdr *mh)		/* queue is unlocked */
	qlock(q);
	/* take self from queue if necessary */
	if(q->reader == u->p){	/* advance a writer to reader */
print("err: reader\n");
		w = q->writer;
		if(w){
			q->reader = w->p;


@@ 656,7 655,6 @@ print("err: reader\n");
			q->writer = 0;
		}
	}else{
print("err: writer\n");
		w = q->writer;
		if(w == mh)
			q->writer = w->next;


@@ 774,7 772,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
		qlocked = 0;
		n = (*devtab[q->msg->type].read)(q->msg, mbr->buf, BUFSIZE);
		if(convM2S(mbr->buf, &mh->rhdr, n) == 0){
			print("format error in mntxmit\n");
			print("%lux %lux %lux %d format error in mntxmit %s\n", u->p, q->reader, q->writer, n, u->p->text);
			mnterrdequeue(q, mh);
			error(0, Ebadmsg);
		}


@@ 798,7 796,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
		/*
		 * Hand response to correct recipient
		 */
if(q->writer == 0) print("response with empty queue\n");
if(q->writer == 0) print("response with empty queue %d %d %d: %d %d\n", mh->rhdr.type, mh->rhdr.err, mh->rhdr.fid, mh->thdr.type, mh->thdr.fid);
		for(ow=0,w=q->writer; w; ow=w,w=w->next)
			if(mh->rhdr.fid == w->thdr.fid
			&& mh->rhdr.type == w->thdr.type+1){


@@ 825,7 823,7 @@ if(q->writer == 0) print("response with empty queue\n");
		qunlock(q);
		qlocked = 0;
		if(waserror()){		/* interrupted sleep */
			print("interrupted i/o\n");
			print("%lux interrupted i/o %d %d\n", u->p, mh->thdr.type, mh->thdr.fid);
			mnterrdequeue(q, mh);
			nexterror();
		}

M gnot/devpipe.c => gnot/devpipe.c +1 -4
@@ 92,22 92,19 @@ pipeopen(Chan *c, int omode)
void
pipecreate(Chan *c, char *name, int omode, ulong perm)
{
	print("pipecreate\n");
	error(0, Egreg);
}

void
piperemove(Chan *c)
{
	print("piperemove\n");
	error(0, Egreg);
}

void
pipewstat(Chan *c, char *db)
{
	print("pipewstat\n");
	error(0, Egreg);
	error(0, Eperm);
}

void

M gnot/devproc.c => gnot/devproc.c +1 -1
@@ 263,7 263,7 @@ procread(Chan *c, void *va, long n)
		}

		/* u area */
		if(c->offset>=USERADDR && c->offset<=USERADDR+BY2PG){
		if(c->offset>=USERADDR && c->offset<USERADDR+BY2PG){
			if(c->offset+n > USERADDR+BY2PG)
				n = USERADDR+BY2PG - c->offset;
			pg = p->upage;

M gnot/fault.c => gnot/fault.c +13 -6
@@ 280,19 280,26 @@ fault(Ureg *ur, FFrame *f)
void
validaddr(ulong addr, ulong len, int write)
{
	Seg *s;
	Seg *s, *ns;

	if((long)len < 0)
		goto Err;
	s = seg(u->p, addr);
	if(s==0 || addr+len>s->maxva || (write && (s->o->flag&OWRPERM)==0)){
	if((long)len < 0){
    Err:
		pprint("invalid address in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp);
		postnote(u->p, 1, "bad address", NDebug);
		error(0, Ebadarg);
	}
    Again:
	s = seg(u->p, addr);
	if(s==0)
		goto Err;
	if(write && (s->o->flag&OWRPERM)==0)
		goto Err;
	if(addr+len > s->maxva){
		len -= s->maxva - addr;
		addr = s->maxva;
		goto Again;
	}
}

/*
 * &s[0] is known to be a valid address.
 */

M gnot/lock.c => gnot/lock.c +4 -6
@@ 4,7 4,7 @@
#include "dat.h"
#include "fns.h"

#define PCOFF -2
#define PCOFF -1

/*
 *  N.B.  Ken's compiler generates a TAS instruction for the sequence:


@@ 25,13 25,13 @@ lock(Lock *l)
	 */
    	if(l->key >= 0){
		l->key |= 0x80;
		l->pc = ((ulong*)&i)[PCOFF];
		l->pc = ((ulong*)&l)[PCOFF];
		return;
	}
	for(i=0; i<10000000; i++)
    		if(l->key >= 0){
			l->key |= 0x80;
			l->pc = ((ulong*)&i)[PCOFF];
			l->pc = ((ulong*)&l)[PCOFF];
			return;
		}
	l->key = 0;


@@ 41,11 41,9 @@ lock(Lock *l)
int
canlock(Lock *l)
{
	int i;

	if(l->key >= 0){
		l->key |= 0x80;
		l->pc = ((ulong*)&i)[PCOFF];
		l->pc = ((ulong*)&l)[PCOFF];
		return 1;
	}
	return 0;

M gnot/main.c => gnot/main.c +1 -1
@@ 289,7 289,7 @@ confinit(void)
	conf.base1 = 16*1024*1024;
	conf.npage = conf.npage0+conf.npage1;
	mul = 1 + (conf.npage1>0);
	conf.nproc = 32*mul;
	conf.nproc = 40*mul;
	conf.npgrp = 15*mul;
	conf.npte = 700*mul;
	conf.nmod = 400*mul;

M port/chan.c => port/chan.c +0 -1
@@ 127,7 127,6 @@ mountsplit(Mount *omnt)
{
	Mount *nmnt;

	print("mount copy on write\n");
	nmnt = newmount();
	lock(nmnt);
	nmnt->term = omnt->term;

M port/devcons.c => port/devcons.c +5 -1
@@ 425,6 425,10 @@ consread(Chan *c, void *buf, long n)

	case Qcons:
		qlock(&kbdq);
		if(waserror()){
			qunlock(&kbdq);
			nexterror();
		}
		while(!cangetc(&lineq)){
			sleep(&kbdq.r, (int(*)(void*))isbrkc, &kbdq);
			do{


@@ 486,7 490,7 @@ consread(Chan *c, void *buf, long n)
		return readnum(c->offset, buf, n, u->p->parentpid, NUMSIZE);

	case Qtime:
		return readnum(c->offset, buf, n, boottime+TK2MS(MACHP(0)->ticks), 12);
		return readnum(c->offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), 12);

	case Quser:
		return readstr(c->offset, buf, n, u->p->pgrp->user);

M port/devdk.c => port/devdk.c +11 -2
@@ 66,7 66,7 @@ struct Dkmsg {
#define	  D_OK		1		/* not used */
#define	  D_OPEN	2		/* (dkmux to host) connection established */
#define	  D_FAIL	3		/* (dkmux to host) connection failed */
#define	T_CHG	3		/* linege the status of a connection */
#define	T_CHG	3		/* change the status of a connection */
#define	  D_CLOSE	1		/* close the connection */
#define	  D_ISCLOSED	2		/* (dkmux to host) confirm a close */
#define	  D_CLOSEALL	3		/* (dkmux to host) close all connections */


@@ 1003,7 1003,7 @@ dkcall(int type, Chan *c, char *addr, char *nuser, char *machine)
	}

	/*
	 *  linege state if serving
	 *  change state if serving
	 */
	if(type == D_SERV){
		lp->state = Llistening;


@@ 1075,7 1075,9 @@ dklisten(Chan *c)
		n = streamread(dc, dialstr, sizeof(dialstr)-1);
		DPRINT("returns %d\n", n);
		if(n <= 0)
{print("bad n\n");
			error(0, Eio);
}
		dialstr[n] = 0;
		DPRINT("dialstr = %s\n", dialstr);



@@ 1085,6 1087,7 @@ dklisten(Chan *c)
		n = getfields(dialstr, line, 12, '\n');
		if (n < 2) {
			DPRINT("bad dialstr from dk (1 line)\n");
print("bad dialstr %d '%s'\n", n, dialstr);
			error(0, Eio);
		}



@@ 1291,6 1294,12 @@ dkcsckproc(void *a)
	dp = (Dk *)a;

	/*
	 *  tell datakit we've rebooted. It should close all channels.
	 */
	dkmesg(dp, T_ALIVE, D_RESTART, 0, 0);	/* do this on mips but not 68020 */
	dkmesg(dp, T_CHG, D_CLOSEALL, 0, 0);

	/*
	 *  loop forever listening
	 */
	for(;;){

M port/devmnt.c => port/devmnt.c +11 -11
@@ 141,22 141,21 @@ mhfree(Mnthdr *mh)
}

MntQ*
mqalloc(void)
mqalloc(Chan *msg)	/* mntqalloc is locked */
{
	MntQ *q;

	lock(&mntqalloc);
	if(q = mntqalloc.free){		/* assign = */
		mntqalloc.free = q->next;
		unlock(&mntqalloc);
		lock(q);
		q->ref = 1;
		q->msg = msg;
		unlock(q);
		incref(msg);
		q->writer = 0;
		q->reader = 0;
		unlock(q);
		return q;
	}
	unlock(&mntqalloc);
	panic("no mntqs\n");			/* there MUST be enough */
}



@@ 167,6 166,7 @@ mqfree(MntQ *mq)

	lock(mq);
	if(--mq->ref == 0){
print("mqfree %lux %lux\n", mq->reader, mq->writer);
		msg = mq->msg;
		mq->msg = 0;
		lock(&mntqalloc);


@@ 271,6 271,7 @@ mntattach(char *spec)
	 * Look for queue to same msg channel
	 */
	q = mntqalloc.arena;
	lock(&mntqalloc);
	for(i=0; i<conf.nmntdev; i++,q++)
		if(q->msg==cm){
			lock(q);


@@ 282,11 283,10 @@ mntattach(char *spec)
			}
			unlock(q);
		}
	m->q = mqalloc();
	m->q->msg = cm;
	incref(cm);
	m->q = mqalloc(cm);

    out:
	unlock(&mntqalloc);
	mh = mhalloc();
	if(waserror()){
		mhfree(mh);


@@ 771,7 771,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
		qlocked = 0;
		n = (*devtab[q->msg->type].read)(q->msg, mbr->buf, BUFSIZE);
		if(convM2S(mbr->buf, &mh->rhdr, n) == 0){
			print("format error in mntxmit\n");
			print("%lux %lux %lux %d format error in mntxmit %s\n", u->p, q->reader, q->writer, n, u->p->text);
			mnterrdequeue(q, mh);
			error(0, Ebadmsg);
		}


@@ 795,7 795,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
		/*
		 * Hand response to correct recipient
		 */
if(q->writer == 0) print("response with empty queue\n");
if(q->writer == 0) print("response with empty queue %d %d %d: %d %d\n", mh->rhdr.type, mh->rhdr.err, mh->rhdr.fid, mh->thdr.type, mh->thdr.fid);
		for(ow=0,w=q->writer; w; ow=w,w=w->next)
			if(mh->rhdr.fid == w->thdr.fid
			&& mh->rhdr.type == w->thdr.type+1){


@@ 822,7 822,7 @@ if(q->writer == 0) print("response with empty queue\n");
		qunlock(q);
		qlocked = 0;
		if(waserror()){		/* interrupted sleep */
			print("interrupted i/o\n");
			print("%lux interrupted i/o %d %d\n", u->p, mh->thdr.type, mh->thdr.fid);
			mnterrdequeue(q, mh);
			nexterror();
		}

M port/devpipe.c => port/devpipe.c +1 -4
@@ 92,22 92,19 @@ pipeopen(Chan *c, int omode)
void
pipecreate(Chan *c, char *name, int omode, ulong perm)
{
	print("pipecreate\n");
	error(0, Egreg);
}

void
piperemove(Chan *c)
{
	print("piperemove\n");
	error(0, Egreg);
}

void
pipewstat(Chan *c, char *db)
{
	print("pipewstat\n");
	error(0, Egreg);
	error(0, Eperm);
}

void

M port/fault.c => port/fault.c +13 -5
@@ 208,17 208,25 @@ o->nmod++;
void
validaddr(ulong addr, ulong len, int write)
{
	Seg *s;
	Seg *s, *ns;

	if((long)len < 0)
		goto Err;
	s = seg(u->p, addr);
	if(s==0 || addr+len>s->maxva || (write && (s->o->flag&OWRPERM)==0)){
	if((long)len < 0){
    Err:
		pprint("invalid address in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp);
		postnote(u->p, 1, "bad address", NDebug);
		error(0, Ebadarg);
	}
    Again:
	s = seg(u->p, addr);
	if(s==0)
		goto Err;
	if(write && (s->o->flag&OWRPERM)==0)
		goto Err;
	if(addr+len > s->maxva){
		len -= s->maxva - addr;
		addr = s->maxva;
		goto Again;
	}
}

void

M port/page.c => port/page.c +7 -3
@@ 10,7 10,7 @@ struct
	Lock;
	ulong	addr;
	int	active;
	Page	*page;		/* base of Page structures, indexed by phys addr */
	Page	*page;		/* base of Page structures, indexed by phys page number */
	ulong	minppn;		/* index of first usable page */
	Page	*head;		/* most recently used */
	Page	*tail;		/* least recently used */


@@ 161,6 161,7 @@ newpage(int noclear, Orig *o, ulong va)
{
	Page *p;
	Orig *o1;
	KMap *k;

	if(palloc.active == 0)
		print("newpage inactive\n");


@@ 206,8 207,11 @@ loop:
	p->ref = 1;
	usepage(p, 0);
	unlock(&palloc);
	if(!noclear)
		memset((void*)(p->pa|KZERO), 0, BY2PG);
	if(!noclear){
		k = kmap(p);
		memset((void*)VA(k), 0, BY2PG);
		kunmap(k);
	}
	p->o = o;
	p->va = va;


M port/proc.c => port/proc.c +22 -12
@@ 303,18 303,23 @@ int
postnote(Proc *p, int dolock, char *n, int flag)
{
	User *up;
	KMap *k;
	int s;
	Rendez *r;

	if(dolock)
		lock(&p->debug);
	up = (User*)(p->upage->pa|KZERO);
	k = kmap(p->upage);
	up = (User*)VA(k);
	if(flag!=NUser && (up->notify==0 || up->notified))
		up->nnote = 0;	/* force user's hand */
	else if(up->nnote == NNOTE-1)
	else if(up->nnote == NNOTE-1){
		kunmap(k);
		return 0;
	}
	strcpy(up->note[up->nnote].msg, n);
	up->note[up->nnote++].flag = flag;
	kunmap(k);
	if(dolock)
		unlock(&p->debug);
	if(r = p->r){	/* assign = */


@@ 398,7 403,7 @@ pexit(char *s, int freemem)
		/*
		 * Pass info through back door, to avoid huge Proc's
		 */
		p->waitmsg = (Waitmsg*)(c->upage->pa|(((ulong)&w)&(BY2PG-1))|KZERO);
		p->waitmsg = (((ulong)&w)&(BY2PG-1));
		c->state = Exiting;
		if(p->state == Inwait)
			ready(p);


@@ 499,6 504,7 @@ ulong
pwait(Waitmsg *w)
{
	Proc *c, *p;
	KMap *k;
	ulong cpid;

	p = u->p;


@@ 515,16 521,17 @@ again:
	lock(&p->wait.queue);	/* wait until child is finished */
	c = p->child;
	if(c == 0){
		print("pwait %d\n", p->pid);
		p->state = Inwait;
		unlock(&p->wait.queue);
		sched();
		goto again;
	}
	p->child = 0;
	k = kmap(c->upage);
	if(w)
		*w = *p->waitmsg;
	cpid = p->waitmsg->pid;
		*w = *(Waitmsg*)(p->waitmsg|VA(k));
	cpid = ((Waitmsg*)(p->waitmsg|VA(k)))->pid;
	kunmap(k);
	p->time[TCUser] += c->time[TUser] + c->time[TCUser];
	p->time[TCSys] += c->time[TSys] + c->time[TCSys];
	p->time[TCReal] += c->time[TReal];


@@ 566,25 573,27 @@ kproc(char *name, void (*func)(void *), void *arg)
	Proc *p;
	int n;
	ulong upa;
	User *up;
	int lastvar;	/* used to compute stack address */
	User *up;
	KMap *k;

	/*
	 * Kernel stack
	 */
	p = newproc();
	p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF));
	upa = p->upage->pa|KZERO;
	up = (User *)upa;
	k = kmap(p->upage);
	upa = VA(k);
	up = (User*)upa;
	up->p = p;

	/*
	 * Save time: only copy u-> data and useful stack
	 */
	memcpy((void*)upa, u, sizeof(User));
	memcpy(up, u, sizeof(User));
	n = USERADDR+BY2PG - (ulong)&lastvar;
	n = (n+32) & ~(BY2WD-1);	/* be safe & word align */
	memcpy((void*)(upa+BY2PG-n), (void*)((u->p->upage->pa|KZERO)+BY2PG-n), n);
	((User *)upa)->p = p;
	memcpy((void*)(upa+BY2PG-n), (void*)(USERADDR+BY2PG-n), n);

	/*
	 * Refs


@@ 593,6 602,7 @@ kproc(char *name, void (*func)(void *), void *arg)
	for(n=0; n<=up->maxfd; n++)
		up->fd[n] = 0;
	up->maxfd = 0;
	kunmap(k);

	/*
	 * Sched

M port/sysfile.c => port/sysfile.c +0 -1
@@ 283,7 283,6 @@ sysstat(ulong *arg)
	validaddr(arg[0], 1, 0);
	c = namec((char*)arg[0], Aaccess, 0, 0);
	if(waserror()){
print("stat error\n");
		close(c);
		nexterror();
	}

M power/dat.h => power/dat.h +1 -1
@@ 310,7 310,7 @@ struct Proc
	Proc	*sib;			/* non-ascendant relatives (circular list) */
	int	nchild;
	QLock	wait;			/* exiting children to be waited for */
	Waitmsg	*waitmsg;
	ulong	waitmsg;
	Proc	*child;
	Proc	*parent;
	Pgrp	*pgrp;

M power/main.c => power/main.c +7 -2
@@ 199,6 199,7 @@ userinit(void)
	Proc *p;
	Seg *s;
	User *up;
	KMap *k;
	int i;
	char **av;



@@ 219,8 220,10 @@ userinit(void)
	/*
	 * User
	 */
	up = (User*)(p->upage->pa|KZERO);
	k = kmap(p->upage);
	up = (User*)VA(k);
	up->p = p;
	kunmap(k);

	/*
	 * User Stack, pass input arguments to boot process


@@ 244,7 247,9 @@ userinit(void)
	s->proc = p;
	s->o = neworig(UTZERO, 1, 0, 0);
	s->o->pte[0].page = newpage(0, 0, UTZERO);
	memcpy((ulong*)(s->o->pte[0].page->pa|KZERO), initcode, sizeof initcode);
	k = kmap(s->o->pte[0].page);
	memcpy((ulong*)VA(k), initcode, sizeof initcode);
	kunmap(k);
	s->minva = 0x1000;
	s->maxva = 0x2000;