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