Plan 9 from Bell Labs’s /usr/web/sources/extra/changes/2005/0913

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


Add devwd - portable watchdog driver interface.
Also change dotdot algorithm as described in 9fans.
 [rsc] --rw-rw-r-- M 57833 rsc sys 2342 Sep 12 23:32 sys/src/9/port/devwd.c
 [rsc] --rw-rw-r-- M 57833 glenda sys 13624 Sep 13 00:37 sys/src/9/alphapc/main.c
	/n/sourcesdump/2005/0913/plan9/sys/src/9/alphapc/main.c:176,183 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/alphapc/main.c:176,183
	  	 * Then early kproc's will have a root and dot.
	  	 */
	  	up->slash = namec("#/", Atodir, 0, 0);
	- 	cnameclose(up->slash->name);
	- 	up->slash->name = newcname("/");
	+ 	pathclose(up->slash->path);
	+ 	up->slash->path = newpath("/");
	  	up->dot = cclone(up->slash);
	  
	  	chandevinit();
 [rsc] --rw-rw-r-- M 57833 glenda bitsy 9081 Sep 13 00:37 sys/src/9/bitsy/main.c
	/n/sourcesdump/2005/0913/plan9/sys/src/9/bitsy/main.c:96,103 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/bitsy/main.c:96,103
	  	 * Then early kproc's will have a root and dot.
	  	 */
	  	up->slash = namec("#/", Atodir, 0, 0);
	- 	cnameclose(up->slash->name);
	- 	up->slash->name = newcname("/");
	+ 	pathclose(up->slash->path);
	+ 	up->slash->path = newpath("/");
	  	up->dot = cclone(up->slash);
	  
	  	chandevinit();
 [rsc] --rw-rw-r-- M 57833 glenda sys 8342 Sep 13 00:37 sys/src/9/mtx/main.c
	/n/sourcesdump/2005/0913/plan9/sys/src/9/mtx/main.c:116,123 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/mtx/main.c:116,123
	  	 * Then early kproc's will have a root and dot.
	  	 */
	  	up->slash = namec("#/", Atodir, 0, 0);
	- 	cnameclose(up->slash->name);
	- 	up->slash->name = newcname("/");
	+ 	pathclose(up->slash->path);
	+ 	up->slash->path = newpath("/");
	  	up->dot = cclone(up->slash);
	  
	  	chandevinit();
 [rsc] --rw-rw-r-- M 57833 glenda sys 14691 Sep 13 00:37 sys/src/9/pc/main.c
	/n/sourcesdump/2005/0913/plan9/sys/src/9/pc/main.c:166,173 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/pc/main.c:166,173
	  	 * Then early kproc's will have a root and dot.
	  	 */
	  	up->slash = namec("#/", Atodir, 0, 0);
	- 	cnameclose(up->slash->name);
	- 	up->slash->name = newcname("/");
	+ 	pathclose(up->slash->path);
	+ 	up->slash->path = newpath("/");
	  	up->dot = cclone(up->slash);
	  
	  	chandevinit();
 [rsc] --rw-rw-r-- M 57833 glenda sys 9241 Sep 13 00:36 sys/src/9/port/cache.c
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/cache.c:148,154 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/cache.c:148,154
	  		o = e->start+e->len;
	  	}
	  	pprint("%s: 0x%lux.0x%lux %d %d %s (%d %c)\n",
	- 	s, m->qid.path, m->qid.vers, m->type, m->dev, c->name, nb, ct ? 'C' : 'N');
	+ 	s, m->qid.path, m->qid.vers, m->type, m->dev, c->path, nb, ct ? 'C' : 'N');
	  
	  	for(e = m->list; e; e = e->next) {
	  		pprint("\t%4d %5d %4d %lux\n",
 [rsc] --rw-rw-r-- M 57833 glenda sys 33640 Sep 13 00:35 sys/src/9/port/chan.c
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:6,16 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:6,44
	  #include	"../port/error.h"
	  
	  int chandebug=0;		/* toggled by sysr1 */
	- QLock chanprint;		/* probably asking for trouble (deadlocks) -rsc */
	+ #define DBG if(chandebug)iprint
	  
	- int domount(Chan**, Mhead**);
	+ enum
	+ {
	+ 	PATHSLOP	= 20,
	+ 	PATHMSLOP	= 20,
	+ };
	  
	- void
	+ struct
	+ {
	+ 	Lock;
	+ 	int	fid;
	+ 	Chan	*free;
	+ 	Chan	*list;
	+ }chanalloc;
	+ 
	+ typedef struct Elemlist Elemlist;
	+ 
	+ struct Elemlist
	+ {
	+ 	char	*aname;	/* original name */
	+ 	char	*name;	/* copy of name, so '/' can be overwritten */
	+ 	int	nelems;
	+ 	char	**elems;
	+ 	int	*off;
	+ 	int	mustbedir;
	+ 	int	nerror;
	+ 	int	prefix;
	+ };
	+ 
	+ #define SEP(c) ((c) == 0 || (c) == '/')
	+ 
	+ static void
	  dumpmount(void)		/* DEBUGGING */
	  {
	  	Pgrp *pg;
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:27,46 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:55,74
	  		return;
	  	}
	  	rlock(&pg->ns);
	- 	if(waserror()) {
	+ 	if(waserror()){
	  		runlock(&pg->ns);
	  		nexterror();
	  	}
	  
	  	he = &pg->mnthash[MNTHASH];
	- 	for(h = pg->mnthash; h < he; h++) {
	- 		for(f = *h; f; f = f->hash) {
	+ 	for(h = pg->mnthash; h < he; h++){
	+ 		for(f = *h; f; f = f->hash){
	  			print("head: %p: %s 0x%llux.%lud %C %lud -> \n", f,
	- 				f->from->name->s, f->from->qid.path,
	+ 				f->from->path->s, f->from->qid.path,
	  				f->from->qid.vers, devtab[f->from->type]->dc,
	  				f->from->dev);
	  			for(t = f->mount; t; t = t->next)
	- 				print("\t%p: %s (umh %p) (path %.8llux dev %C %lud)\n", t, t->to->name->s, t->to->umh, t->to->qid.path, devtab[t->to->type]->dc, t->to->dev);
	+ 				print("\t%p: %s (umh %p) (path %.8llux dev %C %lud)\n", t, t->to->path->s, t->to->umh, t->to->qid.path, devtab[t->to->type]->dc, t->to->dev);
	  		}
	  	}
	  	poperror();
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:47,95 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:75,92
	  	runlock(&pg->ns);
	  }
	  
	- 
	  char*
	- channame(Chan *c)		/* DEBUGGING */
	+ chanpath(Chan *c)
	  {
	  	if(c == nil)
	  		return "<nil chan>";
	- 	if(c->name == nil)
	- 		return "<nil name>";
	- 	if(c->name->s == nil)
	- 		return "<nil name.s>";
	- 	return c->name->s;
	+ 	if(c->path == nil)
	+ 		return "<nil path>";
	+ 	if(c->path->s == nil)
	+ 		return "<nil path.s>";
	+ 	return c->path->s;
	  }
	  
	- enum
	- {
	- 	CNAMESLOP	= 20
	- };
	- 
	- struct
	- {
	- 	Lock;
	- 	int	fid;
	- 	Chan	*free;
	- 	Chan	*list;
	- }chanalloc;
	- 
	- typedef struct Elemlist Elemlist;
	- 
	- struct Elemlist
	- {
	- 	char	*aname;	/* original name */
	- 	char	*name;	/* copy of name, so '/' can be overwritten */
	- 	int	nelems;
	- 	char	**elems;
	- 	int	*off;
	- 	int	mustbedir;
	- 	int	nerror;
	- 	int	prefix;
	- };
	- 
	- #define SEP(c) ((c) == 0 || (c) == '/')
	- void cleancname(Cname*);
	- 
	  int
	  isdotdot(char *p)
	  {
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:230,236 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:227,233
	  		chanalloc.free = c->next;
	  	unlock(&chanalloc);
	  
	- 	if(c == nil) {
	+ 	if(c == nil){
	  		c = smalloc(sizeof(Chan));
	  		lock(&chanalloc);
	  		c->fid = ++chanalloc.fid;
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:256,330 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:253,435
	  	c->mcp = 0;
	  	c->mux = 0;
	  	memset(&c->mqid, 0, sizeof(c->mqid));
	- 	c->name = 0;
	+ 	c->path = 0;
	  	c->ismtpt = 0;
	+ 	
	  	return c;
	  }
	  
	- static Ref ncname;
	+ Ref npath;
	  
	- Cname*
	- newcname(char *s)
	+ Path*
	+ newpath(char *s)
	  {
	- 	Cname *n;
	  	int i;
	+ 	Path *p;
	  
	- 	n = smalloc(sizeof(Cname));
	+ 	p = smalloc(sizeof(Path));
	  	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;
	+ 	p->len = i;
	+ 	p->alen = i+PATHSLOP;
	+ 	p->s = smalloc(p->alen);
	+ 	memmove(p->s, s, i+1);
	+ 	p->ref = 1;
	+ 	incref(&npath);
	+ 
	+ 	/*
	+ 	 * Cannot use newpath for arbitrary names because the mtpt 
	+ 	 * array will not be populated correctly.  The names #/ and / are
	+ 	 * allowed, but other names with / in them draw warnings.
	+ 	 */
	+ 	if(strchr(s, '/') && strcmp(s, "#/") != 0 && strcmp(s, "/") != 0)
	+ 		print("newpath: %s from %lux\n", s, getcallerpc(&s));
	+ 
	+ 	p->mlen = 1;
	+ 	p->malen = PATHMSLOP;
	+ 	p->mtpt = smalloc(p->malen*sizeof p->mtpt[0]);
	+ 	return p;
	  }
	  
	+ static Path*
	+ copypath(Path *p)
	+ {
	+ 	int i;
	+ 	Path *pp;
	+ 	
	+ 	pp = smalloc(sizeof(Path));
	+ 	pp->ref = 1;
	+ 	incref(&npath);
	+ 	DBG("copypath %s %p => %p\n", p->s, p, pp);
	+ 	
	+ 	pp->len = p->len;
	+ 	pp->alen = p->alen;
	+ 	pp->s = smalloc(p->alen);
	+ 	memmove(pp->s, p->s, p->len+1);
	+ 	
	+ 	pp->mlen = p->mlen;
	+ 	pp->malen = p->malen;
	+ 	pp->mtpt = smalloc(p->malen*sizeof pp->mtpt[0]);
	+ 	for(i=0; i<pp->mlen; i++){
	+ 		pp->mtpt[i] = p->mtpt[i];
	+ 		if(pp->mtpt[i])
	+ 			incref(pp->mtpt[i]);
	+ 	}
	+ 
	+ 	return pp;
	+ }
	+ 
	  void
	- cnameclose(Cname *n)
	+ pathclose(Path *p)
	  {
	- 	if(n == nil)
	+ 	int i;
	+ 	
	+ 	if(p == nil)
	  		return;
	- 	if(decref(n))
	+ //XXX
	+ 	DBG("pathclose %p %s ref=%ld =>", p, p->s, p->ref);
	+ 	for(i=0; i<p->mlen; i++)
	+ 		DBG(" %p", p->mtpt[i]);
	+ 	DBG("\n");
	+ 
	+ 	if(decref(p))
	  		return;
	- 	decref(&ncname);
	- 	free(n->s);
	- 	free(n);
	+ 	decref(&npath);
	+ 	free(p->s);
	+ 	for(i=0; i<p->mlen; i++)
	+ 		if(p->mtpt[i])
	+ 			cclose(p->mtpt[i]);
	+ 	free(p->mtpt);
	+ 	free(p);
	  }
	  
	- Cname*
	- addelem(Cname *n, char *s)
	+ /*
	+  * In place, rewrite name to compress multiple /, eliminate ., and process ..
	+  * (Really only called to remove a trailing .. that has been added.
	+  * Otherwise would need to update n->mtpt as well.)
	+  */
	+ static void
	+ fixdotdotname(Path *p)
	  {
	- 	int i, a;
	- 	char *t;
	- 	Cname *new;
	+ 	char *r;
	  
	- 	if(s[0]=='.' && s[1]=='\0')
	- 		return n;
	+ 	if(p->s[0] == '#'){
	+ 		r = strchr(p->s, '/');
	+ 		if(r == nil)
	+ 			return;
	+ 		cleanname(r);
	  
	- 	if(n->ref > 1){
	+ 		/*
	+ 		 * The correct name is #i rather than #i/,
	+ 		 * but the correct name of #/ is #/.
	+ 		 */
	+ 		if(strcmp(r, "/")==0 && p->s[1] != '/')
	+ 			*r = '\0';
	+ 	}else
	+ 		cleanname(p->s);
	+ 	p->len = strlen(p->s);
	+ }
	+ 
	+ static Path*
	+ uniquepath(Path *p)
	+ {
	+ 	Path *new;
	+ 	
	+ 	if(p->ref > 1){
	  		/* copy on write */
	- 		new = newcname(n->s);
	- 		cnameclose(n);
	- 		n = new;
	+ 		new = copypath(p);
	+ 		pathclose(p);
	+ 		p = new;
	  	}
	+ 	return p;
	+ }
	  
	+ static Path*
	+ addelem(Path *p, char *s, Chan *from)
	+ {
	+ 	char *t;
	+ 	int a, i;
	+ 	Chan *c, **tt;
	+ 
	+ 	if(s[0]=='.' && s[1]=='\0')
	+ 		return p;
	+ 
	+ 	p = uniquepath(p);
	+ 
	  	i = strlen(s);
	- 	if(n->len+1+i+1 > n->alen){
	- 		a = n->len+1+i+1 + CNAMESLOP;
	+ 	if(p->len+1+i+1 > p->alen){
	+ 		a = p->len+1+i+1 + PATHSLOP;
	  		t = smalloc(a);
	- 		memmove(t, n->s, n->len+1);
	- 		free(n->s);
	- 		n->s = t;
	- 		n->alen = a;
	+ 		memmove(t, p->s, p->len+1);
	+ 		free(p->s);
	+ 		p->s = t;
	+ 		p->alen = a;
	  	}
	- 	if(n->len>0 && n->s[n->len-1]!='/' && s[0]!='/')	/* don't insert extra slash if one is present */
	- 		n->s[n->len++] = '/';
	- 	memmove(n->s+n->len, s, i+1);
	- 	n->len += i;
	- 	if(isdotdot(s))
	- 		cleancname(n);
	- 	return n;
	+ 	/* don't insert extra slash if one is present */
	+ 	if(p->len>0 && p->s[p->len-1]!='/' && s[0]!='/')
	+ 		p->s[p->len++] = '/';
	+ 	memmove(p->s+p->len, s, i+1);
	+ 	p->len += i;
	+ 	if(isdotdot(s)){
	+ 		fixdotdotname(p);
	+ 		DBG("addelem %s .. => rm %p\n", p->s, p->mtpt[p->mlen-1]);
	+ 		if(p->mlen>0 && (c = p->mtpt[--p->mlen])){
	+ 			p->mtpt[p->mlen] = nil;
	+ 			cclose(c);
	+ 		}
	+ 	}else{
	+ 		if(p->mlen >= p->malen){
	+ 			p->malen = p->mlen+1+PATHMSLOP;
	+ 			tt = smalloc(p->malen*sizeof tt[0]);
	+ 			memmove(tt, p->mtpt, p->mlen*sizeof tt[0]);
	+ 			free(p->mtpt);
	+ 			p->mtpt = tt;
	+ 		}
	+ 		DBG("addelem %s %s => add %p\n", p->s, s, from);
	+ 		p->mtpt[p->mlen++] = from;
	+ 		if(from)
	+ 			incref(from);
	+ 	}
	+ 	return p;
	  }
	  
	  void
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:355,361 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:460,467
	  		c->mchan = nil;
	  	}
	  
	- 	cnameclose(c->name);
	+ 	pathclose(c->path);
	+ 	c->path = nil;
	  
	  	lock(&chanalloc);
	  	c->next = chanalloc.free;
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:369,374 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:475,481
	  	if(c->flag&CFREE)
	  		panic("cclose %lux", getcallerpc(&c));
	  
	+ 	DBG("cclose %p name=%s ref=%ld\n", c, c->path->s, c->ref);
	  	if(decref(c))
	  		return;
	  
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:387,393 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:494,500
	  {
	  	Chan *nc;
	  
	- 	if(c->ref != 1) {
	+ 	if(c->ref != 1){
	  		nc = cclone(c);
	  		cclose(c);
	  		c = nc;
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:403,413 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:510,520
	  }
	  
	  int
	- eqchan(Chan *a, Chan *b, int pathonly)
	+ eqchan(Chan *a, Chan *b, int skipvers)
	  {
	  	if(a->qid.path != b->qid.path)
	  		return 0;
	- 	if(!pathonly && a->qid.vers!=b->qid.vers)
	+ 	if(!skipvers && a->qid.vers!=b->qid.vers)
	  		return 0;
	  	if(a->type != b->type)
	  		return 0;
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:417,427 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:524,534
	  }
	  
	  int
	- eqchantdqid(Chan *a, int type, int dev, Qid qid, int pathonly)
	+ eqchantdqid(Chan *a, int type, int dev, Qid qid, int skipvers)
	  {
	  	if(a->qid.path != qid.path)
	  		return 0;
	- 	if(!pathonly && a->qid.vers!=qid.vers)
	+ 	if(!skipvers && a->qid.vers!=qid.vers)
	  		return 0;
	  	if(a->type != type)
	  		return 0;
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:439,452 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:546,551
	  	mh->ref = 1;
	  	mh->from = from;
	  	incref(from);
	- 
	- /*
	- 	n = from->name->len;
	- 	if(n >= sizeof(mh->fromname))
	- 		n = sizeof(mh->fromname)-1;
	- 	memmove(mh->fromname, from->name->s, n);
	- 	mh->fromname[n] = 0;
	- */
	  	return mh;
	  }
	  
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:453,468 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:552,568
	  int
	  cmount(Chan **newp, Chan *old, int flag, char *spec)
	  {
	- 	Pgrp *pg;
	  	int order, flg;
	+ 	Chan *new;
	  	Mhead *m, **l, *mh;
	  	Mount *nm, *f, *um, **h;
	- 	Chan *new;
	+ 	Pgrp *pg;
	  
	  	if(QTDIR & (old->qid.type^(*newp)->qid.type))
	  		error(Emount);
	  
	- if(old->umh)print("cmount old extra umh\n");
	+ 	if(old->umh)
	+ 		print("cmount: unexpected umh, caller %.8lux\n", getcallerpc(&newp));
	  
	  	order = flag&MORDER;
	  
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:473,492 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:573,594
	  	mh = new->umh;
	  
	  	/*
	- 	 * Not allowed to bind when the old directory
	- 	 * is itself a union.  (Maybe it should be allowed, but I don't see
	- 	 * what the semantics would be.)
	+ 	 * Not allowed to bind when the old directory is itself a union. 
	+ 	 * (Maybe it should be allowed, but I don't see what the semantics
	+ 	 * would be.)
	  	 *
	  	 * We need to check mh->mount->next to tell unions apart from
	  	 * simple mount points, so that things like
	  	 *	mount -c fd /root
	  	 *	bind -c /root /
	- 	 * work.  The check of mount->mflag catches things like
	+ 	 * work.  
	+ 	 * 
	+ 	 * The check of mount->mflag allows things like
	  	 *	mount fd /root
	  	 *	bind -c /root /
	  	 * 
	  	 * This is far more complicated than it should be, but I don't
	- 	 * see an easier way at the moment.		-rsc
	+ 	 * see an easier way at the moment.
	  	 */
	  	if((flag&MCREATE) && mh && mh->mount
	  	&& (mh->mount->next || !(mh->mount->mflag&MCREATE)))
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:496,508 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:598,610
	  	wlock(&pg->ns);
	  
	  	l = &MOUNTH(pg, old->qid);
	- 	for(m = *l; m; m = m->hash) {
	+ 	for(m = *l; m; m = m->hash){
	  		if(eqchan(m->from, old, 1))
	  			break;
	  		l = &m->hash;
	  	}
	  
	- 	if(m == nil) {
	+ 	if(m == nil){
	  		/*
	  		 *  nothing mounted here yet.  create a mount
	  		 *  head and add to the hash table.
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:525,531 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:627,633
	  	wunlock(&pg->ns);
	  
	  	nm = newmount(m, new, flag, spec);
	- 	if(mh != nil && mh->mount != nil) {
	+ 	if(mh != nil && mh->mount != nil){
	  		/*
	  		 *  copy a union when binding it onto a directory
	  		 */
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:534,540 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:636,642
	  			flg = MAFTER;
	  		h = &nm->next;
	  		um = mh->mount;
	- 		for(um = um->next; um; um = um->next) {
	+ 		for(um = um->next; um; um = um->next){
	  			f = newmount(m, um->to, flg, um->spec);
	  			*h = f;
	  			h = &f->next;
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:541,547 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:643,649
	  		}
	  	}
	  
	- 	if(m->mount && order == MREPL) {
	+ 	if(m->mount && order == MREPL){
	  		mountfree(m->mount);
	  		m->mount = 0;
	  	}
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:549,560 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:651,661
	  	if(flag & MCREATE)
	  		nm->mflag |= MCREATE;
	  
	- 	if(m->mount && order == MAFTER) {
	+ 	if(m->mount && order == MAFTER){
	  		for(f = m->mount; f->next; f = f->next)
	  			;
	  		f->next = nm;
	- 	}
	- 	else {
	+ 	}else{
	  		for(f = nm; f->next; f = f->next)
	  			;
	  		f->next = m->mount;
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:589,607 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:690,708
	  	wlock(&pg->ns);
	  
	  	l = &MOUNTH(pg, mnt->qid);
	- 	for(m = *l; m; m = m->hash) {
	+ 	for(m = *l; m; m = m->hash){
	  		if(eqchan(m->from, mnt, 1))
	  			break;
	  		l = &m->hash;
	  	}
	  
	- 	if(m == 0) {
	+ 	if(m == 0){
	  		wunlock(&pg->ns);
	  		error(Eunmount);
	  	}
	  
	  	wlock(&m->lock);
	- 	if(mounted == 0) {
	+ 	if(mounted == 0){
	  		*l = m->hash;
	  		wunlock(&pg->ns);
	  		mountfree(m->mount);
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:613,626 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:714,727
	  	}
	  
	  	p = &m->mount;
	- 	for(f = *p; f; f = f->next) {
	+ 	for(f = *p; f; f = f->next){
	  		/* BUG: Needs to be 2 pass */
	  		if(eqchan(f->to, mounted, 1) ||
	- 		  (f->to->mchan && eqchan(f->to->mchan, mounted, 1))) {
	+ 		  (f->to->mchan && eqchan(f->to->mchan, mounted, 1))){
	  			*p = f->next;
	  			f->next = 0;
	  			mountfree(f);
	- 			if(m->mount == nil) {
	+ 			if(m->mount == nil){
	  				*l = m->hash;
	  				cclose(m->from);
	  				wunlock(&m->lock);
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:650,661 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:751,763
	  		error("clone failed");
	  	nc = wq->clone;
	  	free(wq);
	- 	nc->name = c->name;
	- 	if(c->name)
	- 		incref(c->name);
	+ 	nc->path = c->path;
	+ 	if(c->path)
	+ 		incref(c->path);
	  	return nc;
	  }
	  
	+ /* also used by sysfile.c:/^mountfix */
	  int
	  findmount(Chan **cp, Mhead **mp, int type, int dev, Qid qid)
	  {
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:693,750 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:795,855
	  	return 0;
	  }
	  
	- int
	- domount(Chan **cp, Mhead **mp)
	+ /*
	+  * Calls findmount but also updates path.
	+  */
	+ static int
	+ domount(Chan **cp, Mhead **mp, Path **path)
	  {
	- 	return findmount(cp, mp, (*cp)->type, (*cp)->dev, (*cp)->qid);
	+ 	Chan **lc;
	+ 	Path *p;
	+ 
	+ 	if(findmount(cp, mp, (*cp)->type, (*cp)->dev, (*cp)->qid) == 0)
	+ 		return 0;
	+ 
	+ 	if(path){
	+ 		p = *path;
	+ 		p = uniquepath(p);
	+ 		if(p->mlen <= 0)
	+ 			print("domount: path %s has mlen==%d\n", p->s, p->mlen);
	+ 		else{
	+ 			lc = &p->mtpt[p->mlen-1];
	+ DBG("domount %p %s => add %p (was %p)\n", p, p->s, (*mp)->from, p->mtpt[p->mlen-1]);
	+ 			incref((*mp)->from);
	+ 			if(*lc)
	+ 				cclose(*lc);
	+ 			*lc = (*mp)->from;
	+ 		}
	+ 		*path = p;
	+ 	}
	+ 	return 1;
	  }
	  
	- Chan*
	- undomount(Chan *c, Cname *name)
	+ /*
	+  * If c is the right-hand-side of a mount point, returns the left hand side.
	+  * Changes name to reflect the fact that we've uncrossed the mountpoint,
	+  * so name had better be ours to change!
	+  */
	+ static Chan*
	+ undomount(Chan *c, Path *path)
	  {
	  	Chan *nc;
	- 	Pgrp *pg;
	- 	Mount *t;
	- 	Mhead **h, **he, *f;
	  
	- 	pg = up->pgrp;
	- 	rlock(&pg->ns);
	- 	if(waserror()) {
	- 		runlock(&pg->ns);
	- 		nexterror();
	- 	}
	+ 	if(path->ref != 1 || path->mlen == 0)
	+ 		print("undomount: path %s ref %ld mlen %d caller %lux\n",
	+ 			path->s, path->ref, path->mlen, getcallerpc(&c));
	  
	- 	he = &pg->mnthash[MNTHASH];
	- 	for(h = pg->mnthash; h < he; h++) {
	- 		for(f = *h; f; f = f->hash) {
	- 			if(strcmp(f->from->name->s, name->s) != 0)
	- 				continue;
	- 			for(t = f->mount; t; t = t->next) {
	- 				if(eqchan(c, t->to, 1)) {
	- 					/*
	- 					 * We want to come out on the left hand side of the mount
	- 					 * point using the element of the union that we entered on.
	- 					 * To do this, find the element that has a from name of
	- 					 * c->name->s.
	- 					 */
	- 					if(strcmp(t->head->from->name->s, name->s) != 0)
	- 						continue;
	- 					nc = t->head->from;
	- 					incref(nc);
	- 					cclose(c);
	- 					c = nc;
	- 					break;
	- 				}
	- 			}
	- 		}
	+ 	if(path->mlen>0 && (nc=path->mtpt[path->mlen-1]) != nil){
	+ DBG("undomount %p %s => remove %p\n", path, path->s, nc);
	+ 		cclose(c);
	+ 		path->mtpt[path->mlen-1] = nil;
	+ 		c = nc;
	  	}
	- 	poperror();
	- 	runlock(&pg->ns);
	  	return c;
	  }
	  
	  /*
	-  * Walk but catch errors and return nil instead.
	+  * Call dev walk but catch errors.
	   */
	  static Walkqid*
	  ewalk(Chan *c, Chan *nc, char **name, int nname)
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:767,782 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:872,887
	  walk(Chan **cp, char **names, int nnames, int nomount, int *nerror)
	  {
	  	int dev, dotdot, i, n, nhave, ntry, type;
	- 	Chan *c, *nc;
	- 	Cname *cname;
	- 	Mount *f;
	+ 	Chan *c, *nc, *mtpt;
	+ 	Path *path;
	  	Mhead *mh, *nmh;
	+ 	Mount *f;
	  	Walkqid *wq;
	  
	  	c = *cp;
	  	incref(c);
	- 	cname = c->name;
	- 	incref(cname);
	+ 	path = c->path;
	+ 	incref(path);
	  	mh = nil;
	  
	  	/*
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:787,799 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:892,904
	  	 *    4. repeat.
	  	 *
	  	 * An invariant is that each time through the loop, c is on the undomount
	- 	 * side of the mount point, and c's name is cname.
	+ 	 * side of the mount point, and c's full path is path.
	  	 */
	  	for(nhave=0; nhave<nnames; nhave+=n){
	  		if((c->qid.type&QTDIR)==0){
	  			if(nerror)
	  				*nerror = nhave;
	- 			cnameclose(cname);
	+ 			pathclose(path);
	  			cclose(c);
	  			strcpy(up->errstr, Enotdir);
	  			if(mh != nil)
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:816,823 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:921,928
	  		}
	  
	  		if(!dotdot && !nomount)
	- 			domount(&c, &mh);
	- 
	+ 			domount(&c, &mh, &path);
	+ 				
	  		type = c->type;
	  		dev = c->dev;
	  
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:839,845 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:944,950
	  			}
	  			if(wq == nil){
	  				cclose(c);
	- 				cnameclose(cname);
	+ 				pathclose(path);
	  				if(nerror)
	  					*nerror = nhave+1;
	  				if(mh != nil)
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:853,863 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:958,969
	  			assert(wq->nqid == 1);
	  			assert(wq->clone != nil);
	  
	- 			cname = addelem(cname, "..");
	- 			nc = undomount(wq->clone, cname);
	+ 			path = addelem(path, "..", nil);
	+ 			nc = undomount(wq->clone, path);
	  			n = 1;
	  		}else{
	  			nc = nil;
	+ 			nmh = nil;
	  			if(!nomount)
	  				for(i=0; i<wq->nqid && i<ntry-1; i++)
	  					if(findmount(&nc, &nmh, type, dev, wq->qid[i]))
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:865,871 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:971,977
	  			if(nc == nil){	/* no mount points along path */
	  				if(wq->clone == nil){
	  					cclose(c);
	- 					cnameclose(cname);
	+ 					pathclose(path);
	  					if(wq->nqid==0 || (wq->qid[wq->nqid-1].type&QTDIR)){
	  						if(nerror)
	  							*nerror = nhave+wq->nqid+1;
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:889,896 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:995,1006
	  				}
	  				n = i+1;
	  			}
	- 			for(i=0; i<n; i++)
	- 				cname = addelem(cname, names[nhave+i]);
	+ 			for(i=0; i<n; i++){
	+ 				mtpt = nil;
	+ 				if(i==n-1 && nmh)
	+ 					mtpt = nmh->from;
	+ 				path = addelem(path, names[nhave+i], mtpt);
	+ 			}
	  		}
	  		cclose(c);
	  		c = nc;
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:909,916 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:1019,1026
	  		c->umh = nil;
	  	}
	  
	- 	cnameclose(c->name);
	- 	c->name = cname;
	+ 	pathclose(c->path);
	+ 	c->path = path;
	  
	  	cclose(*cp);
	  	*cp = c;
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:929,940 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:1039,1050
	  	Mount *f;
	  
	  	rlock(&m->lock);
	- 	if(waserror()) {
	+ 	if(waserror()){
	  		runlock(&m->lock);
	  		nexterror();
	  	}
	- 	for(f = m->mount; f; f = f->next) {
	- 		if(f->mflag&MCREATE) {
	+ 	for(f = m->mount; f; f = f->next){
	+ 		if(f->mflag&MCREATE){
	  			nc = cclone(f->to);
	  			runlock(&m->lock);
	  			poperror();
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:951,981 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:1061,1066
	  {
	  }
	  
	- /*
	-  * In place, rewrite name to compress multiple /, eliminate ., and process ..
	-  */
	- void
	- cleancname(Cname *n)
	- {
	- 	char *p;
	- 
	- 	if(n->s[0] == '#'){
	- 		p = strchr(n->s, '/');
	- 		if(p == nil)
	- 			return;
	- 		cleanname(p);
	- 
	- 		/*
	- 		 * The correct name is #i rather than #i/,
	- 		 * but the correct name of #/ is #/.
	- 		 */
	- 		if(strcmp(p, "/")==0 && n->s[1] != '/')
	- 			*p = '\0';
	- 	}else
	- 		cleanname(n->s);
	- 	n->len = strlen(n->s);
	- }
	- 
	  static void
	  growparse(Elemlist *e)
	  {
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:1035,1041 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:1120,1126
	  		name = slash;
	  	}
	  	
	- 	if(chandebug){
	+ 	if(0 && chandebug){
	  		int i;
	  		
	  		print("parsename %s:", e->name);
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:1129,1135 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:1214,1220
	  {
	  	int len, n, t, nomount;
	  	Chan *c, *cnew;
	- 	Cname *cname;
	+ 	Path *path;
	  	Elemlist e;
	  	Rune r;
	  	Mhead *m;
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:1143,1148 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:1228,1234
	  		free(aname);
	  		nexterror();
	  	}
	+ 	DBG("namec %s %d %d\n", aname, amode, omode);
	  	name = aname;
	  
	  	/*
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:1217,1223 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:1303,1309
	  		if(e.off[e.nerror]==0)
	  			print("nerror=%d but off=%d\n",
	  				e.nerror, e.off[e.nerror]);
	- 		if(chandebug)
	+ 		if(0 && chandebug)
	  			print("showing %d+%d/%d (of %d) of %s (%d %d)\n", e.prefix, e.off[e.nerror], e.nerror, e.nelems, aname, e.off[0], e.off[1]);
	  		len = e.prefix+e.off[e.nerror];
	  		free(e.off);
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:1225,1231 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:1311,1317
	  	}
	  
	  	/*
	- 	 * Build a list of elements in the path.
	+ 	 * Build a list of elements in the name.
	  	 */
	  	parsename(name, &e);
	  
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:1261,1269 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:1347,1356
	  
	  	switch(amode){
	  	case Abind:
	+ 		/* no need to maintain path - cannot dotdot an Abind */
	  		m = nil;
	  		if(!nomount)
	- 			domount(&c, &m);
	+ 			domount(&c, &m, nil);
	  		if(c->umh != nil)
	  			putmhead(c->umh);
	  		c->umh = m;
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:1273,1291 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:1360,1378
	  	case Aremove:
	  	case Aopen:
	  	Open:
	- 		/* save the name; domount might change c */
	- 		cname = c->name;
	- 		incref(cname);
	+ 		/* save&update the name; domount might change c */
	+ 		path = c->path;
	+ 		incref(path);
	  		m = nil;
	  		if(!nomount)
	- 			domount(&c, &m);
	+ 			domount(&c, &m, &path);
	  
	  		/* our own copy to open or remove */
	  		c = cunique(c);
	  
	  		/* now it's our copy anyway, we can put the name back */
	- 		cnameclose(c->name);
	- 		c->name = cname;
	+ 		pathclose(c->path);
	+ 		c->path = path;
	  
	  		/* record whether c is on a mount point */
	  		c->ismtpt = m!=nil;
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:1414,1422 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:1501,1509
	  			 * if findmount gave us a new Chan.
	  			 */
	  			cnew = cunique(cnew);
	- 			cnameclose(cnew->name);
	- 			cnew->name = c->name;
	- 			incref(cnew->name);
	+ 			pathclose(cnew->path);
	+ 			cnew->path = c->path;
	+ 			incref(cnew->path);
	  
	  			devtab[cnew->type]->create(cnew, e.elems[e.nelems-1], omode&~(OEXCL|OCEXEC), perm);
	  			poperror();
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:1428,1434 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:1515,1521
	  				putmhead(m);
	  			cclose(c);
	  			c = cnew;
	- 			c->name = addelem(c->name, e.elems[e.nelems-1]);
	+ 			c->path = addelem(c->path, e.elems[e.nelems-1], nil);
	  			break;
	  		}else{		/* create failed */
	  			cclose(cnew);
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/chan.c:1513,1524 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/chan.c:1600,1611
	  	Rune r;
	  
	  	name = aname;
	- 	if(((ulong)name & KZERO) != KZERO) {
	+ 	if(((ulong)name & KZERO) != KZERO){
	  		if(!dup)
	  			print("warning: validname called from %lux with user pointer", pc);
	  		p = name;
	  		t = BY2PG-((ulong)p&(BY2PG-1));
	- 		while((ename=vmemchr(p, 0, t)) == nil) {
	+ 		while((ename=vmemchr(p, 0, t)) == nil){
	  			p += t;
	  			t = BY2PG;
	  		}
 [rsc] --rw-rw-r-- M 57833 glenda sys 8246 Sep 13 00:36 sys/src/9/port/dev.c
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/dev.c:135,141 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/dev.c:135,141
	  		spec = "";
	  	buf = smalloc(4+strlen(spec)+1);
	  	sprint(buf, "#%C%s", tc, spec);
	- 	c->name = newcname(buf);
	+ 	c->path = newpath(buf);
	  	free(buf);
	  	return c;
	  }
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/dev.c:269,280 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/dev.c:269,280
	  		switch((*gen)(c, nil, tab, ntab, i, &dir)){
	  		case -1:
	  			if(c->qid.type & QTDIR){
	- 				if(c->name == nil)
	+ 				if(c->path == nil)
	  					elem = "???";
	- 				else if(strcmp(c->name->s, "/") == 0)
	+ 				else if(strcmp(c->path->s, "/") == 0)
	  					elem = "/";
	  				else
	- 					for(elem=p=c->name->s; *p; p++)
	+ 					for(elem=p=c->path->s; *p; p++)
	  						if(*p == '/')
	  							elem = p+1;
	  				devdir(c, c->qid, elem, 0, eve, DMDIR|0555, &dir);
 [rsc] --rw-rw-r-- M 57833 glenda sys 21545 Sep 13 00:36 sys/src/9/port/devmnt.c
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/devmnt.c:771,781 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/devmnt.c:771,781
	  		if(t == r->request.type+1)
	  			break;
	  		sn = "?";
	- 		if(m->c->name != nil)
	- 			sn = m->c->name->s;
	+ 		if(m->c->path != nil)
	+ 			sn = m->c->path->s;
	  		cn = "?";
	- 		if(r->c != nil && r->c->name != nil)
	- 			cn = r->c->name->s;
	+ 		if(r->c != nil && r->c->path != nil)
	+ 			cn = r->c->path->s;
	  		print("mnt: proc %s %lud: mismatch from %s %s rep 0x%lux 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,
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/devmnt.c:1150,1161 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/devmnt.c:1150,1161
	  	/* This routine is mostly vestiges of prior lives; now it's just sanity checking */
	  
	  	if(c->mchan == nil)
	- 		panic("mntchk 1: nil mchan c %s\n", channame(c));
	+ 		panic("mntchk 1: nil mchan c %s\n", chanpath(c));
	  
	  	m = c->mchan->mux;
	  
	  	if(m == nil)
	- 		print("mntchk 2: nil mux c %s c->mchan %s \n", channame(c), channame(c->mchan));
	+ 		print("mntchk 2: nil mux c %s c->mchan %s \n", chanpath(c), chanpath(c->mchan));
	  
	  	/*
	  	 * Was it closed and reused (was error(Eshutdown); now, it cannot happen)
 [rsc] --rw-rw-r-- M 57833 glenda sys 28465 Sep 13 00:36 sys/src/9/port/devproc.c
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/devproc.c:539,545 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/devproc.c:539,545
	  		&"r w rw"[(c->mode&3)<<1],
	  		devtab[c->type]->dc, c->dev,
	  		c->qid.path, w, c->qid.vers, c->qid.type,
	- 		c->iounit, c->offset, c->name->s);
	+ 		c->iounit, c->offset, c->path->s);
	  	return n;
	  }
	  
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/devproc.c:570,576 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/devproc.c:570,576
	  		nexterror();
	  	}
	  
	- 	n = readstr(0, a, count, p->dot->name->s);
	+ 	n = readstr(0, a, count, p->dot->path->s);
	  	n += snprint(a+n, count-n, "\n");
	  	offset = procoffset(offset, a, &n);
	  	/* compute width of qid.path */
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/devproc.c:935,955 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/devproc.c:935,955
	  		mntscan(mw, p);
	  		if(mw->mh == 0){
	  			mw->cddone = 1;
	- 			i = snprint(a, n, "cd %s\n", p->dot->name->s);
	+ 			i = snprint(a, n, "cd %s\n", p->dot->path->s);
	  			qunlock(&p->debug);
	  			poperror();
	  			return i;
	  		}
	  		int2flag(mw->cm->mflag, flag);
	- 		if(strcmp(mw->cm->to->name->s, "#M") == 0){
	+ 		if(strcmp(mw->cm->to->path->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, mw->cm->spec? mw->cm->spec : "");
	+ 				srv==nil? mw->cm->to->mchan->path->s : srv,
	+ 				mw->mh->from->path->s, mw->cm->spec? 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);
	+ 				mw->cm->to->path->s, mw->mh->from->path->s);
	  		qunlock(&p->debug);
	  		poperror();
	  		return i;
 [rsc] --rw-rw-r-- M 57833 glenda sys 7282 Sep 13 00:36 sys/src/9/port/fault.c
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/fault.c:44,51 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/fault.c:44,51
	  {
	  	char buf[ERRMAX];
	  
	- 	if(c && c->name){
	- 		snprint(buf, sizeof buf, "%s accessing %s: %s", s, c->name->s, up->errstr);
	+ 	if(c && c->path){
	+ 		snprint(buf, sizeof buf, "%s accessing %s: %s", s, c->path->s, up->errstr);
	  		s = buf;
	  	}
	  	if(up->nerrlab) {
 [rsc] --rw-rw-r-- M 57833 glenda sys 22608 Sep 13 00:35 sys/src/9/port/portdat.h
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/portdat.h:3,9 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/portdat.h:3,8
	  typedef struct Chan	Chan;
	  typedef struct Cmdbuf	Cmdbuf;
	  typedef struct Cmdtab	Cmdtab;
	- typedef struct Cname	Cname;
	  typedef struct Dev	Dev;
	  typedef struct Dirtab	Dirtab;
	  typedef struct Edf	Edf;
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/portdat.h:22,27 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/portdat.h:21,27
	  typedef struct Mhead	Mhead;
	  typedef struct Note	Note;
	  typedef struct Page	Page;
	+ typedef struct Path	Path;
	  typedef struct Palloc	Palloc;
	  typedef struct Perf	Perf;
	  typedef struct PhysUart	PhysUart;
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/portdat.h:186,200 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/portdat.h:186,203
	  	};
	  	Chan*	mchan;			/* channel to mounted server */
	  	Qid	mqid;			/* qid of root of mount point */
	- 	Cname*	name;
	+ 	Path*	path;
	  };
	  
	- struct Cname
	+ struct Path
	  {
	  	Ref;
	- 	int	alen;			/* allocated length */
	- 	int	len;			/* strlen(s) */
	  	char	*s;
	+ 	Chan	**mtpt;			/* mtpt history */
	+ 	int	len;			/* strlen(s) */
	+ 	int	alen;			/* allocated length of s */
	+ 	int	mlen;			/* number of path elements */
	+ 	int	malen;			/* allocated length of mtpt */
	  };
	  
	  struct Dev
 [rsc] --rw-rw-r-- M 57833 glenda sys 11002 Sep 13 00:35 sys/src/9/port/portfns.h
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/portfns.h:18,24 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/portfns.h:18,24
	  void		cachedel(Image*, ulong);
	  void		cachepage(Page*, Image*);
	  void		callwithureg(void(*)(Ureg*));
	- char*		channame(Chan*);
	+ char*		chanpath(Chan*);
	  int		canlock(Lock*);
	  int		canpage(Proc*);
	  int		canqlock(QLock*);
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/portfns.h:39,45 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/portfns.h:39,44
	  long		clrfpintr(void);
	  void		cmderror(Cmdbuf*, char*);
	  int		cmount(Chan**, Chan*, int, char*);
	- void		cnameclose(Cname*);
	  void		confinit(void);
	  int		consactive(void);
	  void		(*consdebug)(void);
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/portfns.h:192,202 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/portfns.h:191,201
	  Mhead*		newmhead(Chan*);
	  Mount*		newmount(Mhead*, Chan*, int, char*);
	  Page*		newpage(int, Segment **, ulong);
	+ Path*		newpath(char*);
	  Pgrp*		newpgrp(void);
	  Rgrp*		newrgrp(void);
	  Proc*		newproc(void);
	  void		nexterror(void);
	- Cname*		newcname(char*);
	  int		notify(Ureg*);
	  int		nrand(int);
	  uvlong		ns2fastticks(uvlong);
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/portfns.h:209,214 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/portfns.h:208,214
	  void		pagersummary(void);
	  void		panic(char*, ...);
	  Cmdbuf*		parsecmd(char *a, int n);
	+ void		pathclose(Path*);
	  ulong		perfticks(void);
	  void		pexit(char*, int);
	  int		preempted(void);
 [rsc] --rw-rw-r-- M 57833 glenda sys 22173 Sep 13 00:36 sys/src/9/port/sysfile.c
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/sysfile.c:178,188 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/sysfile.c:178,184
	  	validaddr(arg[1], arg[2], 1);
	  
	  	c = fdtochan(arg[0], -1, 0, 1);
	- 
	- 	if(c->name == nil)
	- 		snprint((char*)arg[1], arg[2], "<null>");
	- 	else
	- 		snprint((char*)arg[1], arg[2], "%s", c->name->s);
	+ 	snprint((char*)arg[1], arg[2], "%s", chanpath(c));
	  	cclose(c);
	  	return 0;
	  }
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/sysfile.c:918,935 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/sysfile.c:914,931
	  }
	  
	  static char*
	- cnamelast(Cname *n)
	+ pathlast(Path *p)
	  {
	  	char *s;
	  
	- 	if(n == nil)
	+ 	if(p == nil)
	  		return nil;
	- 	if(n->len == 0)
	+ 	if(p->len == 0)
	  		return nil;
	- 	s = strrchr(n->s, '/');
	+ 	s = strrchr(p->s, '/');
	  	if(s)
	  		return s+1;
	- 	return n->s;
	+ 	return p->s;
	  }
	  
	  long
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/sysfile.c:967,973 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/sysfile.c:963,969
	  		nexterror();
	  	}
	  	l = devtab[c->type]->stat(c, (uchar*)arg[1], l);
	- 	name = cnamelast(c->name);
	+ 	name = pathlast(c->path);
	  	if(name)
	  		l = dirsetname(name, strlen(name), (uchar*)arg[1], l, arg[2]);
	  
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/sysfile.c:1199,1209 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/sysfile.c:1195,1205
	  	if(c->ismtpt){
	  		/*
	  		 * Renaming mount points is disallowed to avoid surprises
	- 		 * (which should be renamed: the mount point or the mounted Chan?).
	+ 		 * (which should be renamed? the mount point or the mounted Chan?).
	  		 */
	  		dirname(d, &namelen);
	  		if(namelen)
	- 			nameerror(channame(c), Eismtpt);
	+ 			nameerror(chanpath(c), Eismtpt);
	  	}
	  	l = devtab[c->type]->wstat(c, d, nd);
	  	poperror();
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/sysfile.c:1293,1299 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/sysfile.c:1289,1295
	  	/* buf contains a new stat buf; convert to old. yuck. */
	  	if(l <= BIT16SZ)	/* buffer too small; time to face reality */
	  		error(old);
	- 	name = cnamelast(c->name);
	+ 	name = pathlast(c->path);
	  	if(name)
	  		l = dirsetname(name, strlen(name), buf, l, sizeof buf);
	  	l = convM2D(buf, l, &d, strs);
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/sysfile.c:1327,1333 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/sysfile.c:1323,1329
	  	/* buf contains a new stat buf; convert to old. yuck. */
	  	if(l <= BIT16SZ)	/* buffer too small; time to face reality */
	  		error(old);
	- 	name = cnamelast(c->name);
	+ 	name = pathlast(c->path);
	  	if(name)
	  		l = dirsetname(name, strlen(name), buf, l, sizeof buf);
	  	l = convM2D(buf, l, &d, strs);
 [rsc] --rw-rw-r-- M 57833 glenda sys 15164 Sep 13 00:36 sys/src/9/port/sysproc.c
	/n/sourcesdump/2005/0913/plan9/sys/src/9/port/sysproc.c:16,21 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/port/sysproc.c:16,24
	  long
	  sysr1(ulong*)
	  {
	+ 	extern int chandebug;
	+ 	
	+ 	chandebug = !chandebug;
	  	checkpages();
	  	return 0;
	  }
 [rsc] --rw-rw-r-- M 57833 presotto sys 9039 Sep 13 00:37 sys/src/9/ppc/main.c
	/n/sourcesdump/2005/0913/plan9/sys/src/9/ppc/main.c:160,167 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/9/ppc/main.c:160,167
	  	 * Then early kproc's will have a root and dot.
	  	 */
	  	up->slash = namec("#/", Atodir, 0, 0);
	- 	cnameclose(up->slash->name);
	- 	up->slash->name = newcname("/");
	+ 	pathclose(up->slash->path);
	+ 	up->slash->path = newpath("/");
	  	up->dot = cclone(up->slash);
	  
	  	chandevinit();

Add TypeFAT16X, correct some spacing.
 [jmk] --rw-rw-r-- M 57833 glenda sys 21983 Sep 13 10:53 sys/src/cmd/disk/prep/fdisk.c
	/n/sourcesdump/2005/0913/plan9/sys/src/cmd/disk/prep/fdisk.c:188,194 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/cmd/disk/prep/fdisk.c:188,194
	  	uchar	endh;			/* ending head */
	  	uchar	ends;			/* ending sector */
	  	uchar	endc;			/* ending cylinder */
	- 	uchar	xlba[4];			/* starting LBA from beginning of disc or ext. partition */
	+ 	uchar	xlba[4];		/* starting LBA from beginning of disc or ext. partition */
	  	uchar	xsize[4];		/* size in sectors */
	  };
	  
	/n/sourcesdump/2005/0913/plan9/sys/src/cmd/disk/prep/fdisk.c:211,220 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/cmd/disk/prep/fdisk.c:211,221
	  	TypeOS2BOOT	= 0x0A,		/* OS/2 Boot Manager */
	  	TypeFAT32	= 0x0B,		/* FAT 32 */
	  	TypeFAT32LBA	= 0x0C,		/* FAT 32 needing LBA support */
	+ 	TypeFAT16X	= 0x0E,		/* FAT 16 needing LBA support */
	  	TypeEXTHUGE	= 0x0F,		/* FAT 32 extended partition */
	  	TypeUNFORMATTED	= 0x16,		/* unformatted primary partition (OS/2 FDISK)? */
	  	TypeHPFS2	= 0x17,
	- 	TypeIBMRecovery = 0x1C,	/* really hidden fat */
	+ 	TypeIBMRecovery = 0x1C,		/* really hidden fat */
	  	TypeCPM0	= 0x52,
	  	TypeDMDDO	= 0x54,		/* Disk Manager Dynamic Disk Overlay */
	  	TypeGB		= 0x56,		/* ???? */
	/n/sourcesdump/2005/0913/plan9/sys/src/cmd/disk/prep/fdisk.c:234,240 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/cmd/disk/prep/fdisk.c:235,241
	  	TypeBSDISWAP	= 0xB8,
	  	TypeOTHER	= 0xDA,
	  	TypeCPM		= 0xDB,
	- 	TypeDellRecovery	= 0xDE,
	+ 	TypeDellRecovery= 0xDE,
	  	TypeSPEEDSTOR12	= 0xE1,
	  	TypeSPEEDSTOR16	= 0xE4,
	  	TypeLANSTEP	= 0xFE,
	/n/sourcesdump/2005/0913/plan9/sys/src/cmd/disk/prep/fdisk.c:276,281 - 
	/n/sourcesdump/2005/0914/plan9/sys/src/cmd/disk/prep/fdisk.c:277,283
	  	[TypeFAT16]		{ "FAT16", "dos" },
	  	[TypeFAT32]		{ "FAT32", "dos" },
	  	[TypeFAT32LBA]		{ "FAT32LBA", "dos" },
	+ 	[TypeFAT16X]		{ "FAT16X", "dos" },
	  	[TypeEXTHUGE]		{ "EXTHUGE", "" },
	  	[TypeIBMRecovery]	{ "IBMRECOVERY", "ibm" },
	  	[TypeEXTENDED]		{ "EXTENDED", "" },
 [sys] --rwxrwxr-x M 57833 glenda sys 103810 Sep 13 23:10 386/bin/disk/fdisk
	/sys/src/cmd/disk/prep/fdisk.c:Dfmt
	/sys/src/cmd/disk/prep/fdisk.c:addrecover
	/sys/src/cmd/disk/prep/fdisk.c:autopart
	/sys/src/cmd/disk/prep/fdisk.c:cmdactive
	/sys/src/cmd/disk/prep/fdisk.c:cmdadd
	/sys/src/cmd/disk/prep/fdisk.c:cmdext
	/sys/src/cmd/disk/prep/fdisk.c:cmdhelp
	/sys/src/cmd/disk/prep/fdisk.c:cmdokname
	/sys/src/cmd/disk/prep/fdisk.c:cmdsum
	/sys/src/cmd/disk/prep/fdisk.c:cmdtype
	/sys/src/cmd/disk/prep/fdisk.c:diskread
	/sys/src/cmd/disk/prep/fdisk.c:diskwrite
	/sys/src/cmd/disk/prep/fdisk.c:dumplist
	/sys/src/cmd/disk/prep/fdisk.c:findmbr
	/sys/src/cmd/disk/prep/fdisk.c:mkpart
	/sys/src/cmd/disk/prep/fdisk.c:plan9print
	/sys/src/cmd/disk/prep/fdisk.c:rdpart
	/sys/src/cmd/disk/prep/fdisk.c:recover
	/sys/src/cmd/disk/prep/fdisk.c:typestr0
	/sys/src/cmd/disk/prep/fdisk.c:wrpart


Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.