~kris/9p

9hist

e0591a6cf2ff350e7d8c1c4c4eeccdce571b6781 — David du Colombier 27 years ago 9dc6674
Plan 9 from Bell Labs 1999-06-29
M carrera/devether.c => carrera/devether.c +1 -1
@@ 326,7 326,7 @@ etherreset(void)
			i = sprint(buf, "#l%d: %s: %dMbps port 0x%luX",
				ctlrno, ether->type, ether->mbps, ether->port);
			if(ether->irq)
				i += sprint(buf+i, " irq %d", ether->irq);
				i += sprint(buf+i, " irq %ld", ether->irq);
			if(ether->mem)
				i += sprint(buf+i, " addr 0x%luX", PADDR(ether->mem));
			if(ether->size)

M carrera/main.c => carrera/main.c +3 -1
@@ 57,7 57,7 @@ main(void)
	vecinit();
	screeninit();
/*	iprint("\n\nBrazil\n");		/**/
	print("Brazil config reg %#lux\n", configreg);
	print("Brazil config reg %#ux\n", configreg);
	pageinit();
	procinit0();
	initseg();


@@ 337,6 337,8 @@ init0(void)
	 * Then early kproc's will have a root and dot.
	 */
	up->slash = namec("#/", Atodir, 0, 0);
	cnameclose(up->slash->name);
	up->slash->name = newcname("/");
	up->dot = cclone(up->slash, 0);

	chandevinit();

M carrera/trap.c => carrera/trap.c +11 -11
@@ 114,7 114,7 @@ ptlb(ulong phys)

	k = (k+1)&3;
	p = buf[k];
	p += sprint(p, "(0x%ux %d ", (phys<<6) & ~(BY2PG-1), (phys>>3)&7);
	p += sprint(p, "(0x%lux %ld ", (phys<<6) & ~(BY2PG-1), (phys>>3)&7);
	if(phys & 4)
		*p++ = 'd';
	if(phys & 2)


