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