xref: /plan9/sys/src/9/port/chan.c (revision 70b6ec21992a2c55178a99cc7dddb19f051e140a)
1 #include	"u.h"
2 #include	"../port/lib.h"
3 #include	"mem.h"
4 #include	"dat.h"
5 #include	"fns.h"
6 #include	"../port/error.h"
7 
8 int chandebug=0;		/* toggled by sysr1 */
9 #define DBG if(chandebug)iprint
10 
11 enum
12 {
13 	PATHSLOP	= 20,
14 	PATHMSLOP	= 20,
15 };
16 
17 struct
18 {
19 	Lock;
20 	int	fid;
21 	Chan	*free;
22 	Chan	*list;
23 }chanalloc;
24 
25 typedef struct Elemlist Elemlist;
26 
27 struct Elemlist
28 {
29 	char	*aname;	/* original name */
30 	char	*name;	/* copy of name, so '/' can be overwritten */
31 	int	nelems;
32 	char	**elems;
33 	int	*off;
34 	int	mustbedir;
35 	int	nerror;
36 	int	prefix;
37 };
38 
39 #define SEP(c) ((c) == 0 || (c) == '/')
40 
41 static void
dumpmount(void)42 dumpmount(void)		/* DEBUGGING */
43 {
44 	Pgrp *pg;
45 	Mount *t;
46 	Mhead **h, **he, *f;
47 
48 	if(up == nil){
49 		print("no process for dumpmount\n");
50 		return;
51 	}
52 	pg = up->pgrp;
53 	if(pg == nil){
54 		print("no pgrp for dumpmount\n");
55 		return;
56 	}
57 	rlock(&pg->ns);
58 	if(waserror()){
59 		runlock(&pg->ns);
60 		nexterror();
61 	}
62 
63 	he = &pg->mnthash[MNTHASH];
64 	for(h = pg->mnthash; h < he; h++){
65 		for(f = *h; f; f = f->hash){
66 			print("head: %#p: %s %#llux.%lud %C %lud -> \n", f,
67 				f->from->path->s, f->from->qid.path,
68 				f->from->qid.vers, devtab[f->from->type]->dc,
69 				f->from->dev);
70 			for(t = f->mount; t; t = t->next)
71 				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);
72 		}
73 	}
74 	poperror();
75 	runlock(&pg->ns);
76 }
77 
78 char*
chanpath(Chan * c)79 chanpath(Chan *c)
80 {
81 	if(c == nil)
82 		return "<nil chan>";
83 	if(c->path == nil)
84 		return "<nil path>";
85 	if(c->path->s == nil)
86 		return "<nil path.s>";
87 	return c->path->s;
88 }
89 
90 int
isdotdot(char * p)91 isdotdot(char *p)
92 {
93 	return p[0]=='.' && p[1]=='.' && p[2]=='\0';
94 }
95 
96 long
incref(Ref * r)97 incref(Ref *r)
98 {
99 	long x;
100 
101 	lock(r);
102 	x = ++r->ref;
103 	unlock(r);
104 	return x;
105 }
106 
107 long
decref(Ref * r)108 decref(Ref *r)
109 {
110 	long x;
111 
112 	lock(r);
113 	x = --r->ref;
114 	unlock(r);
115 	if(x < 0)
116 		panic("decref pc=%#p", getcallerpc(&r));
117 
118 	return x;
119 }
120 
121 /*
122  * Rather than strncpy, which zeros the rest of the buffer, kstrcpy
123  * truncates if necessary, always zero terminates, does not zero fill,
124  * and puts ... at the end of the string if it's too long.  Usually used to
125  * save a string in up->genbuf;
126  */
127 void
kstrcpy(char * s,char * t,int ns)128 kstrcpy(char *s, char *t, int ns)
129 {
130 	int nt;
131 
132 	nt = strlen(t);
133 	if(nt+1 <= ns){
134 		memmove(s, t, nt+1);
135 		return;
136 	}
137 	/* too long */
138 	if(ns < 4){
139 		/* but very short! */
140 		strncpy(s, t, ns);
141 		return;
142 	}
143 	/* truncate with ... at character boundary (very rare case) */
144 	memmove(s, t, ns-4);
145 	ns -= 4;
146 	s[ns] = '\0';
147 	/* look for first byte of UTF-8 sequence by skipping continuation bytes */
148 	while(ns>0 && (s[--ns]&0xC0)==0x80)
149 		;
150 	strcpy(s+ns, "...");
151 }
152 
153 int
emptystr(char * s)154 emptystr(char *s)
155 {
156 	if(s == nil)
157 		return 1;
158 	if(s[0] == '\0')
159 		return 1;
160 	return 0;
161 }
162 
163 /*
164  * Atomically replace *p with copy of s
165  */
166 void
kstrdup(char ** p,char * s)167 kstrdup(char **p, char *s)
168 {
169 	int n;
170 	char *t, *prev;
171 
172 	n = strlen(s)+1;
173 	/* if it's a user, we can wait for memory; if not, something's very wrong */
174 	if(up){
175 		t = smalloc(n);
176 		setmalloctag(t, getcallerpc(&p));
177 	}else{
178 		t = malloc(n);
179 		if(t == nil)
180 			panic("kstrdup: no memory");
181 	}
182 	memmove(t, s, n);
183 	prev = *p;
184 	*p = t;
185 	free(prev);
186 }
187 
188 static int debugstart = 1;
189 
190 void
chandevreset(void)191 chandevreset(void)
192 {
193 	int i;
194 
195 	todinit();	/* avoid later reentry causing infinite recursion */
196 	debugstart = getconf("*debugstart") != nil;
197 	if(debugstart)
198 		iprint("reset:");
199 	for(i=0; devtab[i] != nil; i++) {
200 		if(debugstart)
201 			iprint(" %s", devtab[i]->name);
202 		devtab[i]->reset();
203 	}
204 	if(debugstart)
205 		iprint("\n");
206 }
207 
208 void
chandevinit(void)209 chandevinit(void)
210 {
211 	int i;
212 
213 	if(debugstart)
214 		iprint("init:");
215 	for(i=0; devtab[i] != nil; i++) {
216 		if(debugstart)
217 			iprint(" %s", devtab[i]->name);
218 		devtab[i]->init();
219 	}
220 	if(debugstart)
221 		iprint("\n");
222 }
223 
224 void
chandevshutdown(void)225 chandevshutdown(void)
226 {
227 	int i;
228 
229 	/* shutdown in reverse order */
230 	for(i=0; devtab[i] != nil; i++)
231 		;
232 	for(i--; i >= 0; i--)
233 		devtab[i]->shutdown();
234 }
235 
236 Chan*
newchan(void)237 newchan(void)
238 {
239 	Chan *c;
240 
241 	lock(&chanalloc);
242 	c = chanalloc.free;
243 	if(c != 0)
244 		chanalloc.free = c->next;
245 	unlock(&chanalloc);
246 
247 	if(c == nil){
248 		c = smalloc(sizeof(Chan));
249 		lock(&chanalloc);
250 		c->fid = ++chanalloc.fid;
251 		c->link = chanalloc.list;
252 		chanalloc.list = c;
253 		unlock(&chanalloc);
254 	}
255 
256 	/* if you get an error before associating with a dev,
257 	   close calls rootclose, a nop */
258 	c->type = 0;
259 	c->flag = 0;
260 	c->ref = 1;
261 	c->dev = 0;
262 	c->offset = 0;
263 	c->devoffset = 0;
264 	c->iounit = 0;
265 	c->umh = 0;
266 	c->uri = 0;
267 	c->dri = 0;
268 	c->aux = 0;
269 	c->mchan = 0;
270 	c->mcp = 0;
271 	c->mux = 0;
272 	memset(&c->mqid, 0, sizeof(c->mqid));
273 	c->path = 0;
274 	c->ismtpt = 0;
275 
276 	return c;
277 }
278 
279 Ref npath;
280 
281 Path*
newpath(char * s)282 newpath(char *s)
283 {
284 	int i;
285 	Path *p;
286 
287 	p = smalloc(sizeof(Path));
288 	i = strlen(s);
289 	p->len = i;
290 	p->alen = i+PATHSLOP;
291 	p->s = smalloc(p->alen);
292 	memmove(p->s, s, i+1);
293 	p->ref = 1;
294 	incref(&npath);
295 
296 	/*
297 	 * Cannot use newpath for arbitrary names because the mtpt
298 	 * array will not be populated correctly.  The names #/ and / are
299 	 * allowed, but other names with / in them draw warnings.
300 	 */
301 	if(strchr(s, '/') && strcmp(s, "#/") != 0 && strcmp(s, "/") != 0)
302 		print("newpath: %s from %#p\n", s, getcallerpc(&s));
303 
304 	p->mlen = 1;
305 	p->malen = PATHMSLOP;
306 	p->mtpt = smalloc(p->malen*sizeof p->mtpt[0]);
307 	return p;
308 }
309 
310 static Path*
copypath(Path * p)311 copypath(Path *p)
312 {
313 	int i;
314 	Path *pp;
315 
316 	pp = smalloc(sizeof(Path));
317 	pp->ref = 1;
318 	incref(&npath);
319 	DBG("copypath %s %p => %p\n", p->s, p, pp);
320 
321 	pp->len = p->len;
322 	pp->alen = p->alen;
323 	pp->s = smalloc(p->alen);
324 	memmove(pp->s, p->s, p->len+1);
325 
326 	pp->mlen = p->mlen;
327 	pp->malen = p->malen;
328 	pp->mtpt = smalloc(p->malen*sizeof pp->mtpt[0]);
329 	for(i=0; i<pp->mlen; i++){
330 		pp->mtpt[i] = p->mtpt[i];
331 		if(pp->mtpt[i])
332 			incref(pp->mtpt[i]);
333 	}
334 
335 	return pp;
336 }
337 
338 void
pathclose(Path * p)339 pathclose(Path *p)
340 {
341 	int i;
342 
343 	if(p == nil)
344 		return;
345 //XXX
346 	DBG("pathclose %p %s ref=%ld =>", p, p->s, p->ref);
347 	for(i=0; i<p->mlen; i++)
348 		DBG(" %p", p->mtpt[i]);
349 	DBG("\n");
350 
351 	if(decref(p))
352 		return;
353 	decref(&npath);
354 	free(p->s);
355 	for(i=0; i<p->mlen; i++)
356 		if(p->mtpt[i])
357 			cclose(p->mtpt[i]);
358 	free(p->mtpt);
359 	free(p);
360 }
361 
362 /*
363  * In place, rewrite name to compress multiple /, eliminate ., and process ..
364  * (Really only called to remove a trailing .. that has been added.
365  * Otherwise would need to update n->mtpt as well.)
366  */
367 static void
fixdotdotname(Path * p)368 fixdotdotname(Path *p)
369 {
370 	char *r;
371 
372 	if(p->s[0] == '#'){
373 		r = strchr(p->s, '/');
374 		if(r == nil)
375 			return;
376 		cleanname(r);
377 
378 		/*
379 		 * The correct name is #i rather than #i/,
380 		 * but the correct name of #/ is #/.
381 		 */
382 		if(strcmp(r, "/")==0 && p->s[1] != '/')
383 			*r = '\0';
384 	}else
385 		cleanname(p->s);
386 	p->len = strlen(p->s);
387 }
388 
389 static Path*
uniquepath(Path * p)390 uniquepath(Path *p)
391 {
392 	Path *new;
393 
394 	if(p->ref > 1){
395 		/* copy on write */
396 		new = copypath(p);
397 		pathclose(p);
398 		p = new;
399 	}
400 	return p;
401 }
402 
403 static Path*
addelem(Path * p,char * s,Chan * from)404 addelem(Path *p, char *s, Chan *from)
405 {
406 	char *t;
407 	int a, i;
408 	Chan *c, **tt;
409 
410 	if(s[0]=='.' && s[1]=='\0')
411 		return p;
412 
413 	p = uniquepath(p);
414 
415 	i = strlen(s);
416 	if(p->len+1+i+1 > p->alen){
417 		a = p->len+1+i+1 + PATHSLOP;
418 		t = smalloc(a);
419 		memmove(t, p->s, p->len+1);
420 		free(p->s);
421 		p->s = t;
422 		p->alen = a;
423 	}
424 	/* don't insert extra slash if one is present */
425 	if(p->len>0 && p->s[p->len-1]!='/' && s[0]!='/')
426 		p->s[p->len++] = '/';
427 	memmove(p->s+p->len, s, i+1);
428 	p->len += i;
429 	if(isdotdot(s)){
430 		fixdotdotname(p);
431 		DBG("addelem %s .. => rm %p\n", p->s, p->mtpt[p->mlen-1]);
432 		if(p->mlen>1 && (c = p->mtpt[--p->mlen])){
433 			p->mtpt[p->mlen] = nil;
434 			cclose(c);
435 		}
436 	}else{
437 		if(p->mlen >= p->malen){
438 			p->malen = p->mlen+1+PATHMSLOP;
439 			tt = smalloc(p->malen*sizeof tt[0]);
440 			memmove(tt, p->mtpt, p->mlen*sizeof tt[0]);
441 			free(p->mtpt);
442 			p->mtpt = tt;
443 		}
444 		DBG("addelem %s %s => add %p\n", p->s, s, from);
445 		p->mtpt[p->mlen++] = from;
446 		if(from)
447 			incref(from);
448 	}
449 	return p;
450 }
451 
452 void
chanfree(Chan * c)453 chanfree(Chan *c)
454 {
455 	c->flag = CFREE;
456 
457 	if(c->dirrock != nil){
458 		free(c->dirrock);
459 		c->dirrock = 0;
460 		c->nrock = 0;
461 		c->mrock = 0;
462 	}
463 	if(c->umh != nil){
464 		putmhead(c->umh);
465 		c->umh = nil;
466 	}
467 	if(c->umc != nil){
468 		cclose(c->umc);
469 		c->umc = nil;
470 	}
471 	if(c->mux != nil){
472 		muxclose(c->mux);
473 		c->mux = nil;
474 	}
475 	if(c->mchan != nil){
476 		cclose(c->mchan);
477 		c->mchan = nil;
478 	}
479 
480 	pathclose(c->path);
481 	c->path = nil;
482 
483 	lock(&chanalloc);
484 	c->next = chanalloc.free;
485 	chanalloc.free = c;
486 	unlock(&chanalloc);
487 }
488 
489 void
cclose(Chan * c)490 cclose(Chan *c)
491 {
492 	if(c->flag&CFREE)
493 		panic("cclose %#p", getcallerpc(&c));
494 
495 	DBG("cclose %p name=%s ref=%ld\n", c, c->path->s, c->ref);
496 	if(decref(c))
497 		return;
498 
499 	if(!waserror()){
500 		devtab[c->type]->close(c);
501 		poperror();
502 	}
503 	chanfree(c);
504 }
505 
506 /*
507  * Queue a chan to be closed by one of the clunk procs.
508  */
509 struct {
510 	Chan *head;
511 	Chan *tail;
512 	int nqueued;
513 	int nclosed;
514 	Lock l;
515 	QLock q;
516 	Rendez r;
517 } clunkq;
518 void closeproc(void*);
519 
520 void
ccloseq(Chan * c)521 ccloseq(Chan *c)
522 {
523 	if(c->flag&CFREE)
524 		panic("cclose %#p", getcallerpc(&c));
525 
526 	DBG("ccloseq %p name=%s ref=%ld\n", c, c->path->s, c->ref);
527 
528 	if(decref(c))
529 		return;
530 
531 	lock(&clunkq.l);
532 	clunkq.nqueued++;
533 	c->next = nil;
534 	if(clunkq.head)
535 		clunkq.tail->next = c;
536 	else
537 		clunkq.head = c;
538 	clunkq.tail = c;
539 	unlock(&clunkq.l);
540 
541 	if(!wakeup(&clunkq.r))
542 		kproc("closeproc", closeproc, nil);
543 }
544 
545 static int
clunkwork(void *)546 clunkwork(void*)
547 {
548 	return clunkq.head != nil;
549 }
550 
551 void
closeproc(void *)552 closeproc(void*)
553 {
554 	Chan *c;
555 
556 	for(;;){
557 		qlock(&clunkq.q);
558 		if(clunkq.head == nil){
559 			if(!waserror()){
560 				tsleep(&clunkq.r, clunkwork, nil, 5000);
561 				poperror();
562 			}
563 			if(clunkq.head == nil){
564 				qunlock(&clunkq.q);
565 				pexit("no work", 1);
566 			}
567 		}
568 		lock(&clunkq.l);
569 		c = clunkq.head;
570 		clunkq.head = c->next;
571 		clunkq.nclosed++;
572 		unlock(&clunkq.l);
573 		qunlock(&clunkq.q);
574 		if(!waserror()){
575 			devtab[c->type]->close(c);
576 			poperror();
577 		}
578 		chanfree(c);
579 	}
580 }
581 
582 /*
583  * Make sure we have the only copy of c.  (Copy on write.)
584  */
585 Chan*
cunique(Chan * c)586 cunique(Chan *c)
587 {
588 	Chan *nc;
589 
590 	if(c->ref != 1){
591 		nc = cclone(c);
592 		cclose(c);
593 		c = nc;
594 	}
595 
596 	return c;
597 }
598 
599 int
eqqid(Qid a,Qid b)600 eqqid(Qid a, Qid b)
601 {
602 	return a.path==b.path && a.vers==b.vers;
603 }
604 
605 int
eqchan(Chan * a,Chan * b,int skipvers)606 eqchan(Chan *a, Chan *b, int skipvers)
607 {
608 	if(a->qid.path != b->qid.path)
609 		return 0;
610 	if(!skipvers && a->qid.vers!=b->qid.vers)
611 		return 0;
612 	if(a->type != b->type)
613 		return 0;
614 	if(a->dev != b->dev)
615 		return 0;
616 	return 1;
617 }
618 
619 int
eqchantdqid(Chan * a,int type,int dev,Qid qid,int skipvers)620 eqchantdqid(Chan *a, int type, int dev, Qid qid, int skipvers)
621 {
622 	if(a->qid.path != qid.path)
623 		return 0;
624 	if(!skipvers && a->qid.vers!=qid.vers)
625 		return 0;
626 	if(a->type != type)
627 		return 0;
628 	if(a->dev != dev)
629 		return 0;
630 	return 1;
631 }
632 
633 Mhead*
newmhead(Chan * from)634 newmhead(Chan *from)
635 {
636 	Mhead *mh;
637 
638 	mh = smalloc(sizeof(Mhead));
639 	mh->ref = 1;
640 	mh->from = from;
641 	incref(from);
642 	return mh;
643 }
644 
645 int
cmount(Chan ** newp,Chan * old,int flag,char * spec)646 cmount(Chan **newp, Chan *old, int flag, char *spec)
647 {
648 	int order, flg;
649 	Chan *new;
650 	Mhead *m, **l, *mh;
651 	Mount *nm, *f, *um, **h;
652 	Pgrp *pg;
653 
654 	if(QTDIR & (old->qid.type^(*newp)->qid.type))
655 		error(Emount);
656 
657 	if(old->umh)
658 		print("cmount: unexpected umh, caller %#p\n", getcallerpc(&newp));
659 
660 	order = flag&MORDER;
661 
662 	if((old->qid.type&QTDIR)==0 && order != MREPL)
663 		error(Emount);
664 
665 	new = *newp;
666 	mh = new->umh;
667 
668 	/*
669 	 * Not allowed to bind when the old directory is itself a union.
670 	 * (Maybe it should be allowed, but I don't see what the semantics
671 	 * would be.)
672 	 *
673 	 * We need to check mh->mount->next to tell unions apart from
674 	 * simple mount points, so that things like
675 	 *	mount -c fd /root
676 	 *	bind -c /root /
677 	 * work.
678 	 *
679 	 * The check of mount->mflag allows things like
680 	 *	mount fd /root
681 	 *	bind -c /root /
682 	 *
683 	 * This is far more complicated than it should be, but I don't
684 	 * see an easier way at the moment.
685 	 */
686 	if((flag&MCREATE) && mh && mh->mount
687 	&& (mh->mount->next || !(mh->mount->mflag&MCREATE)))
688 		error(Emount);
689 
690 	pg = up->pgrp;
691 	wlock(&pg->ns);
692 
693 	l = &MOUNTH(pg, old->qid);
694 	for(m = *l; m; m = m->hash){
695 		if(eqchan(m->from, old, 1))
696 			break;
697 		l = &m->hash;
698 	}
699 
700 	if(m == nil){
701 		/*
702 		 *  nothing mounted here yet.  create a mount
703 		 *  head and add to the hash table.
704 		 */
705 		m = newmhead(old);
706 		*l = m;
707 
708 		/*
709 		 *  if this is a union mount, add the old
710 		 *  node to the mount chain.
711 		 */
712 		if(order != MREPL)
713 			m->mount = newmount(m, old, 0, 0);
714 	}
715 	wlock(&m->lock);
716 	if(waserror()){
717 		wunlock(&m->lock);
718 		nexterror();
719 	}
720 	wunlock(&pg->ns);
721 
722 	nm = newmount(m, new, flag, spec);
723 	if(mh != nil && mh->mount != nil){
724 		/*
725 		 *  copy a union when binding it onto a directory
726 		 */
727 		flg = order;
728 		if(order == MREPL)
729 			flg = MAFTER;
730 		h = &nm->next;
731 		um = mh->mount;
732 		for(um = um->next; um; um = um->next){
733 			f = newmount(m, um->to, flg, um->spec);
734 			*h = f;
735 			h = &f->next;
736 		}
737 	}
738 
739 	if(m->mount && order == MREPL){
740 		mountfree(m->mount);
741 		m->mount = 0;
742 	}
743 
744 	if(flag & MCREATE)
745 		nm->mflag |= MCREATE;
746 
747 	if(m->mount && order == MAFTER){
748 		for(f = m->mount; f->next; f = f->next)
749 			;
750 		f->next = nm;
751 	}else{
752 		for(f = nm; f->next; f = f->next)
753 			;
754 		f->next = m->mount;
755 		m->mount = nm;
756 	}
757 
758 	wunlock(&m->lock);
759 	poperror();
760 	return nm->mountid;
761 }
762 
763 void
cunmount(Chan * mnt,Chan * mounted)764 cunmount(Chan *mnt, Chan *mounted)
765 {
766 	Pgrp *pg;
767 	Mhead *m, **l;
768 	Mount *f, **p;
769 
770 	if(mnt->umh)	/* should not happen */
771 		print("cunmount newp extra umh %p has %p\n", mnt, mnt->umh);
772 
773 	/*
774 	 * It _can_ happen that mounted->umh is non-nil,
775 	 * because mounted is the result of namec(Aopen)
776 	 * (see sysfile.c:/^sysunmount).
777 	 * If we open a union directory, it will have a umh.
778 	 * Although surprising, this is okay, since the
779 	 * cclose will take care of freeing the umh.
780 	 */
781 
782 	pg = up->pgrp;
783 	wlock(&pg->ns);
784 
785 	l = &MOUNTH(pg, mnt->qid);
786 	for(m = *l; m; m = m->hash){
787 		if(eqchan(m->from, mnt, 1))
788 			break;
789 		l = &m->hash;
790 	}
791 
792 	if(m == 0){
793 		wunlock(&pg->ns);
794 		error(Eunmount);
795 	}
796 
797 	wlock(&m->lock);
798 	if(mounted == 0){
799 		*l = m->hash;
800 		wunlock(&pg->ns);
801 		mountfree(m->mount);
802 		m->mount = nil;
803 		cclose(m->from);
804 		wunlock(&m->lock);
805 		putmhead(m);
806 		return;
807 	}
808 
809 	p = &m->mount;
810 	for(f = *p; f; f = f->next){
811 		/* BUG: Needs to be 2 pass */
812 		if(eqchan(f->to, mounted, 1) ||
813 		  (f->to->mchan && eqchan(f->to->mchan, mounted, 1))){
814 			*p = f->next;
815 			f->next = 0;
816 			mountfree(f);
817 			if(m->mount == nil){
818 				*l = m->hash;
819 				cclose(m->from);
820 				wunlock(&m->lock);
821 				wunlock(&pg->ns);
822 				putmhead(m);
823 				return;
824 			}
825 			wunlock(&m->lock);
826 			wunlock(&pg->ns);
827 			return;
828 		}
829 		p = &f->next;
830 	}
831 	wunlock(&m->lock);
832 	wunlock(&pg->ns);
833 	error(Eunion);
834 }
835 
836 Chan*
cclone(Chan * c)837 cclone(Chan *c)
838 {
839 	Chan *nc;
840 	Walkqid *wq;
841 
842 	wq = devtab[c->type]->walk(c, nil, nil, 0);
843 	if(wq == nil)
844 		error("clone failed");
845 	nc = wq->clone;
846 	free(wq);
847 	nc->path = c->path;
848 	if(c->path)
849 		incref(c->path);
850 	return nc;
851 }
852 
853 /* also used by sysfile.c:/^mountfix */
854 int
findmount(Chan ** cp,Mhead ** mp,int type,int dev,Qid qid)855 findmount(Chan **cp, Mhead **mp, int type, int dev, Qid qid)
856 {
857 	Pgrp *pg;
858 	Mhead *m;
859 
860 	pg = up->pgrp;
861 	rlock(&pg->ns);
862 	for(m = MOUNTH(pg, qid); m; m = m->hash){
863 		rlock(&m->lock);
864 		if(m->from == nil){
865 			print("m %p m->from 0\n", m);
866 			runlock(&m->lock);
867 			continue;
868 		}
869 		if(eqchantdqid(m->from, type, dev, qid, 1)){
870 			runlock(&pg->ns);
871 			if(mp != nil){
872 				incref(m);
873 				if(*mp != nil)
874 					putmhead(*mp);
875 				*mp = m;
876 			}
877 			if(*cp != nil)
878 				cclose(*cp);
879 			incref(m->mount->to);
880 			*cp = m->mount->to;
881 			runlock(&m->lock);
882 			return 1;
883 		}
884 		runlock(&m->lock);
885 	}
886 
887 	runlock(&pg->ns);
888 	return 0;
889 }
890 
891 /*
892  * Calls findmount but also updates path.
893  */
894 static int
domount(Chan ** cp,Mhead ** mp,Path ** path)895 domount(Chan **cp, Mhead **mp, Path **path)
896 {
897 	Chan **lc;
898 	Path *p;
899 
900 	if(findmount(cp, mp, (*cp)->type, (*cp)->dev, (*cp)->qid) == 0)
901 		return 0;
902 
903 	if(path){
904 		p = *path;
905 		p = uniquepath(p);
906 		if(p->mlen <= 0)
907 			print("domount: path %s has mlen==%d\n", p->s, p->mlen);
908 		else{
909 			lc = &p->mtpt[p->mlen-1];
910 DBG("domount %p %s => add %p (was %p)\n", p, p->s, (*mp)->from, p->mtpt[p->mlen-1]);
911 			incref((*mp)->from);
912 			if(*lc)
913 				cclose(*lc);
914 			*lc = (*mp)->from;
915 		}
916 		*path = p;
917 	}
918 	return 1;
919 }
920 
921 /*
922  * If c is the right-hand-side of a mount point, returns the left hand side.
923  * Changes name to reflect the fact that we've uncrossed the mountpoint,
924  * so name had better be ours to change!
925  */
926 static Chan*
undomount(Chan * c,Path * path)927 undomount(Chan *c, Path *path)
928 {
929 	Chan *nc;
930 
931 	if(path->ref != 1 || path->mlen == 0)
932 		print("undomount: path %s ref %ld mlen %d caller %#p\n",
933 			path->s, path->ref, path->mlen, getcallerpc(&c));
934 
935 	if(path->mlen>0 && (nc=path->mtpt[path->mlen-1]) != nil){
936 DBG("undomount %p %s => remove %p\n", path, path->s, nc);
937 		cclose(c);
938 		path->mtpt[path->mlen-1] = nil;
939 		c = nc;
940 	}
941 	return c;
942 }
943 
944 /*
945  * Call dev walk but catch errors.
946  */
947 static Walkqid*
ewalk(Chan * c,Chan * nc,char ** name,int nname)948 ewalk(Chan *c, Chan *nc, char **name, int nname)
949 {
950 	Walkqid *wq;
951 
952 	if(waserror())
953 		return nil;
954 	wq = devtab[c->type]->walk(c, nc, name, nname);
955 	poperror();
956 	return wq;
957 }
958 
959 /*
960  * Either walks all the way or not at all.  No partial results in *cp.
961  * *nerror is the number of names to display in an error message.
962  */
963 static char Edoesnotexist[] = "does not exist";
964 int
walk(Chan ** cp,char ** names,int nnames,int nomount,int * nerror)965 walk(Chan **cp, char **names, int nnames, int nomount, int *nerror)
966 {
967 	int dev, didmount, dotdot, i, n, nhave, ntry, type;
968 	Chan *c, *nc, *mtpt;
969 	Path *path;
970 	Mhead *mh, *nmh;
971 	Mount *f;
972 	Walkqid *wq;
973 
974 	c = *cp;
975 	incref(c);
976 	path = c->path;
977 	incref(path);
978 	mh = nil;
979 
980 	/*
981 	 * While we haven't gotten all the way down the path:
982 	 *    1. step through a mount point, if any
983 	 *    2. send a walk request for initial dotdot or initial prefix without dotdot
984 	 *    3. move to the first mountpoint along the way.
985 	 *    4. repeat.
986 	 *
987 	 * Each time through the loop:
988 	 *
989 	 *	If didmount==0, c is on the undomount side of the mount point.
990 	 *	If didmount==1, c is on the domount side of the mount point.
991 	 * 	Either way, c's full path is path.
992 	 */
993 	didmount = 0;
994 	for(nhave=0; nhave<nnames; nhave+=n){
995 		if((c->qid.type&QTDIR)==0){
996 			if(nerror)
997 				*nerror = nhave;
998 			pathclose(path);
999 			cclose(c);
1000 			strcpy(up->errstr, Enotdir);
1001 			if(mh != nil)
1002 				putmhead(mh);
1003 			return -1;
1004 		}
1005 		ntry = nnames - nhave;
1006 		if(ntry > MAXWELEM)
1007 			ntry = MAXWELEM;
1008 		dotdot = 0;
1009 		for(i=0; i<ntry; i++){
1010 			if(isdotdot(names[nhave+i])){
1011 				if(i==0){
1012 					dotdot = 1;
1013 					ntry = 1;
1014 				}else
1015 					ntry = i;
1016 				break;
1017 			}
1018 		}
1019 
1020 		if(!dotdot && !nomount && !didmount)
1021 			domount(&c, &mh, &path);
1022 
1023 		type = c->type;
1024 		dev = c->dev;
1025 
1026 		if((wq = ewalk(c, nil, names+nhave, ntry)) == nil){
1027 			/* try a union mount, if any */
1028 			if(mh && !nomount){
1029 				/*
1030 				 * mh->mount->to == c, so start at mh->mount->next
1031 				 */
1032 				rlock(&mh->lock);
1033 				f = mh->mount;
1034 				for(f = (f? f->next: f); f; f = f->next)
1035 					if((wq = ewalk(f->to, nil, names+nhave, ntry)) != nil)
1036 						break;
1037 				runlock(&mh->lock);
1038 				if(f != nil){
1039 					type = f->to->type;
1040 					dev = f->to->dev;
1041 				}
1042 			}
1043 			if(wq == nil){
1044 				cclose(c);
1045 				pathclose(path);
1046 				if(nerror)
1047 					*nerror = nhave+1;
1048 				if(mh != nil)
1049 					putmhead(mh);
1050 				return -1;
1051 			}
1052 		}
1053 
1054 		didmount = 0;
1055 		if(dotdot){
1056 			assert(wq->nqid == 1);
1057 			assert(wq->clone != nil);
1058 
1059 			path = addelem(path, "..", nil);
1060 			nc = undomount(wq->clone, path);
1061 			nmh = nil;
1062 			n = 1;
1063 		}else{
1064 			nc = nil;
1065 			nmh = nil;
1066 			if(!nomount){
1067 				for(i=0; i<wq->nqid && i<ntry-1; i++){
1068 					if(findmount(&nc, &nmh, type, dev, wq->qid[i])){
1069 						didmount = 1;
1070 						break;
1071 					}
1072 				}
1073 			}
1074 			if(nc == nil){	/* no mount points along path */
1075 				if(wq->clone == nil){
1076 					cclose(c);
1077 					pathclose(path);
1078 					if(wq->nqid==0 || (wq->qid[wq->nqid-1].type&QTDIR)){
1079 						if(nerror)
1080 							*nerror = nhave+wq->nqid+1;
1081 						strcpy(up->errstr, Edoesnotexist);
1082 					}else{
1083 						if(nerror)
1084 							*nerror = nhave+wq->nqid;
1085 						strcpy(up->errstr, Enotdir);
1086 					}
1087 					free(wq);
1088 					if(mh != nil)
1089 						putmhead(mh);
1090 					return -1;
1091 				}
1092 				n = wq->nqid;
1093 				nc = wq->clone;
1094 			}else{		/* stopped early, at a mount point */
1095 				didmount = 1;
1096 				if(wq->clone != nil){
1097 					cclose(wq->clone);
1098 					wq->clone = nil;
1099 				}
1100 				n = i+1;
1101 			}
1102 			for(i=0; i<n; i++){
1103 				mtpt = nil;
1104 				if(i==n-1 && nmh)
1105 					mtpt = nmh->from;
1106 				path = addelem(path, names[nhave+i], mtpt);
1107 			}
1108 		}
1109 		cclose(c);
1110 		c = nc;
1111 		putmhead(mh);
1112 		mh = nmh;
1113 		free(wq);
1114 	}
1115 
1116 	putmhead(mh);
1117 
1118 	c = cunique(c);
1119 
1120 	if(c->umh != nil){	//BUG
1121 		print("walk umh\n");
1122 		putmhead(c->umh);
1123 		c->umh = nil;
1124 	}
1125 
1126 	pathclose(c->path);
1127 	c->path = path;
1128 
1129 	cclose(*cp);
1130 	*cp = c;
1131 	if(nerror)
1132 		*nerror = nhave;
1133 	return 0;
1134 }
1135 
1136 /*
1137  * c is a mounted non-creatable directory.  find a creatable one.
1138  */
1139 Chan*
createdir(Chan * c,Mhead * m)1140 createdir(Chan *c, Mhead *m)
1141 {
1142 	Chan *nc;
1143 	Mount *f;
1144 
1145 	rlock(&m->lock);
1146 	if(waserror()){
1147 		runlock(&m->lock);
1148 		nexterror();
1149 	}
1150 	for(f = m->mount; f; f = f->next){
1151 		if(f->mflag&MCREATE){
1152 			nc = cclone(f->to);
1153 			runlock(&m->lock);
1154 			poperror();
1155 			cclose(c);
1156 			return nc;
1157 		}
1158 	}
1159 	error(Enocreate);
1160 	return 0;
1161 }
1162 
1163 void
saveregisters(void)1164 saveregisters(void)
1165 {
1166 }
1167 
1168 static void
growparse(Elemlist * e)1169 growparse(Elemlist *e)
1170 {
1171 	char **new;
1172 	int *inew;
1173 	enum { Delta = 8 };
1174 
1175 	if(e->nelems % Delta == 0){
1176 		new = smalloc((e->nelems+Delta) * sizeof(char*));
1177 		memmove(new, e->elems, e->nelems*sizeof(char*));
1178 		free(e->elems);
1179 		e->elems = new;
1180 		inew = smalloc((e->nelems+Delta+1) * sizeof(int));
1181 		memmove(inew, e->off, (e->nelems+1)*sizeof(int));
1182 		free(e->off);
1183 		e->off = inew;
1184 	}
1185 }
1186 
1187 /*
1188  * The name is known to be valid.
1189  * Copy the name so slashes can be overwritten.
1190  * An empty string will set nelem=0.
1191  * A path ending in / or /. or /.//./ etc. will have
1192  * e.mustbedir = 1, so that we correctly
1193  * reject, e.g., "/adm/users/." when /adm/users is a file
1194  * rather than a directory.
1195  */
1196 static void
parsename(char * aname,Elemlist * e)1197 parsename(char *aname, Elemlist *e)
1198 {
1199 	char *name, *slash;
1200 
1201 	kstrdup(&e->name, aname);
1202 	name = e->name;
1203 	e->nelems = 0;
1204 	e->elems = nil;
1205 	e->off = smalloc(sizeof(int));
1206 	e->off[0] = skipslash(name) - name;
1207 	for(;;){
1208 		name = skipslash(name);
1209 		if(*name == '\0'){
1210 			e->off[e->nelems] = name+strlen(name) - e->name;
1211 			e->mustbedir = 1;
1212 			break;
1213 		}
1214 		growparse(e);
1215 		e->elems[e->nelems++] = name;
1216 		slash = utfrune(name, '/');
1217 		if(slash == nil){
1218 			e->off[e->nelems] = name+strlen(name) - e->name;
1219 			e->mustbedir = 0;
1220 			break;
1221 		}
1222 		e->off[e->nelems] = slash - e->name;
1223 		*slash++ = '\0';
1224 		name = slash;
1225 	}
1226 
1227 	if(0 && chandebug){
1228 		int i;
1229 
1230 		print("parsename %s:", e->name);
1231 		for(i=0; i<=e->nelems; i++)
1232 			print(" %d", e->off[i]);
1233 		print("\n");
1234 	}
1235 }
1236 
1237 void*
memrchr(void * va,int c,long n)1238 memrchr(void *va, int c, long n)
1239 {
1240 	uchar *a, *e;
1241 
1242 	a = va;
1243 	for(e=a+n-1; e>a; e--)
1244 		if(*e == c)
1245 			return e;
1246 	return nil;
1247 }
1248 
1249 void
namelenerror(char * aname,int len,char * err)1250 namelenerror(char *aname, int len, char *err)
1251 {
1252 	char *ename, *name, *next;
1253 	int i, errlen;
1254 
1255 	/*
1256 	 * If the name is short enough, just use the whole thing.
1257 	 */
1258 	errlen = strlen(err);
1259 	if(len < ERRMAX/3 || len+errlen < 2*ERRMAX/3)
1260 		snprint(up->genbuf, sizeof up->genbuf, "%.*s",
1261 			utfnlen(aname, len), aname);
1262 	else{
1263 		/*
1264 		 * Print a suffix of the name, but try to get a little info.
1265 		 */
1266 		ename = aname+len;
1267 		next = ename;
1268 		do{
1269 			name = next;
1270 			next = memrchr(aname, '/', name-aname);
1271 			if(next == nil)
1272 				next = aname;
1273 			len = ename-next;
1274 		}while(len < ERRMAX/3 || len + errlen < 2*ERRMAX/3);
1275 
1276 		/*
1277 		 * If the name is ridiculously long, chop it.
1278 		 */
1279 		if(name == ename){
1280 			name = ename-ERRMAX/4;
1281 			if(name <= aname)
1282 				panic("bad math in namelenerror");
1283 			/* walk out of current UTF sequence */
1284 			for(i=0; (*name&0xC0)==0x80 && i<UTFmax; i++)
1285 				name++;
1286 		}
1287 		snprint(up->genbuf, sizeof up->genbuf, "...%.*s",
1288 			utfnlen(name, ename-name), name);
1289 	}
1290 	snprint(up->errstr, ERRMAX, "%#q %s", up->genbuf, err);
1291 	nexterror();
1292 }
1293 
1294 void
nameerror(char * name,char * err)1295 nameerror(char *name, char *err)
1296 {
1297 	namelenerror(name, strlen(name), err);
1298 }
1299 
1300 /*
1301  * Turn a name into a channel.
1302  * &name[0] is known to be a valid address.  It may be a kernel address.
1303  *
1304  * Opening with amode Aopen, Acreate, Aremove, or Aaccess guarantees
1305  * that the result will be the only reference to that particular fid.
1306  * This is necessary since we might pass the result to
1307  * devtab[]->remove().
1308  *
1309  * Opening Atodir or Amount does not guarantee this.
1310  *
1311  * Under certain circumstances, opening Aaccess will cause
1312  * an unnecessary clone in order to get a cunique Chan so it
1313  * can attach the correct name.  Sysstat and sys_stat need the
1314  * correct name so they can rewrite the stat info.
1315  */
1316 Chan*
namec(char * aname,int amode,int omode,ulong perm)1317 namec(char *aname, int amode, int omode, ulong perm)
1318 {
1319 	int len, n, t, nomount;
1320 	Chan *c, *cnew;
1321 	Path *path;
1322 	Elemlist e;
1323 	Rune r;
1324 	Mhead *m;
1325 	char *createerr, tmperrbuf[ERRMAX];
1326 	char *name;
1327 
1328 	if(aname[0] == '\0')
1329 		error("empty file name");
1330 	aname = validnamedup(aname, 1);
1331 	if(waserror()){
1332 		free(aname);
1333 		nexterror();
1334 	}
1335 	DBG("namec %s %d %d\n", aname, amode, omode);
1336 	name = aname;
1337 
1338 	/*
1339 	 * Find the starting off point (the current slash, the root of
1340 	 * a device tree, or the current dot) as well as the name to
1341 	 * evaluate starting there.
1342 	 */
1343 	nomount = 0;
1344 	switch(name[0]){
1345 	case '/':
1346 		c = up->slash;
1347 		incref(c);
1348 		break;
1349 
1350 	case '#':
1351 		nomount = 1;
1352 		up->genbuf[0] = '\0';
1353 		n = 0;
1354 		while(*name != '\0' && (*name != '/' || n < 2)){
1355 			if(n >= sizeof(up->genbuf)-1)
1356 				error(Efilename);
1357 			up->genbuf[n++] = *name++;
1358 		}
1359 		up->genbuf[n] = '\0';
1360 		/*
1361 		 *  noattach is sandboxing.
1362 		 *
1363 		 *  the OK exceptions are:
1364 		 *	|  it only gives access to pipes you create
1365 		 *	d  this process's file descriptors
1366 		 *	e  this process's environment
1367 		 *  the iffy exceptions are:
1368 		 *	c  time and pid, but also cons and consctl
1369 		 *	p  control of your own processes (and unfortunately
1370 		 *	   any others left unprotected)
1371 		 */
1372 		n = chartorune(&r, up->genbuf+1)+1;
1373 		/* actually / is caught by parsing earlier */
1374 		if(utfrune("M", r))
1375 			error(Enoattach);
1376 		if(up->pgrp->noattach && utfrune("|decp", r)==nil)
1377 			error(Enoattach);
1378 		t = devno(r, 1);
1379 		if(t == -1)
1380 			error(Ebadsharp);
1381 		if(debugstart && !devtab[t]->attached)
1382 			print("#%C...", devtab[t]->dc);
1383 		c = devtab[t]->attach(up->genbuf+n);
1384 		if(debugstart && c != nil)
1385 			devtab[t]->attached = 1;
1386 		break;
1387 
1388 	default:
1389 		c = up->dot;
1390 		incref(c);
1391 		break;
1392 	}
1393 
1394 	e.aname = aname;
1395 	e.prefix = name - aname;
1396 	e.name = nil;
1397 	e.elems = nil;
1398 	e.off = nil;
1399 	e.nelems = 0;
1400 	e.nerror = 0;
1401 	if(waserror()){
1402 		cclose(c);
1403 		free(e.name);
1404 		free(e.elems);
1405 		/*
1406 		 * Prepare nice error, showing first e.nerror elements of name.
1407 		 */
1408 		if(e.nerror == 0)
1409 			nexterror();
1410 		strcpy(tmperrbuf, up->errstr);
1411 		if(e.off[e.nerror]==0)
1412 			print("nerror=%d but off=%d\n",
1413 				e.nerror, e.off[e.nerror]);
1414 		if(0 && chandebug)
1415 			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]);
1416 		len = e.prefix+e.off[e.nerror];
1417 		free(e.off);
1418 		namelenerror(aname, len, tmperrbuf);
1419 	}
1420 
1421 	/*
1422 	 * Build a list of elements in the name.
1423 	 */
1424 	parsename(name, &e);
1425 
1426 	/*
1427 	 * On create, ....
1428 	 */
1429 	if(amode == Acreate){
1430 		/* perm must have DMDIR if last element is / or /. */
1431 		if(e.mustbedir && !(perm&DMDIR)){
1432 			e.nerror = e.nelems;
1433 			error("create without DMDIR");
1434 		}
1435 
1436 		/* don't try to walk the last path element just yet. */
1437 		if(e.nelems == 0)
1438 			error(Eexist);
1439 		e.nelems--;
1440 	}
1441 
1442 	if(walk(&c, e.elems, e.nelems, nomount, &e.nerror) < 0){
1443 		if(e.nerror < 0 || e.nerror > e.nelems){
1444 			print("namec %s walk error nerror=%d\n", aname, e.nerror);
1445 			e.nerror = 0;
1446 		}
1447 		nexterror();
1448 	}
1449 
1450 	if(e.mustbedir && !(c->qid.type&QTDIR))
1451 		error("not a directory");
1452 
1453 	if(amode == Aopen && (omode&3) == OEXEC && (c->qid.type&QTDIR))
1454 		error("cannot exec directory");
1455 
1456 	switch(amode){
1457 	case Abind:
1458 		/* no need to maintain path - cannot dotdot an Abind */
1459 		m = nil;
1460 		if(!nomount)
1461 			domount(&c, &m, nil);
1462 		if(c->umh != nil)
1463 			putmhead(c->umh);
1464 		c->umh = m;
1465 		break;
1466 
1467 	case Aaccess:
1468 	case Aremove:
1469 	case Aopen:
1470 	Open:
1471 		/* save&update the name; domount might change c */
1472 		path = c->path;
1473 		incref(path);
1474 		m = nil;
1475 		if(!nomount)
1476 			domount(&c, &m, &path);
1477 
1478 		/* our own copy to open or remove */
1479 		c = cunique(c);
1480 
1481 		/* now it's our copy anyway, we can put the name back */
1482 		pathclose(c->path);
1483 		c->path = path;
1484 
1485 		/* record whether c is on a mount point */
1486 		c->ismtpt = m!=nil;
1487 
1488 		switch(amode){
1489 		case Aaccess:
1490 		case Aremove:
1491 			putmhead(m);
1492 			break;
1493 
1494 		case Aopen:
1495 		case Acreate:
1496 if(c->umh != nil){
1497 	print("cunique umh Open\n");
1498 	putmhead(c->umh);
1499 	c->umh = nil;
1500 }
1501 			/* only save the mount head if it's a multiple element union */
1502 			if(m && m->mount && m->mount->next)
1503 				c->umh = m;
1504 			else
1505 				putmhead(m);
1506 
1507 			/* save registers else error() in open has wrong value of c saved */
1508 			saveregisters();
1509 
1510 			if(omode == OEXEC)
1511 				c->flag &= ~CCACHE;
1512 
1513 			c = devtab[c->type]->open(c, omode&~OCEXEC);
1514 
1515 			if(omode & OCEXEC)
1516 				c->flag |= CCEXEC;
1517 			if(omode & ORCLOSE)
1518 				c->flag |= CRCLOSE;
1519 			break;
1520 		}
1521 		break;
1522 
1523 	case Atodir:
1524 		/*
1525 		 * Directories (e.g. for cd) are left before the mount point,
1526 		 * so one may mount on / or . and see the effect.
1527 		 */
1528 		if(!(c->qid.type & QTDIR))
1529 			error(Enotdir);
1530 		break;
1531 
1532 	case Amount:
1533 		/*
1534 		 * When mounting on an already mounted upon directory,
1535 		 * one wants subsequent mounts to be attached to the
1536 		 * original directory, not the replacement.  Don't domount.
1537 		 */
1538 		break;
1539 
1540 	case Acreate:
1541 		/*
1542 		 * We've already walked all but the last element.
1543 		 * If the last exists, try to open it OTRUNC.
1544 		 * If omode&OEXCL is set, just give up.
1545 		 */
1546 		e.nelems++;
1547 		e.nerror++;
1548 		if(walk(&c, e.elems+e.nelems-1, 1, nomount, nil) == 0){
1549 			if(omode&OEXCL)
1550 				error(Eexist);
1551 			omode |= OTRUNC;
1552 			goto Open;
1553 		}
1554 
1555 		/*
1556 		 * The semantics of the create(2) system call are that if the
1557 		 * file exists and can be written, it is to be opened with truncation.
1558 		 * On the other hand, the create(5) message fails if the file exists.
1559 		 * If we get two create(2) calls happening simultaneously,
1560 		 * they might both get here and send create(5) messages, but only
1561 		 * one of the messages will succeed.  To provide the expected create(2)
1562 		 * semantics, the call with the failed message needs to try the above
1563 		 * walk again, opening for truncation.  This correctly solves the
1564 		 * create/create race, in the sense that any observable outcome can
1565 		 * be explained as one happening before the other.
1566 		 * The create/create race is quite common.  For example, it happens
1567 		 * when two rc subshells simultaneously update the same
1568 		 * environment variable.
1569 		 *
1570 		 * The implementation still admits a create/create/remove race:
1571 		 * (A) walk to file, fails
1572 		 * (B) walk to file, fails
1573 		 * (A) create file, succeeds, returns
1574 		 * (B) create file, fails
1575 		 * (A) remove file, succeeds, returns
1576 		 * (B) walk to file, return failure.
1577 		 *
1578 		 * This is hardly as common as the create/create race, and is really
1579 		 * not too much worse than what might happen if (B) got a hold of a
1580 		 * file descriptor and then the file was removed -- either way (B) can't do
1581 		 * anything with the result of the create call.  So we don't care about this race.
1582 		 *
1583 		 * Applications that care about more fine-grained decision of the races
1584 		 * can use the OEXCL flag to get at the underlying create(5) semantics;
1585 		 * by default we provide the common case.
1586 		 *
1587 		 * We need to stay behind the mount point in case we
1588 		 * need to do the first walk again (should the create fail).
1589 		 *
1590 		 * We also need to cross the mount point and find the directory
1591 		 * in the union in which we should be creating.
1592 		 *
1593 		 * The channel staying behind is c, the one moving forward is cnew.
1594 		 */
1595 		m = nil;
1596 		cnew = nil;	/* is this assignment necessary? */
1597 		if(!waserror()){	/* try create */
1598 			if(!nomount && findmount(&cnew, &m, c->type, c->dev, c->qid))
1599 				cnew = createdir(cnew, m);
1600 			else{
1601 				cnew = c;
1602 				incref(cnew);
1603 			}
1604 
1605 			/*
1606 			 * We need our own copy of the Chan because we're
1607 			 * about to send a create, which will move it.  Once we have
1608 			 * our own copy, we can fix the name, which might be wrong
1609 			 * if findmount gave us a new Chan.
1610 			 */
1611 			cnew = cunique(cnew);
1612 			pathclose(cnew->path);
1613 			cnew->path = c->path;
1614 			incref(cnew->path);
1615 
1616 			devtab[cnew->type]->create(cnew, e.elems[e.nelems-1], omode&~(OEXCL|OCEXEC), perm);
1617 			poperror();
1618 			if(omode & OCEXEC)
1619 				cnew->flag |= CCEXEC;
1620 			if(omode & ORCLOSE)
1621 				cnew->flag |= CRCLOSE;
1622 			if(m)
1623 				putmhead(m);
1624 			cclose(c);
1625 			c = cnew;
1626 			c->path = addelem(c->path, e.elems[e.nelems-1], nil);
1627 			break;
1628 		}
1629 
1630 		/* create failed */
1631 		cclose(cnew);
1632 		if(m)
1633 			putmhead(m);
1634 		if(omode & OEXCL)
1635 			nexterror();
1636 		/* save error */
1637 		createerr = up->errstr;
1638 		up->errstr = tmperrbuf;
1639 		/* note: we depend that walk does not error */
1640 		if(walk(&c, e.elems+e.nelems-1, 1, nomount, nil) < 0){
1641 			up->errstr = createerr;
1642 			error(createerr);	/* report true error */
1643 		}
1644 		up->errstr = createerr;
1645 		omode |= OTRUNC;
1646 		goto Open;
1647 
1648 	default:
1649 		panic("unknown namec access %d\n", amode);
1650 	}
1651 
1652 	/* place final element in genbuf for e.g. exec */
1653 	if(e.nelems > 0)
1654 		kstrcpy(up->genbuf, e.elems[e.nelems-1], sizeof up->genbuf);
1655 	else
1656 		kstrcpy(up->genbuf, ".", sizeof up->genbuf);
1657 	free(e.name);
1658 	free(e.elems);
1659 	free(e.off);
1660 	poperror();	/* e c */
1661 	free(aname);
1662 	poperror();	/* aname */
1663 
1664 	return c;
1665 }
1666 
1667 /*
1668  * name is valid. skip leading / and ./ as much as possible
1669  */
1670 char*
skipslash(char * name)1671 skipslash(char *name)
1672 {
1673 	while(name[0]=='/' || (name[0]=='.' && (name[1]==0 || name[1]=='/')))
1674 		name++;
1675 	return name;
1676 }
1677 
1678 char isfrog[256]={
1679 	/*NUL*/	1, 1, 1, 1, 1, 1, 1, 1,
1680 	/*BKS*/	1, 1, 1, 1, 1, 1, 1, 1,
1681 	/*DLE*/	1, 1, 1, 1, 1, 1, 1, 1,
1682 	/*CAN*/	1, 1, 1, 1, 1, 1, 1, 1,
1683 	['/']	1,
1684 	[0x7f]	1,
1685 };
1686 
1687 /*
1688  * Check that the name
1689  *  a) is in valid memory.
1690  *  b) is shorter than 2^16 bytes, so it can fit in a 9P string field.
1691  *  c) contains no frogs.
1692  * The first byte is known to be addressible by the requester, so the
1693  * routine works for kernel and user memory both.
1694  * The parameter slashok flags whether a slash character is an error
1695  * or a valid character.
1696  *
1697  * The parameter dup flags whether the string should be copied
1698  * out of user space before being scanned the second time.
1699  * (Otherwise a malicious thread could remove the NUL, causing us
1700  * to access unchecked addresses.)
1701  */
1702 static char*
validname0(char * aname,int slashok,int dup,ulong pc)1703 validname0(char *aname, int slashok, int dup, ulong pc)
1704 {
1705 	char *ename, *name, *s;
1706 	int c, n;
1707 	Rune r;
1708 
1709 	name = aname;
1710 	if((ulong)name < KZERO){
1711 		if(!dup)
1712 			print("warning: validname called from %#p with user pointer", pc);
1713 		ename = vmemchr(name, 0, (1<<16));
1714 	}else
1715 		ename = memchr(name, 0, (1<<16));
1716 
1717 	if(ename==nil || ename-name>=(1<<16))
1718 		error("name too long");
1719 
1720 	s = nil;
1721 	if(dup){
1722 		n = ename-name;
1723 		s = smalloc(n+1);
1724 		memmove(s, name, n);
1725 		s[n] = 0;
1726 		aname = s;
1727 		name = s;
1728 		setmalloctag(s, pc);
1729 	}
1730 
1731 	while(*name){
1732 		/* all characters above '~' are ok */
1733 		c = *(uchar*)name;
1734 		if(c >= Runeself)
1735 			name += chartorune(&r, name);
1736 		else{
1737 			if(isfrog[c])
1738 				if(!slashok || c!='/'){
1739 					snprint(up->genbuf, sizeof(up->genbuf), "%s: %q", Ebadchar, aname);
1740 					free(s);
1741 					error(up->genbuf);
1742 			}
1743 			name++;
1744 		}
1745 	}
1746 	return s;
1747 }
1748 
1749 void
validname(char * aname,int slashok)1750 validname(char *aname, int slashok)
1751 {
1752 	validname0(aname, slashok, 0, getcallerpc(&aname));
1753 }
1754 
1755 char*
validnamedup(char * aname,int slashok)1756 validnamedup(char *aname, int slashok)
1757 {
1758 	return validname0(aname, slashok, 1, getcallerpc(&aname));
1759 }
1760 
1761 void
isdir(Chan * c)1762 isdir(Chan *c)
1763 {
1764 	if(c->qid.type & QTDIR)
1765 		return;
1766 	error(Enotdir);
1767 }
1768 
1769 /*
1770  * This is necessary because there are many
1771  * pointers to the top of a given mount list:
1772  *
1773  *	- the mhead in the namespace hash table
1774  *	- the mhead in chans returned from findmount:
1775  *	  used in namec and then by unionread.
1776  *	- the mhead in chans returned from createdir:
1777  *	  used in the open/create race protect, which is gone.
1778  *
1779  * The RWlock in the Mhead protects the mount list it contains.
1780  * The mount list is deleted when we cunmount.
1781  * The RWlock ensures that nothing is using the mount list at that time.
1782  *
1783  * It is okay to replace c->mh with whatever you want as
1784  * long as you are sure you have a unique reference to it.
1785  *
1786  * This comment might belong somewhere else.
1787  */
1788 void
putmhead(Mhead * m)1789 putmhead(Mhead *m)
1790 {
1791 	if(m && decref(m) == 0){
1792 		m->mount = (Mount*)0xCafeBeef;
1793 		free(m);
1794 	}
1795 }
1796 
1797