Fix a bunch of %lud and %lux
[akaros.git] / kern / src / ns / chan.c
1 // INFERNO
2 #include <vfs.h>
3 #include <kfs.h>
4 #include <slab.h>
5 #include <kmalloc.h>
6 #include <kref.h>
7 #include <string.h>
8 #include <stdio.h>
9 #include <assert.h>
10 #include <error.h>
11 #include <cpio.h>
12 #include <pmap.h>
13 #include <smp.h>
14 #include <syscall.h>
15
16 char*
17 channame(struct chan *c)                /* DEBUGGING */
18 {
19         if(c == NULL)
20                 return "<NULL chan>";
21         if(c->name == NULL)
22                 return "<NULL name>";
23         if(c->name->s == NULL)
24                 return "<NULL name.s>";
25         return c->name->s;
26 }
27
28 enum
29 {
30         CNAMESLOP       = 20
31 };
32
33 struct
34 {
35         spinlock_t lock;
36         int     fid;
37         struct chan     *free;
38         struct chan     *list;
39 }chanalloc;
40
41 typedef struct Elemlist Elemlist;
42
43 struct Elemlist
44 {
45         char    *name;  /* copy of name, so '/' can be overwritten */
46         int     ARRAY_SIZEs;
47         char    **elems;
48         int     *off;
49         int     mustbedir;
50 };
51
52 #define SEP(c) ((c) == 0 || (c) == '/')
53 void cleancname(struct cname*);
54
55 int
56 isdotdot(char *p)
57 {
58         return p[0]=='.' && p[1]=='.' && p[2]=='\0';
59 }
60
61 int
62 emptystr(char *s)
63 {
64         if(s == NULL)
65                 return 1;
66         if(s[0] == '\0')
67                 return 1;
68         return 0;
69 }
70
71 /*
72  * Atomically replace *p with copy of s
73  */
74 void
75 kstrdup(char **p, char *s)
76 {
77         int n;
78         char *t, *prev;
79
80         n = strlen(s)+1;
81         /* if it's a user, we can wait for memory; if not, something's very wrong */
82         if (current) {
83                 t = kzmalloc(n, 0);
84         }else{
85                 t = kzmalloc(n, 0);
86                 if(t == NULL)
87                         panic("kstrdup: no memory");
88         }
89         memmove(t, s, n);
90         prev = *p;
91         *p = t;
92         kfree(prev);
93 }
94
95 void
96 chandevreset(void)
97 {
98         int i;
99
100         for(i=0; &devtab[i] < __devtabend; i++)
101                 devtab[i].reset();
102 }
103
104 void
105 chandevinit(void)
106 {
107         int i;
108
109         for(i=0; &devtab[i] < __devtabend; i++)
110                 devtab[i].init();
111 }
112
113 void
114 chandevshutdown(void)
115 {
116         int i;
117         
118         /* shutdown in reverse order */
119         for(i=0; &devtab[i] < __devtabend; i++)
120                 ;
121         for(i--; i >= 0; i--)
122                 devtab[i].shutdown();
123 }
124
125 static void chan_release(struct kref *kref)
126 {
127         struct chan *c = container_of(kref, struct chan, ref);
128         ERRSTACK(1);
129         /* this style discards the error from close().  picture it as
130          * if (waserror()) { } else { close(); } chanfree_no_matter_what();  */
131         if (!waserror()) {
132                 printd("releasing chan %p, type %d\n", c, c->type);
133                 /* -1 means there is no dev yet.  wants a noop for close() */
134                 if (c->type != -1)
135                         devtab[c->type].close(c);
136         }
137         /* need to poperror regardless of whether we error'd or not */
138         poperror();
139         /* and chan free no matter what */
140         chanfree(c);
141 }
142
143 struct chan*
144 newchan(void)
145 {
146         struct chan *c;
147
148         spin_lock(&(&chanalloc)->lock);
149         c = chanalloc.free;
150         if(c != 0)
151                 chanalloc.free = c->next;
152         spin_unlock(&(&chanalloc)->lock);
153
154         if(c == NULL) {
155                 c = kzmalloc(sizeof(struct chan), 0);
156                 spin_lock(&(&chanalloc)->lock);
157                 c->fid = ++chanalloc.fid;
158                 c->link = chanalloc.list;
159                 chanalloc.list = c;
160                 spin_unlock(&(&chanalloc)->lock);
161                 spinlock_init(&c->lock);
162                 qlock_init(&c->umqlock);
163         }
164
165         /* if you get an error before associating with a dev, cclose skips calling
166          * the dev's close */
167         c->type = -1;
168         c->flag = 0;
169         kref_init(&c->ref, chan_release, 1);
170         c->dev = 0;
171         c->offset = 0;
172         c->iounit = 0;
173         c->umh = 0;
174         c->uri = 0;
175         c->dri = 0;
176         c->aux = 0;
177         c->mchan = 0;
178         c->mcp = 0;
179         c->mux = 0;
180         c->mqid.path = 0;
181         c->mqid.vers = 0;
182         c->mqid.type = 0;
183         c->name = 0;
184         return c;
185 }
186
187 static void __cname_release(struct kref *kref)
188 {
189         struct cname *n = container_of(kref, struct cname, ref);
190         kfree(n->s);
191         kfree(n);
192 }
193
194 struct cname*
195 newcname(char *s)
196 {
197         struct cname *n;
198         int i;
199
200         n = kzmalloc(sizeof(*n), 0);
201         i = strlen(s);
202         n->len = i;
203         n->alen = i+CNAMESLOP;
204         n->s = kzmalloc(n->alen, 0);
205         memmove(n->s, s, i+1);
206         kref_init(&n->ref, __cname_release, 1);
207         return n;
208 }
209
210 void
211 cnameclose(struct cname *n)
212 {
213         if(n == NULL)
214                 return;
215         kref_put(&n->ref);
216 }
217
218 struct cname*
219 addelem(struct cname *n, char *s)
220 {
221         int i, a;
222         char *t;
223         struct cname *new;
224
225         if(s[0]=='.' && s[1]=='\0')
226                 return n;
227
228         if(kref_refcnt(&n->ref) > 1){
229                 /* copy on write */
230                 new = newcname(n->s);
231                 cnameclose(n);
232                 n = new;
233         }
234
235         i = strlen(s);
236         if(n->len+1+i+1 > n->alen){
237                 a = n->len+1+i+1 + CNAMESLOP;
238                 t = kzmalloc(a, 0);
239                 memmove(t, n->s, n->len+1);
240                 kfree(n->s);
241                 n->s = t;
242                 n->alen = a;
243         }
244         if(n->len>0 && n->s[n->len-1]!='/' && s[0]!='/')        /* don't insert extra slash if one is present */
245                 n->s[n->len++] = '/';
246         memmove(n->s+n->len, s, i+1);
247         n->len += i;
248         if(isdotdot(s))
249                 cleancname(n);
250         return n;
251 }
252
253 void
254 chanfree(struct chan *c)
255 {
256         c->flag = CFREE;
257
258         if(c->umh != NULL){
259                 putmhead(c->umh);
260                 c->umh = NULL;
261         }
262         if(c->umc != NULL){
263                 cclose(c->umc);
264                 c->umc = NULL;
265         }
266         if(c->mux != NULL){
267                 //
268                 muxclose(c->mux);
269                 c->mux = NULL;
270         }
271         if(c->mchan != NULL){
272                 cclose(c->mchan);
273                 c->mchan = NULL;
274         }
275
276         cnameclose(c->name);
277
278         spin_lock(&(&chanalloc)->lock);
279         c->next = chanalloc.free;
280         chanalloc.free = c;
281         spin_unlock(&(&chanalloc)->lock);
282 }
283
284 void
285 cclose(struct chan *c)
286 {
287         if(c == 0)
288                 return;
289
290         if(c->flag&CFREE)
291                 panic("cclose %p", getcallerpc(&c));
292
293         kref_put(&c->ref);
294 }
295
296 /*
297  * Make sure we have the only copy of c.  (Copy on write.)
298  */
299 struct chan*
300 cunique(struct chan *c)
301 {
302         struct chan *nc;
303
304         if(kref_refcnt(&c->ref) != 1) {
305                 nc = cclone(c);
306                 cclose(c);
307                 c = nc;
308         }
309
310         return c;
311 }
312
313 int
314 eqqid(struct qid a, struct qid b)
315 {
316         return a.path==b.path && a.vers==b.vers;
317 }
318
319 int
320 eqchan(struct chan *a, struct chan *b, int pathonly)
321 {
322         if(a->qid.path != b->qid.path)
323                 return 0;
324         if(!pathonly && a->qid.vers!=b->qid.vers)
325                 return 0;
326         if(a->type != b->type)
327                 return 0;
328         if(a->dev != b->dev)
329                 return 0;
330         return 1;
331 }
332
333 int
334 eqchantdqid(struct chan *a, int type, int dev, struct qid qid, int pathonly)
335 {
336         if(a->qid.path != qid.path)
337                 return 0;
338         if(!pathonly && a->qid.vers!=qid.vers)
339                 return 0;
340         if(a->type != type)
341                 return 0;
342         if(a->dev != dev)
343                 return 0;
344         return 1;
345 }
346
347 static void mh_release(struct kref *kref)
348 {
349         struct mhead *mh = container_of(kref, struct mhead, ref);
350         mh->mount = (struct mount*)0xCafeBeef;
351         kfree(mh);
352 }
353
354 struct mhead *newmhead(struct chan *from)
355 {
356         struct mhead *mh;
357
358         mh = kzmalloc(sizeof(struct mhead), 0);
359         kref_init(&mh->ref, mh_release, 1);
360         mh->from = from;
361         kref_get(&from->ref, 1);
362
363 /*
364         n = from->name->len;
365         if(n >= sizeof(mh->fromname))
366                 n = sizeof(mh->fromname)-1;
367         memmove(mh->fromname, from->name->s, n);
368         mh->fromname[n] = 0;
369 */
370         return mh;
371 }
372
373 int
374 cmount(struct chan *new, struct chan *old, int flag, char *spec)
375 {
376         ERRSTACK(1);
377         struct pgrp *pg;
378         int order, flg;
379         struct mhead *m, **l, *mh;
380         struct mount *nm, *f, *um, **h;
381
382         if(QTDIR & (old->qid.type^new->qid.type))
383                 error(Emount);
384
385 if(old->umh)
386         printd("cmount old extra umh\n");
387
388         order = flag&MORDER;
389
390         if((old->qid.type&QTDIR)==0 && order != MREPL)
391                 error(Emount);
392
393         mh = new->umh;
394
395         /*
396          * Not allowed to bind when the old directory
397          * is itself a union.  (Maybe it should be allowed, but I don't see
398          * what the semantics would be.)
399          *
400          * We need to check mh->mount->next to tell unions apart from
401          * simple mount points, so that things like
402          *      mount -c fd /root
403          *      bind -c /root /
404          * work.  The check of mount->mflag catches things like
405          *      mount fd /root
406          *      bind -c /root /
407          * 
408          * This is far more complicated than it should be, but I don't
409          * see an easier way at the moment.             -rsc
410          */
411         if((flag&MCREATE) && mh && mh->mount
412         && (mh->mount->next || !(mh->mount->mflag&MCREATE)))
413                 error(Emount);
414
415         pg = current->pgrp;
416         wlock(&pg->ns);
417
418         l = &MOUNTH(pg, old->qid);
419         for(m = *l; m; m = m->hash) {
420                 if(eqchan(m->from, old, 1))
421                         break;
422                 l = &m->hash;
423         }
424
425         if(m == NULL) {
426                 /*
427                  *  nothing mounted here yet.  create a mount
428                  *  head and add to the hash table.
429                  */
430                 m = newmhead(old);
431                 *l = m;
432
433                 /*
434                  *  if this is a union mount, add the old
435                  *  node to the mount chain.
436                  */
437                 if(order != MREPL)
438                         m->mount = newmount(m, old, 0, 0);
439         }
440         wlock(&m->lock);
441         if(waserror()){
442                 wunlock(&m->lock);
443                 nexterror();
444         }
445         wunlock(&pg->ns);
446
447         nm = newmount(m, new, flag, spec);
448         if(mh != NULL && mh->mount != NULL) {
449                 /*
450                  *  copy a union when binding it onto a directory
451                  */
452                 flg = order;
453                 if(order == MREPL)
454                         flg = MAFTER;
455                 h = &nm->next;
456                 um = mh->mount;
457                 for(um = um->next; um; um = um->next) {
458                         f = newmount(m, um->to, flg, um->spec);
459                         *h = f;
460                         h = &f->next;
461                 }
462         }
463
464         if(m->mount && order == MREPL) {
465                 mountfree(m->mount);
466                 m->mount = 0;
467         }
468
469         if(flag & MCREATE)
470                 nm->mflag |= MCREATE;
471
472         if(m->mount && order == MAFTER) {
473                 for(f = m->mount; f->next; f = f->next)
474                         ;
475                 f->next = nm;
476         }
477         else {
478                 for(f = nm; f->next; f = f->next)
479                         ;
480                 f->next = m->mount;
481                 m->mount = nm;
482         }
483
484         wunlock(&m->lock);
485         poperror();
486         return nm->mountid;
487 }
488
489 void
490 cunmount(struct chan *mnt, struct chan *mounted)
491 {
492         struct pgrp *pg;
493         struct mhead *m, **l;
494         struct mount *f, **p;
495
496         if(mnt->umh)    /* should not happen */
497                 printd("cunmount newp extra umh %p has %p\n", mnt, mnt->umh);
498
499         /*
500          * It _can_ happen that mounted->umh is non-NULL, 
501          * because mounted is the result of namec(Aopen)
502          * (see sysfile.c:/^sysunmount).
503          * If we open a union directory, it will have a umh.
504          * Although surprising, this is okay, since the
505          * cclose will take care of freeing the umh.
506          */
507
508         pg = current->pgrp;
509         wlock(&pg->ns);
510
511         l = &MOUNTH(pg, mnt->qid);
512         for(m = *l; m; m = m->hash) {
513                 if(eqchan(m->from, mnt, 1))
514                         break;
515                 l = &m->hash;
516         }
517
518         if(m == 0) {
519                 wunlock(&pg->ns);
520                 error(Eunmount);
521         }
522
523         wlock(&m->lock);
524         if(mounted == 0) {
525                 *l = m->hash;
526                 wunlock(&pg->ns);
527                 mountfree(m->mount);
528                 m->mount = NULL;
529                 cclose(m->from);
530                 wunlock(&m->lock);
531                 putmhead(m);
532                 return;
533         }
534
535         p = &m->mount;
536         for(f = *p; f; f = f->next) {
537                 /* BUG: Needs to be 2 pass */
538                 if(eqchan(f->to, mounted, 1) ||
539                   (f->to->mchan && eqchan(f->to->mchan, mounted, 1))) {
540                         *p = f->next;
541                         f->next = 0;
542                         mountfree(f);
543                         if(m->mount == NULL) {
544                                 *l = m->hash;
545                                 cclose(m->from);
546                                 wunlock(&m->lock);
547                                 wunlock(&pg->ns);
548                                 putmhead(m);
549                                 return;
550                         }
551                         wunlock(&m->lock);
552                         wunlock(&pg->ns);
553                         return;
554                 }
555                 p = &f->next;
556         }
557         wunlock(&m->lock);
558         wunlock(&pg->ns);
559         error(Eunion);
560 }
561
562 struct chan*
563 cclone(struct chan *c)
564 {
565         struct chan *nc;
566         struct walkqid *wq;
567
568         wq = devtab[c->type].walk(c, NULL, NULL, 0);
569         if(wq == NULL)
570                 error("clone failed");
571         nc = wq->clone;
572         kfree(wq);
573         nc->name = c->name;
574         if(c->name)
575                 kref_get(&c->name->ref, 1);
576         return nc;
577 }
578
579 int
580 findmount(struct chan **cp,
581           struct mhead **mp, int type, int dev, struct qid qid)
582 {
583         struct pgrp *pg;
584         struct mhead *m;
585
586         pg = current->pgrp;
587         rlock(&pg->ns);
588         for(m = MOUNTH(pg, qid); m; m = m->hash){
589                 rlock(&m->lock);
590 if(m->from == NULL){
591         printd("m %p m->from 0\n", m);
592         runlock(&m->lock);
593         continue;
594 }
595                 if(eqchantdqid(m->from, type, dev, qid, 1)) {
596                         runlock(&pg->ns);
597                         if(mp != NULL){
598                                 kref_get(&m->ref, 1);
599                                 if(*mp != NULL)
600                                         putmhead(*mp);
601                                 *mp = m;
602                         }
603                         if(*cp != NULL)
604                                 cclose(*cp);
605                         kref_get(&m->mount->to->ref, 1);
606                         *cp = m->mount->to;
607                         runlock(&m->lock);
608                         return 1;
609                 }
610                 runlock(&m->lock);
611         }
612
613         runlock(&pg->ns);
614         return 0;
615 }
616
617 int
618 domount(struct chan **cp, struct mhead **mp)
619 {
620         return findmount(cp, mp, (*cp)->type, (*cp)->dev, (*cp)->qid);
621 }
622
623 struct chan*
624 undomount(struct chan *c, struct cname *name)
625 {
626         ERRSTACK(1);
627         struct chan *nc;
628         struct pgrp *pg;
629         struct mount *t;
630         struct mhead **h, **he, *f;
631
632         pg = current->pgrp;
633         rlock(&pg->ns);
634         if(waserror()) {
635                 runlock(&pg->ns);
636                 nexterror();
637         }
638
639         he = &pg->mnthash[MNTHASH];
640         for(h = pg->mnthash; h < he; h++) {
641                 for(f = *h; f; f = f->hash) {
642                         if(strcmp(f->from->name->s, name->s) != 0)
643                                 continue;
644                         for(t = f->mount; t; t = t->next) {
645                                 if(eqchan(c, t->to, 1)) {
646                                         /*
647                                          * We want to come out on the left hand side of the mount
648                                          * point using the element of the union that we entered on.
649                                          * To do this, find the element that has a from name of
650                                          * c->name->s.
651                                          */
652                                         if(strcmp(t->head->from->name->s, name->s) != 0)
653                                                 continue;
654                                         nc = t->head->from;
655                                         kref_get(&nc->ref, 1);
656                                         cclose(c);
657                                         c = nc;
658                                         break;
659                                 }
660                         }
661                 }
662         }
663         poperror();
664         runlock(&pg->ns);
665         return c;
666 }
667
668 /*
669  * Either walks all the way or not at all.  No partial results in *cp.
670  * *nerror is the number of names to display in an error message.
671  */
672 static char Edoesnotexist[] = "does not exist";
673 int
674 walk(struct chan **cp, char **names, int nnames, int nomount, int *nerror)
675 {
676         int dev, dotdot, i, n, nhave, ntry, type;
677         struct chan *c, *nc;
678         struct cname *cname;
679         struct mount *f;
680         struct mhead *mh, *nmh;
681         struct walkqid *wq;
682
683         c = *cp;
684         kref_get(&c->ref, 1);
685         cname = c->name;
686         kref_get(&cname->ref, 1);
687         mh = NULL;
688
689         /*
690          * While we haven't gotten all the way down the path:
691          *    1. step through a mount po int unused_int, if any
692          *    2. send a walk request for initial dotdot or initial prefix without dotdot
693          *    3. move to the first mountpoint along the way.
694          *    4. repeat.
695          *
696          * An invariant is that each time through the loop, c is on the undomount
697          * side of the mount po int unused_int, and c's name is cname.
698          */
699         for(nhave=0; nhave<nnames; nhave+=n){
700                 if((c->qid.type&QTDIR)==0){
701                         if(nerror)
702                                 *nerror = nhave;
703                         cnameclose(cname);
704                         cclose(c);
705                         set_errstr(Enotdir);
706                         if(mh != NULL)
707                                 putmhead(mh);
708                         return -1;
709                 }
710                 ntry = nnames - nhave;
711                 if(ntry > MAXWELEM)
712                         ntry = MAXWELEM;
713                 dotdot = 0;
714                 for(i=0; i<ntry; i++){
715                         if(isdotdot(names[nhave+i])){
716                                 if(i==0) {
717                                         dotdot = 1;
718                                         ntry = 1;
719                                 } else
720                                         ntry = i;
721                                 break;
722                         }
723                 }
724
725                 if(!dotdot && !nomount)
726                         domount(&c, &mh);
727
728                 type = c->type;
729                 dev = c->dev;
730
731                 if((wq = devtab[type].walk(c, NULL, names+nhave, ntry)) == NULL){
732                         /* try a union mount, if any */
733                         if(mh && !nomount){
734                                 /*
735                                  * mh->mount == c, so start at mh->mount->next
736                                  */
737                                 rlock(&mh->lock);
738                                 for(f = mh->mount->next; f; f = f->next)
739                                         if((wq = devtab[f->to->type].walk(f->to, NULL, names+nhave, ntry)) != NULL)
740                                                 break;
741                                 runlock(&mh->lock);
742                                 if(f != NULL){
743                                         type = f->to->type;
744                                         dev = f->to->dev;
745                                 }
746                         }
747                         if(wq == NULL){
748                                 cclose(c);
749                                 cnameclose(cname);
750                                 if(nerror)
751                                         *nerror = nhave+1;
752                                 if(mh != NULL)
753                                         putmhead(mh);
754                                 return -1;
755                         }
756                 }
757
758                 nmh = NULL;
759                 if(dotdot) {
760                         assert(wq->nqid == 1);
761                         assert(wq->clone != NULL);
762
763                         cname = addelem(cname, "..");
764                         nc = undomount(wq->clone, cname);
765                         n = 1;
766                 } else {
767                         nc = NULL;
768                         if(!nomount)
769                                 for(i=0; i<wq->nqid && i<ntry-1; i++)
770                                         if(findmount(&nc, &nmh, type, dev, wq->qid[i]))
771                                                 break;
772                         if(nc == NULL){ /* no mount points along path */
773                                 if(wq->clone == NULL){
774                                         cclose(c);
775                                         cnameclose(cname);
776                                         if(wq->nqid==0 || (wq->qid[wq->nqid-1].type&QTDIR)){
777                                                 if(nerror)
778                                                         *nerror = nhave+wq->nqid+1;
779                                                 set_errstr(Edoesnotexist);
780                                         }else{
781                                                 if(nerror)
782                                                         *nerror = nhave+wq->nqid;
783                                                 set_errstr(Enotdir);
784                                         }
785                                         kfree(wq);
786                                         if(mh != NULL)
787                                                 putmhead(mh);
788                                         return -1;
789                                 }
790                                 n = wq->nqid;
791                                 nc = wq->clone;
792                         }else{          /* stopped early, at a mount point */
793                                 if(wq->clone != NULL){
794                                         cclose(wq->clone);
795                                         wq->clone = NULL;
796                                 }
797                                 n = i+1;
798                         }
799                         for(i=0; i<n; i++)
800                                 cname = addelem(cname, names[nhave+i]);
801                 }
802                 cclose(c);
803                 c = nc;
804                 putmhead(mh);
805                 mh = nmh;
806                 kfree(wq);
807         }
808
809         putmhead(mh);
810
811         c = cunique(c);
812
813         if(c->umh != NULL){     //BUG
814                 printd("walk umh\n");
815                 putmhead(c->umh);
816                 c->umh = NULL;
817         }
818
819         cnameclose(c->name);
820         c->name = cname;
821
822         cclose(*cp);
823         *cp = c;
824         if(nerror)
825                 *nerror = 0;
826         return 0;
827 }
828
829 /*
830  * c is a mounted non-creatable directory.  find a creatable one.
831  */
832 struct chan*
833 createdir(struct chan *c, struct mhead *m)
834 {
835         ERRSTACK(1);
836         struct chan *nc;
837         struct mount *f;
838
839         rlock(&m->lock);
840         if(waserror()) {
841                 runlock(&m->lock);
842                 nexterror();
843         }
844         for(f = m->mount; f; f = f->next) {
845                 if(f->mflag&MCREATE) {
846                         nc = cclone(f->to);
847                         runlock(&m->lock);
848                         poperror();
849                         cclose(c);
850                         return nc;
851                 }
852         }
853         error(Enocreate);
854         poperror();
855         return 0;
856 }
857
858 /*
859  * In place, rewrite name to compress multiple /, eliminate ., and process ..
860  */
861 void
862 cleancname(struct cname *n)
863 {
864         char *p;
865
866         if(n->s[0] == '#'){
867                 p = strchr(n->s, '/');
868                 if(p == NULL)
869                         return;
870                 cleanname(p);
871
872                 /*
873                  * The correct name is #i rather than #i/,
874                  * but the correct name of #/ is #/.
875                  */
876                 if(strcmp(p, "/")==0 && n->s[1] != '/')
877                         *p = '\0';
878         }else
879                 cleanname(n->s);
880         n->len = strlen(n->s);
881 }
882
883 static void
884 growparse(Elemlist *e)
885 {
886         char **new;
887         int *inew;
888         enum { Delta = 8 };
889
890         if(e->ARRAY_SIZEs % Delta == 0){
891                 new = kzmalloc((e->ARRAY_SIZEs + Delta) * sizeof(char *), 0);
892                 memmove(new, e->elems, e->ARRAY_SIZEs*sizeof( char *));
893                 kfree(e->elems);
894                 e->elems = new;
895                 inew = kzmalloc((e->ARRAY_SIZEs + Delta + 1) * sizeof(int), 0);
896                 memmove(inew, e->off, e->ARRAY_SIZEs*sizeof(int));
897                 kfree(e->off);
898                 e->off = inew;
899         }
900 }
901
902 /*
903  * The name is known to be valid.
904  * Copy the name so slashes can be overwritten.
905  * An empty string will set ARRAY_SIZE=0.
906  * A path ending in / or /. or /.//./ etc. will have
907  * e.mustbedir = 1, so that we correctly
908  * reject, e.g., "/adm/users/." when /adm/users is a file
909  * rather than a directory.
910  */
911 static void
912 parsename(char *name, Elemlist *e)
913 {
914         char *slash;
915
916         kstrdup(&e->name, name);
917         name = e->name;
918         e->ARRAY_SIZEs = 0;
919         e->elems = NULL;
920         e->off = kzmalloc(sizeof(int), 0);
921         e->off[0] = skipslash(name) - name;
922         for(;;){
923                 name = skipslash(name);
924                 if(*name=='\0'){
925                         e->mustbedir = 1;
926                         break;
927                 }
928                 growparse(e);
929                 
930                 e->elems[e->ARRAY_SIZEs++] = name;
931                 /* we may want to do this again some day
932                 slash = utfrune(name, '/');
933                 */
934                 slash = strchr(name, '/');
935                 if(slash == NULL){
936                         e->off[e->ARRAY_SIZEs] = name+strlen(name) - e->name;
937                         e->mustbedir = 0;
938                         break;
939                 }
940                 e->off[e->ARRAY_SIZEs] = slash - e->name;
941                 *slash++ = '\0';
942                 name = slash;
943         }
944 }
945
946 void*
947 memrchr(void *va, int c, long n)
948 {
949         uint8_t *a, *e;
950
951         a = va;
952         for(e=a+n-1; e>a; e--)
953                 if(*e == c)
954                         return e;
955         return NULL;
956 }
957
958 /*
959  * Turn a name into a channel.
960  * &name[0] is known to be a valid address.  It may be a kernel address.
961  *
962  * Opening with amode Aopen, Acreate, or Aremove guarantees
963  * that the result will be the only reference to that particular fid.
964  * This is necessary since we might pass the result to
965  * devtab[].remove().
966  *
967  * Opening Atodir, Amount, or Aaccess does not guarantee this.
968  *
969  * Opening Aaccess can, under certain conditions, return a
970  * correct Chan* but with an incorrect struct cname attached.
971  * Since the functions that open Aaccess (sysstat, syswstat, sys_stat)
972  * do not use the struct cname*, this avoids an unnecessary clone.
973  */
974 struct chan*
975 namec(char *aname, int amode, int omode, uint32_t perm)
976 {
977         ERRSTACK(2);
978         int n, prefix, len, t, nomount, npath;
979         struct chan *c, *cnew;
980         struct cname *cname;
981         Elemlist e;
982         struct mhead *m;
983         char tmperrbuf[ERRMAX];
984         char *name;
985         // Rune r;
986
987         name = aname;
988         if(name[0] == '\0')
989                 error("empty file name");
990         validname(name, 1);
991
992         /*
993          * Find the starting off point (the current slash, the root of
994          * a device tree, or the current dot) as well as the name to
995          * evaluate starting there.
996          */
997         nomount = 0;
998         switch(name[0]){
999         case '/':
1000                 c = current->slash;
1001                 if (! c)
1002                         panic("no slash!");
1003                 kref_get(&c->ref, 1);
1004                 break;
1005         
1006         case '#':
1007                 nomount = 1;
1008                 get_cur_genbuf()[0] = '\0';
1009                 n = 0;
1010                 while(*name!='\0' && (*name != '/' || n < 2)){
1011                         if(n >= sizeof(get_cur_genbuf())-1)
1012                                 error(Efilename);
1013                         get_cur_genbuf()[n++] = *name++;
1014                 }
1015                 get_cur_genbuf()[n] = '\0';
1016 #if 0
1017                 n = chartorune(&r, get_cur_genbuf()+1)+1;
1018                 if(r == 'M')
1019                         error(Enoattach);
1020 #endif
1021                 if (get_cur_genbuf()[1] == 'M')
1022                         error(Enoattach);
1023                 /*
1024                  *  the nodevs exceptions are
1025                  *      |  it only gives access to pipes you create
1026                  *      e  this process's environment
1027                  *      s  private file2chan creation space
1028                  *      D private secure sockets name space
1029                  *      a private TLS name space
1030                  */
1031                 if(current->pgrp->nodevs &&
1032                    //              (utfrune("|esDa", r) == NULL
1033                    ((strchr("|esDa", get_cur_genbuf()[1]) == NULL)
1034                     || (get_cur_genbuf()[1] == 's' // || r == 's'
1035                         && get_cur_genbuf()[n]!='\0')))
1036                         error(Enoattach);
1037                 t = devno(/*r*/get_cur_genbuf()[1], 1);
1038                 if(t == -1)
1039                         error(Ebadsharp);
1040                 c = devtab[t].attach(get_cur_genbuf()+n);
1041                 break;
1042
1043         default:
1044                 c = current->dot;
1045                 if (! c)
1046                         panic("no dot!");
1047                 kref_get(&c->ref, 1);
1048                 break;
1049         }
1050         prefix = name - aname;
1051
1052         e.name = NULL;
1053         e.elems = NULL;
1054         e.off = NULL;
1055         e.ARRAY_SIZEs = 0;
1056         if(waserror()){
1057                 cclose(c);
1058                 kfree(e.name);
1059                 kfree(e.elems);
1060                 kfree(e.off);
1061 //dumpmount();
1062                 nexterror();
1063         }
1064
1065         /*
1066          * Build a list of elements in the path.
1067          */
1068         parsename(name, &e);
1069
1070         /*
1071          * On create, ....
1072          */
1073         if(amode == Acreate){
1074                 /* perm must have DMDIR if last element is / or /. */
1075                 if(e.mustbedir && !(perm&DMDIR)){
1076                         npath = e.ARRAY_SIZEs;
1077                         strncpy(tmperrbuf,  "create without DMDIR", sizeof(tmperrbuf));
1078                         goto NameError;
1079                 }
1080
1081                 /* don't try to walk the last path element just yet. */
1082                 if(e.ARRAY_SIZEs == 0)
1083                         error(Eexist);
1084                 e.ARRAY_SIZEs--;
1085         }
1086
1087         if(walk(&c, e.elems, e.ARRAY_SIZEs, nomount, &npath) < 0){
1088                 if(npath < 0 || npath > e.ARRAY_SIZEs){
1089                         printd("namec %s walk error npath=%d\n", aname, npath);
1090                         error("walk failed");
1091                 }
1092         NameError:
1093                 error("some kinda name error");
1094                 /* brho: skipping the namec custom error string business, since it hides
1095                  * the underlying failure.  implement this if you want the old stuff. */
1096 #if 0
1097                 strncpy(tmperrbuf,  current->errstr, sizeof(tmperrbuf));
1098                 len = prefix+e.off[npath];
1099                 if(len < ERRMAX/3 || (name=memrchr(aname, '/', len))==NULL || name==aname)
1100                         snprintf(get_cur_genbuf(), sizeof current->genbuf, "%.*s", len, aname);
1101                 else
1102                         snprintf(get_cur_genbuf(), sizeof current->genbuf, "...%.*s", (int)(len-(name-aname)), name);
1103                 snprintf(current->errstr, ERRMAX, "%#q %s", get_cur_genbuf(), tmperrbuf);
1104 #endif
1105         }
1106
1107         if(e.mustbedir && !(c->qid.type&QTDIR)){
1108                 npath = e.ARRAY_SIZEs;
1109                 strncpy(tmperrbuf,  "not a directory", sizeof(tmperrbuf));
1110                 goto NameError;
1111         }
1112
1113         if(amode == Aopen && (omode&3) == OEXEC && (c->qid.type&QTDIR)){
1114                 npath = e.ARRAY_SIZEs;
1115                 error("cannot exec directory");
1116         }
1117
1118         switch(amode){
1119         case Aaccess:
1120                 if(!nomount)
1121                         domount(&c, NULL);
1122                 break;
1123
1124         case Abind:
1125                 m = NULL;
1126                 if(!nomount)
1127                         domount(&c, &m);
1128                 if(c->umh != NULL)
1129                         putmhead(c->umh);
1130                 c->umh = m;
1131                 break;
1132
1133         case Aremove:
1134         case Aopen:
1135         Open:
1136                 /* save the name; domount might change c */
1137                 cname = c->name;
1138                 kref_get(&cname->ref, 1);
1139                 m = NULL;
1140                 if(!nomount)
1141                         domount(&c, &m);
1142
1143                 /* our own copy to open or remove */
1144                 c = cunique(c);
1145
1146                 /* now it's our copy anyway, we can put the name back */
1147                 cnameclose(c->name);
1148                 c->name = cname;
1149
1150                 switch(amode){
1151                 case Aremove:
1152                         putmhead(m);
1153                         break;
1154
1155                 case Aopen:
1156                 case Acreate:
1157 if(c->umh != NULL){
1158         printd("cunique umh\n");
1159         putmhead(c->umh);
1160         c->umh = NULL;
1161 }
1162
1163                         /* only save the mount head if it's a multiple element union */
1164                         if(m && m->mount && m->mount->next)
1165                                 c->umh = m;
1166                         else
1167                                 putmhead(m);
1168
1169                         if(omode == OEXEC)
1170                                 c->flag &= ~CCACHE;
1171
1172                         c = devtab[c->type].open(c, omode&~OCEXEC);
1173
1174                         if(omode & OCEXEC)
1175                                 c->flag |= CCEXEC;
1176                         if(omode & ORCLOSE)
1177                                 c->flag |= CRCLOSE;
1178                         break;
1179                 }
1180                 break;
1181
1182         case Atodir:
1183                 /*
1184                  * Directories (e.g. for cd) are left before the mount po int unused_int,
1185                  * so one may mount on / or . and see the effect.
1186                  */
1187                 if(!(c->qid.type & QTDIR))
1188                         error(Enotdir);
1189                 break;
1190
1191         case Amount:
1192                 /*
1193                  * When mounting on an already mounted upon directory,
1194                  * one wants subsequent mounts to be attached to the
1195                  * original directory, not the replacement.  Don't domount.
1196                  */
1197                 break;
1198
1199         case Acreate:
1200                 /*
1201                  * We've already walked all but the last element.
1202                  * If the last exists, try to open it OTRUNC.
1203                  * If omode&OEXCL is set, just give up.
1204                  */
1205                 e.ARRAY_SIZEs++;
1206                 if(walk(&c, e.elems+e.ARRAY_SIZEs-1, 1, nomount, NULL) == 0){
1207                         if(omode&OEXCL)
1208                                 error(Eexist);
1209                         omode |= OTRUNC;
1210                         goto Open;
1211                 }
1212
1213                 /*
1214                  * The semantics of the create(2) system call are that if the
1215                  * file exists and can be written, it is to be opened with truncation.
1216                  * On the other hand, the create(5) message fails if the file exists.
1217                  * If we get two create(2) calls happening simultaneously, 
1218                  * they might both get here and send create(5) messages, but only 
1219                  * one of the messages will succeed.  To provide the expected create(2)
1220                  * semantics, the call with the failed message needs to try the above
1221                  * walk again, opening for truncation.  This correctly solves the 
1222                  * create/create race, in the sense that any observable outcome can
1223                  * be explained as one happening before the other.
1224                  * The create/create race is quite common.  For example, it happens
1225                  * when two rc subshells simultaneously update the same
1226                  * environment variable.
1227                  *
1228                  * The implementation still admits a create/create/remove race:
1229                  * (A) walk to file, fails
1230                  * (B) walk to file, fails
1231                  * (A) create file, succeeds, returns 
1232                  * (B) create file, fails
1233                  * (A) remove file, succeeds, returns
1234                  * (B) walk to file, return failure.
1235                  *
1236                  * This is hardly as common as the create/create race, and is really
1237                  * not too much worse than what might happen if (B) got a hold of a
1238                  * file descriptor and then the file was removed -- either way (B) can't do
1239                  * anything with the result of the create call.  So we don't care about this race.
1240                  *
1241                  * Applications that care about more fine-grained decision of the races
1242                  * can use the OEXCL flag to get at the underlying create(5) semantics;
1243                  * by default we provide the common case.
1244                  *
1245                  * We need to stay behind the mount point in case we
1246                  * need to do the first walk again (should the create fail).
1247                  *
1248                  * We also need to cross the mount point and find the directory
1249                  * in the union in which we should be creating.
1250                  *
1251                  * The channel staying behind is c, the one moving forward is cnew.
1252                  */
1253                 m = NULL;
1254                 cnew = NULL;    /* is this assignment necessary? */
1255                 /* discard error */
1256                 if(!waserror()){        /* try create */
1257                         if(!nomount && findmount(&cnew, &m, c->type, c->dev, c->qid))
1258                                 cnew = createdir(cnew, m);
1259                         else{
1260                                 cnew = c;
1261                                 kref_get(&cnew->ref, 1);
1262                         }
1263
1264                         /*
1265                          * We need our own copy of the Chan because we're
1266                          * about to send a create, which will move it.  Once we have
1267                          * our own copy, we can fix the name, which might be wrong
1268                          * if findmount gave us a new Chan.
1269                          */
1270                         cnew = cunique(cnew);
1271                         cnameclose(cnew->name);
1272                         cnew->name = c->name;
1273                         kref_get(&cnew->name->ref, 1);
1274
1275                         devtab[cnew->type].create(cnew, e.elems[e.ARRAY_SIZEs-1], omode&~(OEXCL|OCEXEC), perm);
1276                         poperror();
1277                         if(omode & OCEXEC)
1278                                 cnew->flag |= CCEXEC;
1279                         if(omode & ORCLOSE)
1280                                 cnew->flag |= CRCLOSE;
1281                         if(m)
1282                                 putmhead(m);
1283                         cclose(c);
1284                         c = cnew;
1285                         c->name = addelem(c->name, e.elems[e.ARRAY_SIZEs-1]);
1286                         break;
1287                 }
1288
1289                 /* create failed */
1290                 cclose(cnew);
1291                 if(m)
1292                         putmhead(m);
1293                 if(omode & OEXCL)
1294                         nexterror();    /* safe since we're in a waserror() */
1295                 poperror();             /* matching the if(!waserror) */
1296
1297                 /* save error, so walk doesn't clobber our existing errstr */         
1298                 strncpy(tmperrbuf, current_errstr(), MAX_ERRSTR_LEN);                 
1299                 /* note: we depend that walk does not error */
1300                 if (walk(&c, e.elems + e.ARRAY_SIZEs - 1, 1, nomount, NULL) < 0) {
1301                         error(tmperrbuf);   /* report the error we had originally */      
1302                 }
1303                 strncpy(current_errstr(), tmperrbuf, MAX_ERRSTR_LEN); 
1304                 omode |= OTRUNC;
1305                 goto Open;
1306
1307         default:
1308                 panic("unknown namec access %d\n", amode);
1309         }
1310
1311         poperror();
1312
1313         if(e.ARRAY_SIZEs > 0)
1314                 strncpy(get_cur_genbuf(), e.elems[e.ARRAY_SIZEs-1], GENBUF_SZ);
1315         else
1316                 strncpy(get_cur_genbuf(), ".", GENBUF_SZ);
1317
1318         kfree(e.name);
1319         kfree(e.elems);
1320         kfree(e.off);
1321
1322         return c;
1323 }
1324
1325 /*
1326  * name is valid. skip leading / and ./ as much as possible
1327  */
1328 char*
1329 skipslash(char *name)
1330 {
1331         while(name[0]=='/' || (name[0]=='.' && (name[1]==0 || name[1]=='/')))
1332                 name++;
1333         return name;
1334 }
1335
1336 char isfrog[256]={
1337         /*NUL*/ 1, 1, 1, 1, 1, 1, 1, 1,
1338         /*BKS*/ 1, 1, 1, 1, 1, 1, 1, 1,
1339         /*DLE*/ 1, 1, 1, 1, 1, 1, 1, 1,
1340         /*CAN*/ 1, 1, 1, 1, 1, 1, 1, 1,
1341         ['/']   1,
1342         [0x7f]  1,
1343 };
1344
1345 /*
1346  * Check that the name
1347  *  a) is in valid memory.
1348  *  b) is shorter than 2^16 bytes, so it can fit in a 9P string field.
1349  *  c) contains no frogs.
1350  * The first byte is known to be addressible by the requester, so the
1351  * routine works for kernel and user memory both.
1352  * The parameter slashok flags whether a slash character is an error
1353  * or a valid character.
1354  */
1355 void
1356 validname(char *aname, int slashok)
1357 {
1358         char *ename, *name;
1359         int c;
1360
1361         name = aname;
1362         ename = memchr(name, 0, (1<<16));
1363
1364         if(ename==NULL || ename-name>=(1<<16))
1365                 error("name too long");
1366
1367         while(*name){
1368                 /* all characters above '~' are ok */
1369                 c = *( uint8_t *)name;
1370 #if 0       
1371                 if(c >= Runeself)
1372                         name += chartorune(&r, name);
1373 #endif
1374                 if(c >= 0x7f){
1375                         error("Akaros doesn't do UTF-8");
1376                 } else {
1377                         if(isfrog[c])
1378                                 if(!slashok || c!='/'){
1379                                         error("%s: %q", Ebadchar, aname);
1380                         }
1381                         name++;
1382                 }
1383         }
1384 }
1385
1386 void
1387 isdir(struct chan *c)
1388 {
1389         if(c->qid.type & QTDIR)
1390                 return;
1391         error(Enotdir);
1392 }
1393
1394 /*
1395  * This is necessary because there are many
1396  * pointers to the top of a given mount list:
1397  *
1398  *      - the mhead in the namespace hash table
1399  *      - the mhead in chans returned from findmount:
1400  *        used in namec and then by unionread.
1401  *      - the mhead in chans returned from createdir:
1402  *        used in the open/create race protect, which is gone.
1403  *
1404  * The RWlock in the Mhead protects the mount list it contains.
1405  * The mount list is deleted when we cunmount.
1406  * The RWlock ensures that nothing is using the mount list at that time.
1407  *
1408  * It is okay to replace c->mh with whatever you want as 
1409  * long as you are sure you have a unique reference to it.
1410  *
1411  * This comment might belong somewhere else.
1412  */
1413 void
1414 putmhead(struct mhead *m)
1415 {
1416         if (m)
1417                 kref_put(&m->ref);
1418 }