@@ 133,20 133,20 @@ kpteprint(Ureg *ur)
	KMap *k;

	i = (ur->badvaddr & ~(2*BY2PG-1)) | TLBPID(tlbvirt());
	print("tlbvirt=0x%ux\n", i);
	print("tlbvirt=0x%lux\n", i);
	i = gettlbp(i, tlbstuff);
	print("i=%d v=0x%ux p0=%s p1=%s\n",
	print("i=%ld v=0x%lux p0=%s p1=%s\n",
		i, tlbstuff[0], ptlb(tlbstuff[1]), ptlb(tlbstuff[2]));

	i = (ur->badvaddr & ~KMAPADDR)>>15;
	if(i > KPTESIZE){
		print("kpte index = 0x%ux ?\n", i);
		print("kpte index = 0x%lux ?\n", i);
		return;
	}
	k = &kpte[i];
	print("i=%d, &k=0x%ux, k={v=0x%ux, p0=%s, p1=%s, pg=0x%ux}\n",
	print("i=%ld, &k=0x%lux, k={v=0x%lux, p0=%s, p1=%s, pg=0x%lux}\n",
		i, k, k->virt, ptlb(k->phys0), ptlb(k->phys1), k->pg);
	print("pg={pa=0x%ux, va=0x%ux}\n", k->pg->pa, k->pg->va);
	print("pg={pa=0x%lux, va=0x%lux}\n", k->pg->pa, k->pg->va);
}

void


@@ 161,7 161,7 @@ kvce(Ureg *ur, int ecode)
	c = 'D';
	if(ecode == CVCEI)
		c = 'I';
	print("Trap: VCE%c: addr=0x%ux\n", c, ur->badvaddr);
	print("Trap: VCE%c: addr=0x%lux\n", c, ur->badvaddr);
	if((ur->badvaddr & KSEGM) == KSEG3) {
		kpteprint(ur);
		return;


@@ 179,7 179,7 @@ kvce(Ureg *ur, int ecode)
		if(*p){
			pg = &(*p)->pages[(soff&(PTEMAPMEM-1))/BY2PG];
			if(*pg) {
				print("pa=0x%ux, va=0x%ux\n",
				print("pa=0x%lux, va=0x%lux\n",
					(*pg)->pa, (*pg)->va);
			} else
				print("no *pg\n");


@@ 313,7 313,7 @@ seteisadma(int ch, void (*func)(void))
	if(ch < 0 || ch > 7)
		panic("seteisadma");
	if(eisadma[ch] != 0)
		print("EISA dma%d: intr used twice");
		print("EISA dma%d: intr used twice", ch);

	eisadma[ch] = func;
}


@@ 396,7 396,7 @@ intr(Ureg *ur)
		devint = IO(uchar, I386ack);
		switch(devint) {
		default:
			print("i386ACK #%lux\n", devint);
			print("i386ACK #%ux\n", devint);
			break;
		case 7:
			audiosbintr();


@@ 508,7 508,7 @@ dumpregs(Ureg *ur)
	int i;

	if(up)
		print("registers for %s %d\n", up->text, up->pid);
		print("registers for %s %ld\n", up->text, up->pid);
	else
		print("registers for kernel\n");


M ip/devip.c => ip/devip.c +0 -5
@@ 285,8 285,6 @@ ipclone(Chan* c, Chan* nc)
static int
ipwalk(Chan* c, char* name)
{
	Path *op;

	if(strcmp(name, "..") != 0)
		return devwalk(c, name, nil, 0, ipgen);



@@ 301,9 299,6 @@ ipwalk(Chan* c, char* name)
	default:
		panic("ipwalk %lux", c->qid.path);
	}
	op = c->path;
	c->path = ptenter(&syspt, op, name);
	decref(op);
	return 1;
}


M pc/devastar.c => pc/devastar.c +11 -5
@@ 307,8 307,8 @@ enum

static int	astarsetup(Astar*);
static void	astarintr(Ureg*, void*);
static void	astarkick(Astarchan*);
static void	astarkickin(Astarchan*);
static void	astarkick(void*);
static void	astarkickin(void*);
static void	enable(Astarchan*);
static void	disable(Astarchan*);
static void	astarctl(Astarchan*, char*);


@@ 1211,7 1211,7 @@ astarctl(Astarchan *ac, char *cmd)

	/* let output drain for a while */
	for(i = 0; i < 16 && qlen(ac->oq); i++)
		tsleep(&ac->r, qlen, ac->oq, 125);
		tsleep(&ac->r, (int (*)(void*))qlen, ac->oq, 125);

	if(strncmp(cmd, "break", 5) == 0)
		cmd = "k";


@@ 1491,8 1491,11 @@ astaroutput(Astarchan *ac)
}

static void
astarkick(Astarchan *ac)
astarkick(void *v)
{
	Astarchan *ac;

	ac = v;
	ilock(&ac->a->pagelock);
	astaroutput(ac);
	iunlock(&ac->a->pagelock);


@@ 1547,8 1550,11 @@ astarinput(Astarchan *ac)
 *  get flow controlled input going again
 */
static void
astarkickin(Astarchan *ac)
astarkickin(void *v)
{
	Astarchan *ac;

	ac = v;
	ilock(&ac->a->pagelock);
	astarinput(ac);
	iunlock(&ac->a->pagelock);

M pc/main.c => pc/main.c +2 -0
@@ 200,6 200,8 @@ init0(void)
	 * Then early kproc's will have a root and dot.
	 */
	up->slash = namec("#/", Atodir, 0, 0);
	cnameclose(up->slash->name);
	up->slash->name = newcname("/");
	up->dot = cclone(up->slash, 0);

	chandevinit();

M port/cache.c => port/cache.c +1 -3
@@ 128,9 128,7 @@ cprint(Chan *c, Mntcache *m, char *s)
	ulong o;
	int nb, ct;
	Extent *e;
	char buf[128];

	ptpath(c->path, buf, sizeof(buf));
	nb = 0;
	ct = 1;
	o = 0;


@@ 143,7 141,7 @@ cprint(Chan *c, Mntcache *m, char *s)
		o = e->start+e->len;
	}
	pprint("%s: 0x%lux.0x%lux %d %d %s (%d %c)\n",
	s, m->path, m->vers, m->type, m->dev, buf, nb, ct ? 'C' : 'N');
	s, m->path, m->vers, m->type, m->dev, c->name, nb, ct ? 'C' : 'N');

	for(e = m->list; e; e = e->next) {
		pprint("\t%4d %5d %4d %lux\n",

M port/chan.c => port/chan.c +174 -16
@@ 5,6 5,11 @@
#include	"fns.h"
#include	"../port/error.h"

enum
{
	CNAMESLOP	= 20
};

struct
{
	Lock;


@@ 13,6 18,8 @@ struct
	Chan	*list;
}chanalloc;

#define SEP(c) ((c) == 0 || (c) == '/')

int
incref(Ref *r)
{


@@ 100,12 107,72 @@ newchan(void)
	c->uri = 0;
	c->aux = 0;
	c->mchan = 0;
	c->path = 0;
	c->mcp = 0;
	c->mqid = (Qid){0, 0};
	c->name = 0;
	return c;
}

static Ref ncname;

Cname*
newcname(char *s)
{
	Cname *n;
	int i;

	n = smalloc(sizeof(Cname));
	i = strlen(s);
	n->len = i;
	n->alen = i+CNAMESLOP;
	n->s = smalloc(n->alen);
	memmove(n->s, s, i+1);
	n->ref = 1;
	incref(&ncname);
	return n;
}

void
cnameclose(Cname *n)
{
	if(n == 0)
		return;
	if(decref(n))
		return;
	decref(&ncname);
	free(n->s);
	free(n);
}

Cname*
addelem(Cname *n, char *s)
{
	int i, a;
	char *t;
	Cname *new;

	if(n->ref > 1){
		/* copy on write */
		new = newcname(n->s);
		cnameclose(n);
		n = new;
	}

	i = strlen(s);
	if(n->len+1+i+1 < n->alen){
		a = n->len+1+i+1 + CNAMESLOP;
		t = smalloc(a);
		memmove(t, n->s, n->len+1);
		free(n->s);
		n->s = t;
		n->alen = a;
	}
	n->s[n->len++] = '/';
	memmove(n->s+n->len, s, i+1);
	n->len += i;
	return n;
}

void
chanfree(Chan *c)
{


@@ 121,18 188,7 @@ chanfree(Chan *c)
		c->mh = nil;
	}

	/*
	 * Channel can be closed before a path is created or the last
	 * channel in a mount which has already cleared its pt names
	 */
	if(c->path) {
		if (c->path->ref <= 0) {
			char buf[100];
			ptpath(c->path, buf, sizeof(buf));
			print("decref %s\n", buf);
		}
		decref(c->path);
	}
	cnameclose(c->name);

	lock(&chanalloc);
	c->next = chanalloc.free;


@@ 333,7 389,13 @@ cunmount(Chan *mnt, Chan *mounted)
Chan*
cclone(Chan *c, Chan *nc)
{
	return devtab[c->type]->clone(c, nc);
	nc = devtab[c->type]->clone(c, nc);
	if(nc != nil){
		nc->name = c->name;
		if(c->name)
			incref(c->name);
	}
	return nc;
}

Chan*


@@ 411,6 473,21 @@ undomount(Chan *c)
}

int
walkname(Chan **cp, char *name, int domnt)
{
	Chan *c;

	if(walk(cp, name, domnt) < 0)
		return -1;
	c = *cp;
	if(c->name == nil)
		c->name = newcname(name);
	else
		c->name = addelem(c->name, name);
	return 0;
}

int
walk(Chan **cp, char *name, int domnt)
{
	Chan *c, *ac;


@@ 563,6 640,56 @@ saveregisters(void)
}

/*
 * In place, rewrite name to compress multiple /, eliminate ., and process ..
 */
void
cleanname(Cname *n, int offset)
{
	char *p, *q, *dotdot, *name;
	int rooted;

	name = n->s+offset;
	rooted = name[0] == '/';

	/*
	 * invariants:
	 *	p points at beginning of path element we're considering.
	 *	q points just past the last path element we wrote (no slash).
	 *	dotdot points just past the point where .. cannot backtrack
	 *		any further (no slash).
	 */
	p = q = dotdot = name+rooted;
	while(*p) {
		if(p[0] == '/')	/* null element */
			p++;
		else if(p[0] == '.' && SEP(p[1]))
			p += 1;	/* don't count the separator in case it is nul */
		else if(p[0] == '.' && p[1] == '.' && SEP(p[2])) {
			p += 2;
			if(q > dotdot) {	/* can backtrack */
				while(--q > dotdot && *q != '/')
					;
			} else if(!rooted) {	/* ``/..'' ≡ ``/'', but ``./../'' ≡ ``..'' */
				if(q != name)
					*q++ = '/';
				*q++ = '.';
				*q++ = '.';
				dotdot = q;
			}
		} else {	/* real path element */
			if(q != name+rooted)
				*q++ = '/';
			while((*q = *p) != '/' && *q != 0)
				p++, q++;
		}
	}
	if(q == name)	/* empty string is really ``.'' */
		*q++ = '.';
	*q = 0;
	n->len = (q-name) + offset;
}

/*
 * Turn a name into a channel.
 * &name[0] is known to be a valid address.  It may be a kernel address.
 */


@@ 572,7 699,8 @@ namec(char *name, int amode, int omode, ulong perm)
	Rune r;
	char *p;
	char *elem;
	int t, n;
	Cname *cname;
	int t, n, newname;
	int mntok, isdot;
	Chan *c, *cc;
	char createerr[ERRLEN];


@@ 589,15 717,24 @@ namec(char *name, int amode, int omode, ulong perm)
		}
	}

	newname = 1;
	cname = nil;
	if(waserror()){
		cnameclose(cname);
		nexterror();
	}

	elem = up->elem;
	mntok = 1;
	isdot = 0;
	switch(name[0]) {
	case '/':
		c = cclone(up->slash, 0);
		cname = newcname(name);	/* save this before advancing */
		name = skipslash(name);
		c = cclone(up->slash, 0);
		break;
	case '#':
		cname = newcname(name);	/* save this before advancing */
		mntok = 0;
		elem[0] = 0;
		n = 0;


@@ 611,6 748,8 @@ namec(char *name, int amode, int omode, ulong perm)
				name = skipslash(name);
				if(*name)
					error(Efilename);
				poperror();
				cnameclose(cname);
				return c;
			}
			else {


@@ 627,6 766,8 @@ namec(char *name, int amode, int omode, ulong perm)
		name = skipslash(name);
		break;
	default:
		cname = newcname(up->dot->name->s);
		cname = addelem(cname, name);
		c = cclone(up->dot, 0);
		name = skipslash(name);
		if(*name == 0)


@@ 688,7 829,10 @@ namec(char *name, int amode, int omode, ulong perm)
		if(omode == OEXEC)
			c->flag &= ~CCACHE;

		cc = c;
		c = devtab[c->type]->open(c, omode&~OCEXEC);
		if(cc != c)
			newname = 0;

		if(omode & OCEXEC)
			c->flag |= CCEXEC;


@@ 760,6 904,20 @@ namec(char *name, int amode, int omode, ulong perm)
	default:
		panic("unknown namec access %d\n", amode);
	}

	poperror();

	/* peculiar workaround for #/ */
	if(newname){
		if(cname->s[0]=='#' && cname->s[1]=='/')
			cleanname(cname, 2);
		else
			cleanname(cname, 0);
		cnameclose(c->name);
		c->name = cname;
	}else
		cnameclose(cname);

	poperror();
	return c;
}

