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