~kris/9p

9hist

3cfbb8523f7fdef04a8e53f148ca62a15d0c5c90 — David du Colombier 35 years ago 854cf1d
Plan 9 from Bell Labs 1991-04-27
M gnot/dat.h => gnot/dat.h +0 -1
@@ 177,7 177,6 @@ struct Dev
	long	 (*write)(Chan*, void*, long, ulong);
	void	 (*remove)(Chan*);
	void	 (*wstat)(Chan*, char*);
	Chan	*(*clwalk)(Chan*, char*);
};

struct Dirtab

M gnot/devcons.c => gnot/devcons.c +0 -6
@@ 495,12 495,6 @@ conswalk(Chan *c, char *name)
	return devwalk(c, name, consdir, NCONS, consgen);
}

Chan*
consclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void
consstat(Chan *c, char *dp)
{

M gnot/devincon.c => gnot/devincon.c +0 -6
@@ 359,12 359,6 @@ inconwalk(Chan *c, char *name)
	return devwalk(c, name, 0, 0, streamgen);
}

Chan*
inconclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void	 
inconstat(Chan *c, char *dp)
{

M gnot/devport.c => gnot/devport.c +0 -6
@@ 83,12 83,6 @@ portwalk(Chan *c, char *name)
	return devwalk(c, name, portdir, NPORT, devgen);
}