M port/dev.c => port/dev.c +13 -11
@@ 71,10 71,9 @@ devattach(int tc, char *spec)
	c = newchan();
	c->qid = (Qid){CHDIR, 0};
	c->type = devno(tc, 0);
	if(tc != 'M') {
		sprint(buf, "#%C%s", tc, spec);
		c->path = ptenter(&syspt, 0, buf);
	}
	sprint(buf, "#%C%s", tc, spec==nil? "" : spec);
	free(c->name);
	c->name = newcname(buf);
	return c;
}



@@ 101,8 100,8 @@ devclone(Chan *c, Chan *nc)
	nc->mchan = c->mchan;
	nc->mqid = c->mqid;
	nc->mcp = c->mcp;
	nc->path = c->path;
	incref(nc->path);
	if(c->name)
		incref(c->name);
	return nc;
}



@@ 111,7 110,6 @@ devwalk(Chan *c, char *name, Dirtab *tab, int ntab, Devgen *gen)
{
	long i;
	Dir dir;
	Path *op;

	isdir(c);
	if(name[0]=='.' && name[1]==0)


@@ 126,9 124,6 @@ devwalk(Chan *c, char *name, Dirtab *tab, int ntab, Devgen *gen)
		case 1:
			if(strcmp(name, dir.name) == 0){
				c->qid = dir.qid;
				op = c->path;
				c->path = ptenter(&syspt, op, name);
				decref(op);
				return 1;
			}
			continue;


@@ 142,12 137,19 @@ devstat(Chan *c, char *db, Dirtab *tab, int ntab, Devgen *gen)
{
	int i;
	Dir dir;
	char *p, *elem;

	for(i=0;; i++)
		switch((*gen)(c, tab, ntab, i, &dir)){
		case -1:
			if(c->qid.path & CHDIR){
				devdir(c, c->qid, c->path->elem, i*DIRLEN, eve, CHDIR|0555, &dir);
				if(c->name == nil)
					elem = "???";
				else
					for(elem=p=c->name->s; *p; p++)
						if(*p = '/')
							elem = p+1;
				devdir(c, c->qid, elem, i*DIRLEN, eve, CHDIR|0555, &dir);
				convD2M(&dir, db);
				return;
			}

M port/devdraw.c => port/devdraw.c +4 -5
@@ 824,8 824,6 @@ drawattach(char *spec)
int
drawwalk(Chan *c, char *name)
{
	Path *op;

	if(screendata.data == nil)
		error("no frame buffer");
	if(strcmp(name, "..") == 0){


@@ 841,9 839,10 @@ drawwalk(Chan *c, char *name)
		default:
			panic("drawwalk %lux", c->qid.path);
		}
		op = c->path;
		c->path = ptenter(&syspt, op, name);
		decref(op);
print("drawwalk: ..?\n");
//		op = c->path;
//		c->path = ptenter(&syspt, op, name);
//		decref(op);
		return 1;
	}
	return devwalk(c, name, 0, 0, drawgen);

M port/devmnt.c => port/devmnt.c +9 -14
@@ 153,7 153,6 @@ mntattach(char *muxattach)
	incref(m->c);

	sprint(buf, "#M%lud", m->id);
	m->tree.root = ptenter(&m->tree, 0, buf);

	unlock(m);



@@ 184,8 183,6 @@ mntattach(char *muxattach)
		c->mntptr = mc->mntptr;
		c->mchan = c->mntptr->c;
		c->mqid = c->qid;
		c->path = c->mntptr->tree.root;
		incref(c->path);
		incref(c->mntptr);
	}



@@ 233,8 230,6 @@ mattach(Mnt *m, Chan *c, char *spec)
	c->qid = r->reply.qid;
	c->mchan = m->c;
	c->mqid = c->qid;
	c->path = m->tree.root;
	incref(c->path);

	poperror();
	mntfree(r);


@@ 279,7 274,6 @@ static int
mntwalk(Chan *c, char *name)
{
	Mnt *m;
	Path *op;
	Mntrpc *r;

	m = mntchk(c);


@@ 294,10 288,6 @@ mntwalk(Chan *c, char *name)
	mountrpc(m, r);

	c->qid = r->reply.qid;
	op = c->path;
	c->path = ptenter(&m->tree, op, name);

	decref(op);

	poperror();
	mntfree(r);


@@ 415,9 405,6 @@ mclose(Mnt *m, Chan *c)
	if(decref(m) != 0)
		return;

	c->path = 0;
	ptclose(&m->tree);

	for(q = m->queue; q; q = r) {
		r = q->list;
		q->flushed = 0;


@@ 909,6 896,9 @@ mntqrm(Mnt *m, Mntrpc *r)
void
recoverchan(Mnt *m, Chan *c)
{
panic("recoverchan");
#ifdef asdf
BUG: WON'T WORK WITH PATHS GONE?
	int i, n, flg;
	Path *safe, *p, **pav;



@@ 956,6 946,7 @@ recoverchan(Mnt *m, Chan *c)
	free(pav);
	if(flg&COPEN)
		mntopen(c, c->mode);
#endif
}

Mnt*


@@ 1039,7 1030,8 @@ mntrecover(Mnt *m, Mntrpc *r)
		/*
		 * Send a message to boot via #/recover
		 */
		rootrecover(m->c->path, m->tree.root->elem);
panic("mntrecover\n");
//		rootrecover(m->c->path, m->tree.root->elem);
		lock(m);
	}
	r->list = m->recwait;


@@ 1070,6 1062,8 @@ mntrecover(Mnt *m, Mntrpc *r)
void
mntrepl(char *buf)
{
panic("mntrepl");
#ifdef asdf
	int fd;
	Mnt *m;
	char *p;


@@ 1105,6 1099,7 @@ mntrepl(char *buf)

	unlock(m);
	cclose(c2);
#endif
}

Dev mntdevtab = {

M port/devproc.c => port/devproc.c +46 -20
@@ 10,6 10,7 @@ enum
{
	Qctl,
	Qdir,
	Qfd,
	Qfpregs,
	Qkregs,
	Qmem,


@@ 24,7 25,6 @@ enum
	Qtext,
	Qwait,
	Qprofile,
	Qfd,
};

#define	STATSIZE	(2*NAMELEN+12+9*12)


@@ 263,17 263,19 @@ procfds(Proc *p, char *va, int count, long offset)

	qlock(&p->debug);
	lock(f);
	n = 0;
	n = readstr(0, va, count, p->dot->name->s);
	n += snprint(va+n, count-n, "\n");
	for(i = 0; i <= f->maxfd; i++) {
		c = f->fd[i];
		if(c == nil)
			continue;
		n += snprint(va+n, count-n, "%3d %.2s %.8lux.%.8lud %8lld ",
		n += snprint(va+n, count-n, "%3d %.2s %C %4ld %.8lux.%.8lud %8lld ",
			i,
			&"r w rw"[(c->mode&3)<<1],
			devtab[c->type]->dc, c->dev,
			c->qid.path, c->qid.vers,
			c->offset);
		n += ptpath(c->path, va+n, count-n);
		n += readstr(0, va+n, count-n, c->name->s);
		n += snprint(va+n, count-n, "\n");
		if(offset > 0) {
			offset -= n;


@@ 299,6 301,27 @@ procclose(Chan * c)
		free(c->aux);
}

static void
int2flag(int flag, char *s)
{
	if(flag == 0){
		*s = '\0';
		return;
	}
	*s++ = '-';
	if(flag & MAFTER)
		*s++ = 'a';
	if(flag & MBEFORE)
		*s++ = 'b';
	if(flag & MCREATE)
		*s++ = 'c';
	if(flag & MCACHE)
		*s++ = 'C';
	if(flag & MRECOV)
		*s++ = 'r';
	*s = '\0';
}

static long
procread(Chan *c, void *va, long n, vlong off)
{


@@ 311,7 334,7 @@ procread(Chan *c, void *va, long n, vlong off)
	Segment *sg, *s;
	char *a = va, *sps;
	int i, j, rsize, pid;
	char statbuf[NSEG*32];
	char statbuf[NSEG*32], *srv, flag[10];
	ulong offset = off;

	if(c->qid.path & CHDIR)


@@ 515,23 538,26 @@ procread(Chan *c, void *va, long n, vlong off)

	case Qns:
		mw = c->aux;
		mntscan(mw, p);
		if(mw->mh == 0)
		if(mw->cddone)
			return 0;
		if(n < NAMELEN+11)
			error(Etoosmall);
		i = sprint(a, "%.*s %d ", NAMELEN, mw->cm->spec, mw->cm->flag);
		n -= i;
		a += i;
		i = ptpath(mw->mh->from->path, a, n);
		n -= i;
		a += i;
		if(n > 0) {
			*a++ = ' ';
			n--;
		mntscan(mw, p);
		if(mw->mh == 0){
			mw->cddone = 1;
			i = snprint(a, n, "cd %s\n", p->dot->name->s);
			return i;
		}
		a += ptpath(mw->cm->to->path, a, n);
		return a - (char*)va;
		int2flag(mw->cm->flag, flag);
		if(strcmp(mw->cm->to->name->s, "#M") == 0){
			srv = srvname(mw->cm->to->mchan);
			i = snprint(a, n, "mount %s %s %s %.*s\n", flag,
				srv==nil? mw->cm->to->mchan->name->s : srv,
				mw->mh->from->name->s, NAMELEN, mw->cm->spec);
			free(srv);
		}else
			i = snprint(a, n, "bind %s %s %s\n", flag,
				mw->cm->to->name->s, mw->mh->from->name->s);
		return i;

	case Qnoteid:
		return readnum(offset, va, n, p->noteid, NUMSIZE);
	case Qfd:

M port/devroot.c => port/devroot.c +3 -6
@@ 239,16 239,13 @@ Dev rootdevtab = {
};

void
rootrecover(Path *p, char *mntname)
rootrecover(Chan *c, char *mntname)
{
	int i;
	Recover *r;
	char buf[256];

	r = malloc(sizeof(Recover));
	i = ptpath(p, buf, sizeof(buf));
	r->req = smalloc(i+strlen(mntname)+2);
	sprint(r->req, "%s %s", buf, mntname);
	r->req = smalloc(c->name->len+strlen(mntname)+2);
	sprint(r->req, "%s %s", c->name->s, mntname);
	lock(&reclist);
	r->next = reclist.q;
	reclist.q = r;

M port/devsrv.c => port/devsrv.c +15 -0
@@ 73,6 73,21 @@ srvlookup(char *name, ulong qidpath)
	return nil;
}

char*
srvname(Chan *c)
{
	Srv *sp;
	char *s;

	for(sp = srv; sp; sp = sp->link)
		if(sp->chan == c){
			s = smalloc(3+strlen(sp->name)+1);
			sprint(s, "#s/%s", sp->name);
			return s;
		}
	return nil;
}

static Chan*
srvopen(Chan *c, int omode)
{

M port/lib.h => port/lib.h +2 -2
@@ 81,8 81,8 @@ extern	char	end[];
#define	MBEFORE	0x0001	/* mount goes before others in union directory */
#define	MAFTER	0x0002	/* mount goes after others in union directory */
#define	MCREATE	0x0004	/* permit creation in mounted directory */
#define MRECOV	0x0008	/* perform recovery if mount channel is lost */
#define MCACHE	0x0010	/* cache some data */
#define	MRECOV	0x0008	/* perform recovery if mount channel is lost */
#define	MCACHE	0x0010	/* cache some data */
#define	MMASK	0x001F	/* all bits on */

#define	OREAD	0	/* open for read */

M port/netif.c => port/netif.c +0 -1
@@ 146,7 146,6 @@ netifopen(Netif *nif, Chan *c, int omode)
		case Ncloneqid:
			id = openfile(nif, -1);
			c->qid.path = NETQID(id, Nctlqid);
			ptclone(c, 0, id);
			break;
		default:
			if(omode != OREAD)

M port/portdat.h => port/portdat.h +12 -21
@@ 2,6 2,7 @@ typedef struct Alarms	Alarms;
typedef struct Block	Block;
typedef struct Chan	Chan;
typedef struct Cmdbuf	Cmdbuf;
typedef struct Cname	Cname;
typedef struct Crypt	Crypt;
typedef struct Dev	Dev;
typedef struct Dirtab	Dirtab;


@@ 20,7 21,6 @@ typedef struct Mnt	Mnt;
typedef struct Mhead	Mhead;
typedef struct Note	Note;
typedef struct Page	Page;
typedef struct Path	Path;
typedef struct Palloc	Palloc;
typedef struct Pgrps	Pgrps;
typedef struct Pgrp	Pgrp;


@@ 113,15 113,6 @@ enum
	CCACHE	= 0x0080,		/* client cache */
};

struct Path
{
	Ref;
	Path*	hash;
	Path*	parent;
	Pthash*	pthash;
	char	elem[NAMELEN];
};

enum
{
	BINTR	=	(1<<0),


@@ 154,7 145,6 @@ struct Chan
	ushort	flag;
	Qid	qid;
	int	fid;			/* for devmnt */
	Path*	path;
	Mhead*	mh;			/* mount point that derived Chan */
	Mhead*	xmh;			/* Last mount point crossed */
	int	uri;			/* union read index */


@@ 170,6 160,15 @@ struct Chan
	Chan*	mchan;			/* channel to mounted server */
	Qid	mqid;			/* qid of root of mount point */
	Session*session;
	Cname	*name;
};

struct Cname
{
	Ref;
	int	alen;			/* allocated length */
	int	len;			/* strlen(s) */
	char	*s;
};

struct Dev


@@ 209,16 208,9 @@ enum
	NSCACHE	=	(1<<NSLOG),
};

struct Pthash
{
	QLock;
	int	npt;
	Path*	root;
	Path*	hash[NSCACHE];
};

struct Mntwalk				/* state for /proc/#/ns */
{
	int		cddone;
	ulong	id;
	Mhead*	mh;
	Mount*	cm;


@@ 259,7 251,6 @@ struct Mnt
	int	blocksize;	/* read/write block size */
	ushort	flushtag;	/* Tag to send flush on */
	ushort	flushbase;	/* Base tag of flush window for this buffer */
	Pthash	tree;		/* Path names from this mount point */
	char	*partial;	/* Outstanding read data */
	int	npart;		/* Sizeof remains */
};


@@ 744,7 735,7 @@ struct Logflag {

struct Cmdbuf
{
	char	buf[256];
	char	buf[64];
	char	*f[16];
	int	nf;
};

M port/portfns.h => port/portfns.h +5 -5
@@ 43,6 43,7 @@ void		closepgrp(Pgrp*);
void		closergrp(Rgrp*);
long		clrfpintr(void);
int		cmount(Chan*, Chan*, int, char*);
void		cnameclose(Cname*);
void		confinit(void);
void		confinit1(int);
int		consactive(void);


@@ 174,6 175,7 @@ Rgrp*		newrgrp(void);
Proc*		newproc(void);
char*		nextelem(char*, char*);
void		nexterror(void);
Cname*		newcname(char*);
int		notify(Ureg*);
int		nrand(int);
int		okaddr(ulong, ulong, int);


@@ 206,12 208,8 @@ void		procinit0(void);
void		procflushseg(Segment*);
Proc*		proctab(int);
void		procwired(Proc*);
void		ptclone(Chan*, int, int);
void		ptclose(Pthash*);
Pte*		ptealloc(void);
Pte*		ptecpy(Pte*);
Path*		ptenter(Pthash*, Path*, char*);
int		ptpath(Path*, char*, int);
int		pullblock(Block**, int);
Block*		pullupblock(Block*, int);
void		putimage(Image*);


@@ 262,7 260,7 @@ void		resetscsi(void);
void		resrcwait(char*);
int		return0(void*);
void		rlock(RWlock*);
void		rootrecover(Path*, char*);
void		rootrecover(Chan*, char*);
void		rootreq(Chan*, Mnt*);
long		rtctime(void);
void		runlock(RWlock*);


@@ 301,6 299,7 @@ int		spllo(void);
void		splx(int);
void		splxpc(int);
void		srvrecover(Chan*, Chan*);
char*	srvname(Chan*);
int		swapcount(ulong);
int		swapfull(void);
void		swapinit(void);


@@ 325,6 324,7 @@ void		vcacheinval(Page*, ulong);
void*		vmemchr(void*, int, int);
int		wakeup(Rendez*);
int		walk(Chan**, char*, int);
int		walkname(Chan**, char*, int);
void		wlock(RWlock*);
void		wunlock(RWlock*);
#define		xalloc(s)	xallocz(s, 1)

M port/sysfile.c => port/sysfile.c +9 -14
@@ 107,7 107,7 @@ openmode(ulong o)
long
sysfd2path(ulong *arg)
{
	Chan *c, *oc;
	Chan *c;

	validaddr(arg[1], arg[2], 1);



@@ 121,18 121,13 @@ sysfd2path(ulong *arg)
		cclose(c);
		nexterror();
	}
	/* If we used open the chan will be at the first element
	 * of a union rather than the mhead of the union. undomount
	 * will make it look like we used Atodir rather than Aopen.
	 */
	oc = c;
	if(c->qid.path & CHDIR)
		c = undomount(c);
	poperror();
	if(c == oc)
		cclose(c);

	ptpath(c->path, (char*)arg[1], arg[2]);
	if(c->name == nil)
		snprint((char*)arg[1], arg[2], "<null>");
	else
		snprint((char*)arg[1], arg[2], "%s", c->name->s);

	poperror();
	return 0;
}



@@ 162,9 157,9 @@ syspipe(ulong *arg)
		nexterror();
	}
	c[1] = cclone(c[0], 0);
	if(walk(&c[0], "data", 1) < 0)
	if(walkname(&c[0], "data", 1) < 0)
		error(Egreg);
	if(walk(&c[1], "data1", 1) < 0)
	if(walkname(&c[1], "data1", 1) < 0)
		error(Egreg);
	c[0] = d->open(c[0], ORDWR);
	c[1] = d->open(c[1], ORDWR);