Chan*
portclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void
portstat(Chan *c, char *db)
{

M port/chan.c => port/chan.c +144 -140
@@ 11,18 11,6 @@ struct{
	Chan	*free;
}chanalloc;

/*
 *  used by namec, domount, and walk to point
 *  to the current mount entry during name resolution
 */
typedef struct Finger	Finger;
struct Finger {
	Chan	*c;		/* channel we're walking */
	int	needcl;		/* true if we need to clone c before using it */
	Mount	*mnt;		/* last mount point we ran traversed */
	ulong	mountid;	/* id of that mount point */
};

int
incref(Ref *r)
{


@@ 95,7 83,9 @@ loop:
		c->dev = 0;
		c->offset = 0;
		c->mnt = 0;
		c->stream = 0;
		c->aux = 0;
		c->mntindex = 0;
		c->mchan = 0;
		c->mqid = (Qid){0, 0};
		return c;


@@ 292,13 282,15 @@ clone(Chan *c, Chan *nc)
	return (*devtab[c->type].clone)(c, nc);
}

void
domount(Finger *f)
Chan*
domount(Chan *c)
{
	int i;
	ulong mntid;
	Mtab *mt;
	Mount *mnt;
	Pgrp *pg;
	Chan *mc;
	Chan *nc, *mc;

	pg = u->p->pgrp;
	/*


@@ 306,101 298,110 @@ domount(Finger *f)
	 */
	mt = pg->mtab;
	for(i=0; i<pg->nmtab; i++,mt++)
		if(mt->c && eqchan(mt->c, f->c, 1))
		if(mt->c && eqchan(mt->c, c, 1))
			goto Found;
	/*
	 * No; c is unaffected
	 */
	return;
	return c;

	/*
	 * Yes; move c through table
	 */
    Found:
	lock(pg);
	if(!eqchan(mt->c, f->c, 1)){	/* table changed underfoot */
	if(!eqchan(mt->c, c, 1)){	/* table changed underfoot */
		pprint("domount: changed underfoot?\n");
		unlock(pg);
		return;
		return c;
	}
	f->mnt = mt->mnt;
	f->mountid = f->mnt->mountid;
	mc = mt->mnt->c;
	mnt = mt->mnt;
	mntid = mnt->mountid;
	mc = mnt->c;
	incref(mc);
	unlock(pg);
	close(f->c);
	f->c = mc;
	f->needcl = 1;
	if(waserror()){
		close(mc);
		nexterror();
	}
	nc = clone(mc, 0);
	close(mc);
	poperror();
	close(c);
	nc->mnt = mnt;
	nc->mountid = mntid;
	return nc;
}

int
walk(Finger *f, char *name, int domnt)
Chan*
walk(Chan *ac, char *name, int domnt)
{
	Mount *mnt;
	int first = 1;
	Mount *mnt = f->mnt;
	ulong mountid = f->mountid;
	Chan *c = f->c;
	Chan *mc;
	Chan *c = ac;
	Chan *nc, *mc;
	Pgrp *pg = u->p->pgrp;

	/*
	 * name may be empty if the file name is "/", "#c" etc.
	 */
	if(name[0]){
		for(;;){
			if(!first || f->needcl){
				mc = (*devtab[c->type].clwalk)(c, name);
				if(mc){
					close(c);
					c = mc;
					break;
				}
			} else {
				if((*devtab[c->type].walk)(c, name) != 0){
					break;
				}
			}
			if(!(c->flag&CMOUNT))
				goto Notfound;
			if(mnt == 0)
				panic("walk");	/* ??? is this safe ??? */
			lock(pg);
			if(mnt->term){
				unlock(pg);
				goto Notfound;
			}
			if(mountid != mnt->mountid){
				pprint("walk: changed underfoot? '%s'\n", name);
				unlock(pg);
				goto Notfound;
			}
			mnt = mnt->next;
			mountid = mnt->mountid;
			mc = mnt->c;
			incref(mc);
    Again:
	if(name[0] && (*devtab[c->type].walk)(c, name)==0){
		if(!(c->flag&CMOUNT))
			goto Notfound;
		mnt = c->mnt;
		if(mnt == 0)
			panic("walk");
		lock(pg);
		if(mnt->term){
			unlock(pg);
			if(!first)
				close(c);
			c = mc;
			first = 0;
			goto Notfound;
		}

		/*
		 *  we get here only if we have a cloned and walked
		 *  channel
		 */
		if(c->mountid != mnt->mountid){
			pprint("walk: changed underfoot? '%s'\n", name);
			unlock(pg);
			goto Notfound;
		}
		mnt = mnt->next;
		mc = mnt->c;
		incref(mc);
		unlock(pg);
		if(waserror()){
			close(mc);
			nexterror();
		}
		if(mnt == 0)
			panic("walk 1");
		nc = clone(mc, 0);
		close(mc);
		poperror();
		if(!first)
			close(f->c);
		f->c = c;
		f->needcl = 0;
		f->mnt = 0;
			close(c);
		nc->mnt = mnt;
		nc->mountid = mnt->mountid;
		c = nc;
		first = 0;
		goto Again;
	}

	if(name[0])			/* walk succeeded */
		c->flag &= ~CMOUNT;

	if(domnt){
		if(waserror()){
			if(!first)
				close(c);
			return 0;
		}
		c = domount(c);
		poperror();
	}

	if(domnt)
		domount(f);
	if(!first)
		close(ac);


	return 1;
	return c;

    Notfound:
	if(!first)


@@ 409,22 410,22 @@ walk(Finger *f, char *name, int domnt)
}

/*
 * f->c is a mounted non-creatable directory.  find a creatable one.
 * c is a mounted non-creatable directory.  find a creatable one.
 */
void
createdir(Finger *f)
Chan*
createdir(Chan *c)
{
	Mount *mnt;
	Pgrp *pg = u->p->pgrp;
	Chan *mc;
	Chan *mc, *nc;

	lock(pg);
	if(waserror()){
		unlock(pg);
		nexterror();
	}
	mnt = f->mnt;
	if(f->mountid != mnt->mountid){
	mnt = c->mnt;
	if(c->mountid != mnt->mountid){
		pprint("createdir: changed underfoot?\n");
		error(Enocreate);
	}


@@ 436,10 437,16 @@ createdir(Finger *f)
	mc = mnt->c;
	incref(mc);
	unlock(pg);
	if(waserror()){
		close(mc);
		nexterror();
	}
	nc = clone(mc, 0);
	poperror();
	close(f->c);
	f->needcl = 1;
	f->c = mc;
	close(c);
	close(mc);
	nc->mnt = mnt;
	return nc;
}

void


@@ 447,19 454,6 @@ saveregisters(void)
{
}

void
doclone(Finger *f)
{
	Chan *nc;

	if(f->needcl == 0)
		return;
	nc = clone(f->c, 0);
	close(f->c);
	f->c = nc;
	f->needcl = 0;
}

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


@@ 467,11 461,11 @@ doclone(Finger *f)
Chan*
namec(char *name, int amode, int omode, ulong perm)
{
	Chan *c, *nc, *cc;
	int t;
	int mntok, isdot;
	char *p;
	char *elem;
	Finger f;

	if(name[0] == 0)
		error(Enonexist);


@@ 492,11 486,8 @@ namec(char *name, int amode, int omode, ulong perm)
	elem = u->elem;
	mntok = 1;
	isdot = 0;
	f.mnt = 0;
	if(name[0] == '/'){
		f.c = u->slash;
		incref(f.c);
		f.needcl = 1;
		c = clone(u->slash, 0);
		/*
		 * Skip leading slashes.
		 */


@@ 514,19 505,16 @@ namec(char *name, int amode, int omode, ulong perm)
			elem[0]=0;
		}else
			name = nextelem(name, elem);
		f.c = (*devtab[t].attach)(elem);
		f.needcl = 0;
		c = (*devtab[t].attach)(elem);
	}else{
		f.c = u->dot;
		incref(f.c);
		f.needcl = 1;
		c = clone(u->dot, 0);
		name = skipslash(name);	/* eat leading ./ */
		if(*name == 0)
			isdot = 1;
	}

	if(waserror()){
		close(f.c);
		close(c);
		nexterror();
	}



@@ 537,15 525,16 @@ namec(char *name, int amode, int omode, ulong perm)
	 *  current directory.
	 */
	if(mntok && !isdot && !(amode==Amount && elem[0]==0))
		domount(&f);		/* see case Atodir below */
		c = domount(c);			/* see case Atodir below */

	/*
	 * How to treat the last element of the name depends on the operation.
	 * Therefore do all but the last element by the easy algorithm.
	 */
	while(*name){
		if(walk(&f, elem, mntok) == 0)
		if((nc=walk(c, elem, mntok)) == 0)
			error(Enonexist);
		c = nc;
		name = nextelem(name, elem);
	}



@@ 555,10 544,11 @@ namec(char *name, int amode, int omode, ulong perm)
	switch(amode){
	case Aaccess:
		if(isdot)
			domount(&f);
			c = domount(c);
		else{
			if(walk(&f, elem, mntok) == 0)
			if((nc=walk(c, elem, mntok)) == 0)
				error(Enonexist);
			c = nc;
		}
		break;



@@ 567,26 557,26 @@ namec(char *name, int amode, int omode, ulong perm)
		 * Directories (e.g. for cd) are left before the mount point,
		 * so one may mount on / or . and see the effect.
		 */
		if(walk(&f, elem, 0) == 0)
		if((nc=walk(c, elem, 0)) == 0)
			error(Enonexist);
		if(!(f.c->qid.path & CHDIR))
		c = nc;
		if(!(c->qid.path & CHDIR))
			error(Enotdir);
		break;

	case Aopen:
		if(isdot)
			domount(&f);
			c = domount(c);
		else{
			if(walk(&f, elem, mntok) == 0)
			if((nc=walk(c, elem, mntok)) == 0)
				error(Enonexist);
			c = nc;
		}
	Open:
		saveregisters(); /* else error() in open has wrong value of c saved */
		if(f.needcl)
			doclone(&f);
		f.c = (*devtab[f.c->type].open)(f.c, omode);
		saveregisters();	/* else error() in open has wrong value of c saved */
		c = (*devtab[c->type].open)(c, omode);
		if(omode & OCEXEC)
			f.c->flag |= CCEXEC;
			c->flag |= CCEXEC;
		break;

	case Amount:


@@ 595,37 585,51 @@ namec(char *name, int amode, int omode, ulong perm)
		 * the second mount to be attached to the original directory, not
		 * the replacement.
		 */
		if(walk(&f, elem, 0) == 0)
		if((nc=walk(c, elem, 0)) == 0)
			error(Enonexist);
		c = nc;
		break;

	case Acreate:
		if(isdot)
			error(Eisdir);
		if(walk(&f, elem, 1) != 0){

		/*
		 *  Walk the element before trying to create it
		 *  to see if it exists.  We clone the channel
		 *  first, just in case someone is trying to
		 *  use clwalk outside the kernel.
		 */
		cc = clone(c, 0);
		if(waserror()){
			close(cc);
			nexterror();
		}
		if((nc=walk(cc, elem, 1)) != 0){
			poperror();
			close(c);
			c = nc;
			omode |= OTRUNC;
			goto Open;
		}
		if((f.c->flag&(CMOUNT|CCREATE)) == CMOUNT)
			createdir(&f);
		if(f.needcl)
			doclone(&f);
		(*devtab[f.c->type].create)(f.c, elem, omode, perm);
		close(cc);
		poperror();

		/*
		 *  the file didn't exist, try the create
		 */
		if((c->flag&(CMOUNT|CCREATE)) == CMOUNT)
			c = createdir(c);
		(*devtab[c->type].create)(c, elem, omode, perm);
		if(omode & OCEXEC)
			f.c->flag |= CCEXEC;
			c->flag |= CCEXEC;
		break;

	default:
		panic("unknown namec access %d\n", amode);
	}
	if(f.needcl)
		doclone(&f);
	poperror();
	if(f.c->flag & CMOUNT){
		f.c->mnt = f.mnt;
		f.c->mountid = f.mountid;
	}
	return f.c;
	return c;
}

/*

M port/dev.c => port/dev.c +1 -20
@@ 77,6 77,7 @@ devclone(Chan *c, Chan *nc)
	nc->offset = c->offset;
	nc->flag = c->flag;
	nc->mnt = c->mnt;
	nc->mountid = c->mountid;
	nc->aux = c->aux;
	nc->mchan = c->mchan;
	nc->mqid = c->mqid;


@@ 108,26 109,6 @@ devwalk(Chan *c, char *name, Dirtab *tab, int ntab, Devgen *gen)
		}
}

Chan*
devclwalk(Chan *c, char *name)
{
	Chan *nc;

	nc = 0;
	if(waserror()){
		if(nc)
			close(nc);
		return 0;
	}
	nc = (*devtab[c->type].clone)(c, 0);
	if((*devtab[nc->type].walk)(nc, name) == 0){
		close(nc);
		nc = 0;
	}
	poperror();
	return nc;
}

void
devstat(Chan *c, char *db, Dirtab *tab, int ntab, Devgen *gen)
{

M port/devarp.c => port/devarp.c +0 -6
@@ 81,12 81,6 @@ arpwalk(Chan *c, char *name)
	return devwalk(c, name, arptab, (long)Narptab, devgen);
}

Chan*
arpclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void
arpstat(Chan *c, char *db)
{

M port/devbit.c => port/devbit.c +0 -6
@@ 194,12 194,6 @@ bitwalk(Chan *c, char *name)
	return devwalk(c, name, bitdir, NBIT, devgen);
}

Chan*
bitclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void
bitstat(Chan *c, char *db)
{

M port/devboot.c => port/devboot.c +0 -6
@@ 47,12 47,6 @@ bootwalk(Chan *c, char *name)
	return devwalk(c, name, bootdir, NBOOT, devgen);
}

Chan*
bootclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void	 
bootstat(Chan *c, char *dp)
{

M port/devcons.c => port/devcons.c +0 -6
@@ 406,12 406,6 @@ conswalk(Chan *c, char *name)
	return devwalk(c, name, consdir, NCONS, devgen);
}

Chan*
consclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void
consstat(Chan *c, char *dp)
{

M port/devdk.c => port/devdk.c +0 -6
@@ 753,12 753,6 @@ dkwalk(Chan *c, char *name)
		return devwalk(c, name, dksubdir, Nsubdir, streamgen);
}

Chan*
dkclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void	 
dkstat(Chan *c, char *dp)
{

M port/devdup.c => port/devdup.c +0 -6
@@ 46,12 46,6 @@ dupclone(Chan *c, Chan *nc)
	return devclone(c, nc);
}

Chan*
dupclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

int
dupwalk(Chan *c, char *name)
{

M port/devenv.c => port/devenv.c +0 -6
@@ 270,12 270,6 @@ envwalk(Chan *c, char *name)
	return 0;
}

Chan*
envclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void
envstat(Chan *c, char *db)
{

M port/devip.c => port/devip.c +0 -6
@@ 135,12 135,6 @@ ipwalk(Chan *c, char *name)
		return devwalk(c, name, ipsubdir, Nipsubdir, streamgen);
}

Chan*
ipclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void
ipstat(Chan *c, char *db)
{

M port/deviproute.c => port/deviproute.c +0 -6
@@ 222,12 222,6 @@ iproutewalk(Chan *c, char *name)
	return devwalk(c, name, iproutetab, (long)Niproutetab, devgen);
}

Chan*
iprouteclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void
iproutestat(Chan *c, char *db)
{

M port/devkprof.c => port/devkprof.c +0 -6
@@ 63,12 63,6 @@ kprofwalk(Chan *c, char *name)
	return devwalk(c, name, kproftab, (long)Nkproftab, devgen);
}

Chan*
kprofclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void
kprofstat(Chan *c, char *db)
{

M port/devlance.c => port/devlance.c +0 -6
@@ 581,12 581,6 @@ lancewalk(Chan *c, char *name)
		return devwalk(c, name, 0, 0, streamgen);
}

Chan*
lanceclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void	 
lancestat(Chan *c, char *dp)
{

M port/devmnt.c => port/devmnt.c +2 -45
@@ 353,6 353,7 @@ mntclone(Chan *c, Chan *nc)
	nc->flag = c->flag;
	nc->offset = c->offset;
	nc->mnt = c->mnt;
	nc->mountid = c->mountid;
	nc->aux = c->aux;
	nc->mntindex = c->mntindex;
	nc->mchan = c->mchan;


@@ 390,50 391,6 @@ mntwalk(Chan *c, char *name)
	return found;
}

Chan *
mntclwalk(Chan *c, char *name)
{
	Mnt *m;
	Mnthdr *mh;
	Chan *nc;

	nc = newchan();
	mh = 0;
	if(waserror()){
		close(nc);
		if(mh)
			mhfree(mh);
		return 0;
	}
	m = mntdev(c, 0);
	mh = mhalloc();
	mh->thdr.type = Tclwalk;
	mh->thdr.fid = c->fid;
	mh->thdr.newfid = nc->fid;
	strcpy(mh->thdr.name, name);
	mntxmit(m, mh);
	if(mh->rhdr.fid == mh->thdr.fid){
		/*
		 *  hack to indicate the most common error
		 */
		errors("directory entry not found");
	}
	nc->type = c->type;
	nc->dev = c->dev;
	nc->mode = c->mode;
	nc->flag = c->flag;
	nc->offset = c->offset;
	nc->mnt = c->mnt;
	nc->aux = c->aux;
	nc->mchan = c->mchan;
	nc->mqid = c->qid;
	nc->qid = mh->rhdr.qid;
	incref(m);
	poperror();
	mhfree(mh);
	return nc;
}

void	 
mntstat(Chan *c, char *dp)
{


@@ 784,7 741,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
		print("type mismatch %d %d\n", mh->rhdr.type, mh->thdr.type+1);
		error(Ebadmsg);
	}
	if(mh->rhdr.fid!=mh->thdr.fid && mh->thdr.type!=Tclwalk){
	if(mh->rhdr.fid != mh->thdr.fid){
		print("fid mismatch %d %d type %d\n", mh->rhdr.fid, mh->thdr.fid, mh->rhdr.type);
		error(Ebadmsg);
	}

M port/devnonet.c => port/devnonet.c +0 -6
@@ 202,12 202,6 @@ nonetwalk(Chan *c, char *name)
		return devwalk(c, name, nosubdir, Nsubdir, streamgen);
}

Chan*
nonetclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void	 
nonetstat(Chan *c, char *dp)
{

M port/devpipe.c => port/devpipe.c +0 -6
@@ 125,12 125,6 @@ pipewalk(Chan *c, char *name)
	return devwalk(c, name, pipedir, NPIPEDIR, pipegen);
}

Chan*
pipeclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void
pipestat(Chan *c, char *db)
{

M port/devproc.c => port/devproc.c +0 -6
@@ 101,12 101,6 @@ procwalk(Chan *c, char *name)
	return devwalk(c, name, 0, 0, procgen);
}

Chan*
procclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void
procstat(Chan *c, char *db)
{

M port/devroot.c => port/devroot.c +0 -6
@@ 61,12 61,6 @@ rootwalk(Chan *c, char *name)
	return devwalk(c, name, rootdir, nroot, devgen);
}

Chan*
rootclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void	 
rootstat(Chan *c, char *dp)
{

M port/devscsi.c => port/devscsi.c +0 -6
@@ 95,12 95,6 @@ scsiwalk(Chan *c, char *name)
	return devwalk(c, name, 0, 0, scsigen);
}

Chan*
scsiclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void
scsistat(Chan *c, char *db)
{

M port/devsrv.c => port/devsrv.c +0 -6
@@ 104,12 104,6 @@ srvwalk(Chan *c, char *name)
	return 1;
}

Chan*
srvclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void
srvstat(Chan *c, char *db)
{

M port/devwren.c => port/devwren.c +0 -6
@@ 170,12 170,6 @@ wrenwalk(Chan *c, char *name)
	return devwalk(c, name, wrendir, NWREN, wrengen);
}

Chan*
wrenclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void
wrenstat(Chan *c, char *db)
{

M port/fault.c => port/fault.c +1 -0
@@ 19,6 19,7 @@ fault(ulong addr, int read)
	int i, touched = 0;
	KMap *k, *k1;

	m->pfault++;
	s = seg(u->p, addr);
	if(s == 0){
		if(addr > USTKTOP)

M power/dat.h => power/dat.h +0 -1
@@ 193,7 193,6 @@ struct Dev
	long	 (*write)(Chan*, void*, long, ulong);
	void	 (*remove)(Chan*);
	void	 (*wstat)(Chan*, char*);
	Chan	*(*clwalk)(Chan*, char*);
};

struct Dirtab

M power/devbit3.c => power/devbit3.c +0 -6
@@ 68,12 68,6 @@ bit3clone(Chan *c, Chan *nc)
	return devclone(c, nc);
}

Chan*
bit3clwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

int	 
bit3walk(Chan *c, char *name)
{

M power/devhotrod.c => power/devhotrod.c +0 -6
@@ 152,12 152,6 @@ hotrodwalk(Chan *c, char *name)
	return devwalk(c, name, hotroddir, NHOTRODDIR, devgen);
}

Chan*
hotrodclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void	 
hotrodstat(Chan *c, char *dp)
{

M power/devhs.c => power/devhs.c +0 -6
@@ 184,12 184,6 @@ hsvmewalk(Chan *c, char *name)
	return devwalk(c, name, 0, 0, streamgen);
}

Chan*
hsvmeclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void	 
hsvmestat(Chan *c, char *dp)
{

M power/devrtc.c => power/devrtc.c +0 -6
@@ 104,12 104,6 @@ rtcwalk(Chan *c, char *name)
	return 0;
}

Chan*
rtcclwalk(Chan *c, char *name)
{
	return devclwalk(c, name);
}

void	 
rtcstat(Chan *c, char *dp)
{

M power/faultmips.c => power/faultmips.c +0 -1
@@ 17,7 17,6 @@ faultmips(Ureg *ur, int user, int code)
	extern char *excname[];
	int read;

	m->pfault++;
	addr = ur->badvaddr;
	addr &= ~(BY2PG-1);
	read = !(code==CTLBM || code==CTLBS);

M ss/dat.h => ss/dat.h +10 -1
@@ 111,6 111,7 @@ struct Chan
		Stream	*stream;	/* for stream channels */
		void	*aux;
		Qid	pgrpid;		/* for #p/notepg */
		int	mntindex;	/* for devmnt */
	};
	Chan	*mchan;			/* channel to mounted server */
	Qid	mqid;			/* qid of root of mount point */


@@ 178,7 179,6 @@ struct Dev
	long	 (*write)(Chan*, void*, long, ulong );
	void	 (*remove)(Chan*);
	void	 (*wstat)(Chan*, char*);
	Chan	*(*clwalk)(Chan*, char*);
};

struct Dirtab


@@ 227,6 227,15 @@ struct Mach
	char	pidhere[NTLBPID];	/* is this tlbpid possibly in this mmu? */
	int	lastpid;		/* last pid allocated on this machine */
	Proc	*pidproc[NTLBPID];	/* process that owns this pid on this mach */

	int	tlbfault;
	int	tlbpurge;
	int	pfault;
	int	cs;
	int	syscall;
	int	spinlock;
	int	intr;

	int	stack[1];
};