9ns: Fix issues with can_have_children
[akaros.git] / kern / src / ns / chan.c
1 /* Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
2  * Portions Copyright © 1997-1999 Vita Nuova Limited
3  * Portions Copyright © 2000-2007 Vita Nuova Holdings Limited
4  *                                (www.vitanuova.com)
5  * Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
6  *
7  * Modified for the Akaros operating system:
8  * Copyright (c) 2013-2014 The Regents of the University of California
9  * Copyright (c) 2013-2015 Google Inc.
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a copy
12  * of this software and associated documentation files (the "Software"), to deal
13  * in the Software without restriction, including without limitation the rights
14  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15  * copies of the Software, and to permit persons to whom the Software is
16  * furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included in
19  * all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
24  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27  * SOFTWARE. */
28
29 #include <slab.h>
30 #include <kmalloc.h>
31 #include <kref.h>
32 #include <string.h>
33 #include <stdio.h>
34 #include <assert.h>
35 #include <error.h>
36 #include <cpio.h>
37 #include <pmap.h>
38 #include <smp.h>
39 #include <syscall.h>
40
41 struct chan *kern_slash;
42
43 char *channame(struct chan *c)
44 {       /* DEBUGGING */
45         if (c == NULL)
46                 return "<NULL chan>";
47         if (c->name == NULL)
48                 return "<NULL name>";
49         if (c->name->s == NULL)
50                 return "<NULL name.s>";
51         return c->name->s;
52 }
53
54 enum {
55         CNAMESLOP = 20
56 };
57
58 struct {
59         spinlock_t lock;
60         int fid;
61         struct chan *free;
62         struct chan *list;
63 } chanalloc;
64
65 typedef struct Elemlist Elemlist;
66
67 struct Elemlist {
68         char *name;                                     /* copy of name, so '/' can be overwritten */
69         int ARRAY_SIZEs;
70         char **elems;
71         int *off;
72         int mustbedir;
73 };
74
75 struct walk_helper {
76         bool can_mount;
77         bool no_follow;
78         unsigned int nr_loops;
79 };
80 #define WALK_MAX_NR_LOOPS 8
81
82 static struct chan *walk_symlink(struct chan *symlink, struct walk_helper *wh,
83                                  unsigned int nr_names_left);
84
85 #define SEP(c) ((c) == 0 || (c) == '/')
86 void cleancname(struct cname *);
87
88 int isdotdot(char *p)
89 {
90         return p[0] == '.' && p[1] == '.' && p[2] == '\0';
91 }
92
93 int emptystr(char *s)
94 {
95         if (s == NULL)
96                 return 1;
97         if (s[0] == '\0')
98                 return 1;
99         return 0;
100 }
101
102 /*
103  * Atomically replace *p with copy of s
104  */
105 void kstrdup(char **p, char *s)
106 {
107         int n;
108         char *t, *prev;
109
110         n = strlen(s) + 1;
111         /* if it's a user, we can wait for memory; if not, something's very wrong */
112         if (current) {
113                 t = kzmalloc(n, 0);
114         } else {
115                 t = kzmalloc(n, 0);
116                 if (t == NULL)
117                         panic("kstrdup: no memory");
118         }
119         memmove(t, s, n);
120         prev = *p;
121         *p = t;
122         kfree(prev);
123 }
124
125 void chandevreset(void)
126 {
127         int i;
128
129         for (i = 0; &devtab[i] < __devtabend; i++) {
130                 if (devtab[i].reset)
131                         devtab[i].reset();
132         }
133 }
134
135 void chandevinit(void)
136 {
137         int i;
138
139         for (i = 0; &devtab[i] < __devtabend; i++) {
140                 if (devtab[i].init)
141                         devtab[i].init();
142         }
143 }
144
145 void chandevshutdown(void)
146 {
147         int i;
148
149         /* shutdown in reverse order */
150         for (i = 0; &devtab[i] < __devtabend; i++) ;
151         for (i--; i >= 0; i--) {
152                 if (devtab[i].shutdown)
153                         devtab[i].shutdown();
154         }
155 }
156
157 static void chan_release(struct kref *kref)
158 {
159         struct chan *c = container_of(kref, struct chan, ref);
160         ERRSTACK(1);
161
162         /* We can be called from RCU callbacks, but close methods can block.  In
163          * those cases, we need to defer our work to a kernel message. */
164         if (in_rcu_cb_ctx(this_pcpui_ptr())) {
165                 run_as_rkm(chan_release, kref);
166                 return;
167         }
168         /* this style discards the error from close().  picture it as
169          * if (waserror()) { } else { close(); } chanfree_no_matter_what();  */
170         if (!waserror()) {
171                 printd("releasing chan %p, type %d\n", c, c->type);
172                 /* -1 means there is no dev yet.  wants a noop for close() */
173                 if (c->type != -1)
174                         devtab[c->type].close(c);
175         }
176         /* need to poperror regardless of whether we error'd or not */
177         poperror();
178         /* and chan free no matter what */
179         chanfree(c);
180 }
181
182 struct chan *newchan(void)
183 {
184         struct chan *c;
185
186         spin_lock(&(&chanalloc)->lock);
187         c = chanalloc.free;
188         if (c != 0)
189                 chanalloc.free = c->next;
190         spin_unlock(&(&chanalloc)->lock);
191
192         if (c == NULL) {
193                 c = kzmalloc(sizeof(struct chan), 0);
194                 spin_lock(&(&chanalloc)->lock);
195                 c->fid = ++chanalloc.fid;
196                 c->link = chanalloc.list;
197                 chanalloc.list = c;
198                 spin_unlock(&(&chanalloc)->lock);
199                 spinlock_init(&c->lock);
200                 qlock_init(&c->umqlock);
201         }
202
203         /* if you get an error before associating with a dev, cclose skips calling
204          * the dev's close */
205         c->type = -1;
206         c->flag = 0;
207         kref_init(&c->ref, chan_release, 1);
208         c->dev = 0;
209         c->offset = 0;
210         c->iounit = 0;
211         c->umh = 0;
212         c->uri = 0;
213         c->dri = 0;
214         c->aux = 0;
215         c->mchan = 0;
216         c->mcp = 0;
217         c->mux = 0;
218         c->mqid.path = 0;
219         c->mqid.vers = 0;
220         c->mqid.type = 0;
221         c->name = 0;
222         c->buf = NULL;
223         c->mountpoint = NULL;
224         return c;
225 }
226
227 static void __cname_release(struct kref *kref)
228 {
229         struct cname *n = container_of(kref, struct cname, ref);
230         kfree(n->s);
231         kfree(n);
232 }
233
234 struct cname *newcname(char *s)
235 {
236         struct cname *n;
237         int i;
238
239         n = kzmalloc(sizeof(*n), 0);
240         i = strlen(s);
241         n->len = i;
242         n->alen = i + CNAMESLOP;
243         n->s = kzmalloc(n->alen, 0);
244         memmove(n->s, s, i + 1);
245         kref_init(&n->ref, __cname_release, 1);
246         return n;
247 }
248
249 void cnameclose(struct cname *n)
250 {
251         if (n == NULL)
252                 return;
253         kref_put(&n->ref);
254 }
255
256 struct cname *addelem(struct cname *n, char *s)
257 {
258         int i, a;
259         char *t;
260         struct cname *new;
261
262         if (s[0] == '.' && s[1] == '\0')
263                 return n;
264
265         if (kref_refcnt(&n->ref) > 1) {
266                 /* copy on write */
267                 new = newcname(n->s);
268                 cnameclose(n);
269                 n = new;
270         }
271
272         i = strlen(s);
273         if (n->len + 1 + i + 1 > n->alen) {
274                 a = n->len + 1 + i + 1 + CNAMESLOP;
275                 t = kzmalloc(a, 0);
276                 memmove(t, n->s, n->len + 1);
277                 kfree(n->s);
278                 n->s = t;
279                 n->alen = a;
280         }
281         if (n->len > 0 && n->s[n->len - 1] != '/' && s[0] != '/')       /* don't insert extra slash if one is present */
282                 n->s[n->len++] = '/';
283         memmove(n->s + n->len, s, i + 1);
284         n->len += i;
285         if (isdotdot(s))
286                 cleancname(n);
287         return n;
288 }
289
290 void chanfree(struct chan *c)
291 {
292         c->flag = CFREE;
293
294         if (c->umh != NULL) {
295                 putmhead(c->umh);
296                 c->umh = NULL;
297         }
298         if (c->umc != NULL) {
299                 cclose(c->umc);
300                 c->umc = NULL;
301         }
302         if (c->mux != NULL) {
303                 //
304                 muxclose(c->mux);
305                 c->mux = NULL;
306         }
307         if (c->mchan != NULL) {
308                 cclose(c->mchan);
309                 c->mchan = NULL;
310         }
311
312         cnameclose(c->name);
313         if (c->buf)
314                 kfree(c->buf);
315         c->buf = NULL;
316         c->bufused = 0;
317         c->ateof = 0;
318
319         spin_lock(&(&chanalloc)->lock);
320         c->next = chanalloc.free;
321         chanalloc.free = c;
322         spin_unlock(&(&chanalloc)->lock);
323 }
324
325 void cclose(struct chan *c)
326 {
327         if (c == 0)
328                 return;
329
330         if (c->flag & CFREE)
331                 panic("cclose %p", getcallerpc(&c));
332
333         kref_put(&c->ref);
334 }
335
336 /* convenience wrapper for interposition.  if you do use this, don't forget
337  * about the kref_get_not_zero in plan9setup() */
338 void chan_incref(struct chan *c)
339 {
340         kref_get(&c->ref, 1);
341 }
342
343 /*
344  * Make sure we have the only copy of c.  (Copy on write.)
345  */
346 struct chan *cunique(struct chan *c)
347 {
348         struct chan *nc;
349
350         if (kref_refcnt(&c->ref) != 1) {
351                 nc = cclone(c);
352                 cclose(c);
353                 c = nc;
354         }
355
356         return c;
357 }
358
359 int eqqid(struct qid a, struct qid b)
360 {
361         return a.path == b.path && a.vers == b.vers;
362 }
363
364 int eqchan(struct chan *a, struct chan *b, int pathonly)
365 {
366         if (a->qid.path != b->qid.path)
367                 return 0;
368         if (!pathonly && a->qid.vers != b->qid.vers)
369                 return 0;
370         if (a->type != b->type)
371                 return 0;
372         if (a->dev != b->dev)
373                 return 0;
374         return 1;
375 }
376
377 int eqchantdqid(struct chan *a, int type, int dev, struct qid qid, int pathonly)
378 {
379         if (a->qid.path != qid.path)
380                 return 0;
381         if (!pathonly && a->qid.vers != qid.vers)
382                 return 0;
383         if (a->type != type)
384                 return 0;
385         if (a->dev != dev)
386                 return 0;
387         return 1;
388 }
389
390 static void mh_release(struct kref *kref)
391 {
392         struct mhead *mh = container_of(kref, struct mhead, ref);
393         mh->mount = (struct mount *)0xCafeBeef;
394         kfree(mh);
395 }
396
397 struct mhead *newmhead(struct chan *from)
398 {
399         struct mhead *mh;
400
401         mh = kzmalloc(sizeof(struct mhead), 0);
402         kref_init(&mh->ref, mh_release, 1);
403         rwinit(&mh->lock);
404         mh->from = from;
405         chan_incref(from);
406
407 /*
408         n = from->name->len;
409         if(n >= sizeof(mh->fromname))
410                 n = sizeof(mh->fromname)-1;
411         memmove(mh->fromname, from->name->s, n);
412         mh->fromname[n] = 0;
413 */
414         return mh;
415 }
416
417 int cmount(struct chan *new, struct chan *old, int flag, char *spec)
418 {
419         ERRSTACK(1);
420         struct pgrp *pg;
421         int order, flg;
422         struct mhead *m, **l, *mh;
423         struct mount *nm, *f, *um, **h;
424
425         /* Can bind anything onto a symlink's name.  Otherwise, both the old and the
426          * new must agree on whether or not it is a directory. */
427         if (!(old->qid.type & QTSYMLINK) &&
428             (QTDIR & (old->qid.type ^ new->qid.type)))
429                 error(EINVAL, ERROR_FIXME);
430
431         if (old->umh)
432                 printd("cmount old extra umh\n");
433
434         order = flag & MORDER;
435
436         if ((old->qid.type & QTDIR) == 0 && order != MREPL)
437                 error(EINVAL, ERROR_FIXME);
438
439         mh = new->umh;
440
441         /*
442          * Not allowed to bind when the old directory
443          * is itself a union.  (Maybe it should be allowed, but I don't see
444          * what the semantics would be.)
445          *
446          * We need to check mh->mount->next to tell unions apart from
447          * simple mount points, so that things like
448          *  mount -c fd /root
449          *  bind -c /root /
450          * work.  The check of mount->mflag catches things like
451          *  mount fd /root
452          *  bind -c /root /
453          *
454          * This is far more complicated than it should be, but I don't
455          * see an easier way at the moment.     -rsc
456          */
457         if ((flag & MCREATE) && mh && mh->mount
458                 && (mh->mount->next || !(mh->mount->mflag & MCREATE)))
459                 error(EEXIST, ERROR_FIXME);
460
461         pg = current->pgrp;
462         wlock(&pg->ns);
463
464         l = &MOUNTH(pg, old->qid);
465         for (m = *l; m; m = m->hash) {
466                 if (eqchan(m->from, old, 1))
467                         break;
468                 l = &m->hash;
469         }
470
471         if (m == NULL) {
472                 /*
473                  *  nothing mounted here yet.  create a mount
474                  *  head and add to the hash table.
475                  */
476                 m = newmhead(old);
477                 *l = m;
478
479                 /*
480                  *  if this is a union mount, add the old
481                  *  node to the mount chain.
482                  */
483                 if (order != MREPL)
484                         m->mount = newmount(m, old, 0, 0);
485         }
486         wlock(&m->lock);
487         if (waserror()) {
488                 wunlock(&m->lock);
489                 nexterror();
490         }
491         wunlock(&pg->ns);
492
493         nm = newmount(m, new, flag, spec);
494         if (mh != NULL && mh->mount != NULL) {
495                 /*
496                  *  copy a union when binding it onto a directory
497                  */
498                 flg = order;
499                 if (order == MREPL)
500                         flg = MAFTER;
501                 h = &nm->next;
502                 um = mh->mount;
503                 for (um = um->next; um; um = um->next) {
504                         f = newmount(m, um->to, flg, um->spec);
505                         *h = f;
506                         h = &f->next;
507                 }
508         }
509
510         if (m->mount && order == MREPL) {
511                 mountfree(m->mount);
512                 m->mount = 0;
513         }
514
515         if (flag & MCREATE)
516                 nm->mflag |= MCREATE;
517
518         if (m->mount && order == MAFTER) {
519                 for (f = m->mount; f->next; f = f->next) ;
520                 f->next = nm;
521         } else {
522                 for (f = nm; f->next; f = f->next) ;
523                 f->next = m->mount;
524                 m->mount = nm;
525         }
526
527         wunlock(&m->lock);
528         poperror();
529         return nm->mountid;
530 }
531
532 void cunmount(struct chan *mnt, struct chan *mounted)
533 {
534         struct pgrp *pg;
535         struct mhead *m, **l;
536         struct mount *f, **p;
537
538         if (mnt->umh)   /* should not happen */
539                 printd("cunmount newp extra umh %p has %p\n", mnt, mnt->umh);
540
541         /*
542          * It _can_ happen that mounted->umh is non-NULL,
543          * because mounted is the result of namec(Aopen)
544          * (see sysfile.c:/^sysunmount).
545          * If we open a union directory, it will have a umh.
546          * Although surprising, this is okay, since the
547          * cclose will take care of freeing the umh.
548          */
549
550         pg = current->pgrp;
551         wlock(&pg->ns);
552
553         l = &MOUNTH(pg, mnt->qid);
554         for (m = *l; m; m = m->hash) {
555                 if (eqchan(m->from, mnt, 1))
556                         break;
557                 l = &m->hash;
558         }
559
560         if (m == 0) {
561                 wunlock(&pg->ns);
562                 error(ENOENT, ERROR_FIXME);
563         }
564
565         wlock(&m->lock);
566         if (mounted == 0) {
567                 *l = m->hash;
568                 wunlock(&pg->ns);
569                 mountfree(m->mount);
570                 m->mount = NULL;
571                 cclose(m->from);
572                 wunlock(&m->lock);
573                 putmhead(m);
574                 return;
575         }
576
577         p = &m->mount;
578         for (f = *p; f; f = f->next) {
579                 /* BUG: Needs to be 2 pass */
580                 if (eqchan(f->to, mounted, 1) ||
581                         (f->to->mchan && eqchan(f->to->mchan, mounted, 1))) {
582                         *p = f->next;
583                         f->next = 0;
584                         mountfree(f);
585                         if (m->mount == NULL) {
586                                 *l = m->hash;
587                                 cclose(m->from);
588                                 wunlock(&m->lock);
589                                 wunlock(&pg->ns);
590                                 putmhead(m);
591                                 return;
592                         }
593                         wunlock(&m->lock);
594                         wunlock(&pg->ns);
595                         return;
596                 }
597                 p = &f->next;
598         }
599         wunlock(&m->lock);
600         wunlock(&pg->ns);
601         error(ENOENT, ERROR_FIXME);
602 }
603
604 struct chan *cclone(struct chan *c)
605 {
606         struct chan *nc;
607         struct walkqid *wq;
608
609         wq = devtab[c->type].walk(c, NULL, NULL, 0);
610         if (wq == NULL)
611                 error(EFAIL, "clone failed");
612         nc = wq->clone;
613         kfree(wq);
614         nc->name = c->name;
615         if (c->name)
616                 kref_get(&c->name->ref, 1);
617         return nc;
618 }
619
620 /* Helper: is something mounted on the chan? */
621 static bool is_mount_point(struct chan *c)
622 {
623         struct pgrp *pg;
624         struct mhead *m;
625         int type = c->type;
626         int dev = c->dev;
627         struct qid qid = c->qid;
628
629         if (!current)
630                 return false;
631         pg = current->pgrp;
632         rlock(&pg->ns);
633         for (m = MOUNTH(pg, qid); m; m = m->hash) {
634                 rlock(&m->lock);
635                 if (!m->from) {
636                         runlock(&m->lock);
637                         continue;
638                 }
639                 if (eqchantdqid(m->from, type, dev, qid, 1)) {
640                         runlock(&m->lock);
641                         runlock(&pg->ns);
642                         return true;
643                 }
644                 runlock(&m->lock);
645         }
646         runlock(&pg->ns);
647         return false;
648 }
649
650 int
651 findmount(struct chan **cp,
652                   struct mhead **mp, int type, int dev, struct qid qid)
653 {
654         struct pgrp *pg;
655         struct mhead *m;
656
657         if (!current)
658                 return 0;
659         pg = current->pgrp;
660         rlock(&pg->ns);
661         for (m = MOUNTH(pg, qid); m; m = m->hash) {
662                 rlock(&m->lock);
663                 if (m->from == NULL) {
664                         printd("m %p m->from 0\n", m);
665                         runlock(&m->lock);
666                         continue;
667                 }
668                 if (eqchantdqid(m->from, type, dev, qid, 1)) {
669                         runlock(&pg->ns);
670                         if (mp != NULL) {
671                                 kref_get(&m->ref, 1);
672                                 if (*mp != NULL)
673                                         putmhead(*mp);
674                                 *mp = m;
675                         }
676                         if (*cp != NULL)
677                                 cclose(*cp);
678                         chan_incref(m->mount->to);
679                         *cp = m->mount->to;
680                         runlock(&m->lock);
681                         return 1;
682                 }
683                 runlock(&m->lock);
684         }
685
686         runlock(&pg->ns);
687         return 0;
688 }
689
690 int domount(struct chan **cp, struct mhead **mp)
691 {
692         return findmount(cp, mp, (*cp)->type, (*cp)->dev, (*cp)->qid);
693 }
694
695 struct chan *undomount(struct chan *c, struct cname *name)
696 {
697         ERRSTACK(1);
698         struct chan *nc;
699         struct pgrp *pg;
700         struct mount *t;
701         struct mhead **h, **he, *f;
702
703         if (!current)
704                 return c;
705         pg = current->pgrp;
706         rlock(&pg->ns);
707         if (waserror()) {
708                 runlock(&pg->ns);
709                 nexterror();
710         }
711
712         he = &pg->mnthash[MNTHASH];
713         for (h = pg->mnthash; h < he; h++) {
714                 for (f = *h; f; f = f->hash) {
715                         if (strcmp(f->from->name->s, name->s) != 0)
716                                 continue;
717                         for (t = f->mount; t; t = t->next) {
718                                 if (eqchan(c, t->to, 1)) {
719                                         /*
720                                          * We want to come out on the left hand side of the mount
721                                          * point using the element of the union that we entered on.
722                                          * To do this, find the element that has a from name of
723                                          * c->name->s.
724                                          */
725                                         if (strcmp(t->head->from->name->s, name->s) != 0)
726                                                 continue;
727                                         nc = t->head->from;
728                                         chan_incref(nc);
729                                         cclose(c);
730                                         c = nc;
731                                         break;
732                                 }
733                         }
734                 }
735         }
736         poperror();
737         runlock(&pg->ns);
738         return c;
739 }
740
741 /*
742  * Either walks all the way or not at all.  No partial results in *cp.
743  * *nerror is the number of names to display in an error message.
744  */
745 int walk(struct chan **cp, char **names, int nnames, struct walk_helper *wh,
746          int *nerror)
747 {
748         int dev, dotdot, i, n, nhave, ntry, type;
749         struct chan *c, *nc, *lastmountpoint = NULL;
750         struct cname *cname;
751         struct mount *f;
752         struct mhead *mh, *nmh;
753         struct walkqid *wq;
754
755         c = *cp;
756         chan_incref(c);
757         cname = c->name;
758         kref_get(&cname->ref, 1);
759         mh = NULL;
760
761         /*
762          * While we haven't gotten all the way down the path:
763          *    1. step through a mount point, if any
764          *    2. send a walk request for initial dotdot or initial prefix without dotdot
765          *    3. move to the first mountpoint along the way.
766          *    4. repeat.
767          *
768          * An invariant is that each time through the loop, c is on the undomount
769          * side of the mount point, and c's name is cname.
770          */
771         for (nhave = 0; nhave < nnames; nhave += n) {
772                 /* We only allow symlink when they are first and it's .. (see below) */
773                 if ((c->qid.type & (QTDIR | QTSYMLINK)) == 0) {
774                         if (nerror)
775                                 *nerror = nhave;
776                         cnameclose(cname);
777                         cclose(c);
778                         set_error(ENOTDIR, ERROR_FIXME);
779                         if (mh != NULL)
780                                 putmhead(mh);
781                         return -1;
782                 }
783                 ntry = nnames - nhave;
784                 if (ntry > MAXWELEM)
785                         ntry = MAXWELEM;
786                 dotdot = 0;
787                 for (i = 0; i < ntry; i++) {
788                         if (isdotdot(names[nhave + i])) {
789                                 if (i == 0) {
790                                         dotdot = 1;
791                                         ntry = 1;
792                                 } else
793                                         ntry = i;
794                                 break;
795                         }
796                 }
797
798                 if (!dotdot && wh->can_mount)
799                         domount(&c, &mh);
800                 /* Bug - the only time we walk from a symlink should be during
801                  * walk_symlink, which should have given us a dotdot. */
802                 if ((c->qid.type & QTSYMLINK) && !dotdot)
803                         panic("Got a walk from a symlink that wasn't ..!");
804
805                 type = c->type;
806                 dev = c->dev;
807
808                 if ((wq = devtab[type].walk(c, NULL, names + nhave, ntry)) == NULL) {
809                         /* try a union mount, if any */
810                         if (mh && wh->can_mount) {
811                                 /*
812                                  * mh->mount == c, so start at mh->mount->next
813                                  */
814                                 rlock(&mh->lock);
815                                 for (f = mh->mount->next; f; f = f->next)
816                                         if ((wq =
817                                                  devtab[f->to->type].walk(f->to, NULL, names + nhave,
818                                                                                                   ntry)) != NULL)
819                                                 break;
820                                 runlock(&mh->lock);
821                                 if (f != NULL) {
822                                         type = f->to->type;
823                                         dev = f->to->dev;
824                                 }
825                         }
826                         if (wq == NULL) {
827                                 cclose(c);
828                                 cnameclose(cname);
829                                 if (nerror)
830                                         *nerror = nhave + 1;
831                                 if (mh != NULL)
832                                         putmhead(mh);
833                                 return -1;
834                         }
835                 }
836
837                 nmh = NULL;
838                 if (dotdot) {
839                         assert(wq->nqid == 1);
840                         assert(wq->clone != NULL);
841
842                         cname = addelem(cname, "..");
843                         nc = undomount(wq->clone, cname);
844                         n = 1;
845                 } else {
846                         nc = NULL;
847                         if (wh->can_mount)
848                                 for (i = 0; i < wq->nqid && i < ntry - 1; i++)
849                                         if (findmount(&nc, &nmh, type, dev, wq->qid[i]))
850                                                 break;
851                         if (nc == NULL) {       /* no mount points along path */
852                                 if (wq->clone == NULL) {
853                                         cclose(c);
854                                         cnameclose(cname);
855                                         if (wq->nqid == 0 || (wq->qid[wq->nqid - 1].type & QTDIR)) {
856                                                 if (nerror)
857                                                         *nerror = nhave + wq->nqid + 1;
858                                                 set_error(ENOENT, "walk failed");
859                                         } else {
860                                                 if (nerror)
861                                                         *nerror = nhave + wq->nqid;
862                                                 set_error(ENOTDIR, "walk failed");
863                                         }
864                                         kfree(wq);
865                                         if (mh != NULL)
866                                                 putmhead(mh);
867                                         return -1;
868                                 }
869                                 n = wq->nqid;
870                                 if (wq->clone->qid.type & QTSYMLINK) {
871                                         nc = walk_symlink(wq->clone, wh, nnames - nhave - n);
872                                         if (!nc) {
873                                                 /* walk_symlink() set error.  This seems to be the
874                                                  * standard walk() error-cleanup. */
875                                                 if (nerror)
876                                                         *nerror = nhave + wq->nqid;
877                                                 cclose(c);
878                                                 cclose(wq->clone);
879                                                 cnameclose(cname);
880                                                 kfree(wq);
881                                                 if (mh != NULL)
882                                                         putmhead(mh);
883                                                 return -1;
884                                         }
885                                 } else {
886                                         nc = wq->clone;
887                                 }
888                         } else {        /* stopped early, at a mount point */
889                                 if (wq->clone != NULL) {
890                                         cclose(wq->clone);
891                                         wq->clone = NULL;
892                                 }
893                                 lastmountpoint = nc;
894                                 n = i + 1;
895                         }
896                         for (i = 0; i < n; i++)
897                                 cname = addelem(cname, names[nhave + i]);
898                 }
899                 cclose(c);
900                 c = nc;
901                 putmhead(mh);
902                 mh = nmh;
903                 kfree(wq);
904         }
905
906         putmhead(mh);
907
908         c = cunique(c);
909
910         if (c->umh != NULL) {   //BUG
911                 printd("walk umh\n");
912                 putmhead(c->umh);
913                 c->umh = NULL;
914         }
915
916         cnameclose(c->name);
917         c->name = cname;
918         c->mountpoint = lastmountpoint;
919
920         cclose(*cp);
921         *cp = c;
922         if (nerror)
923                 *nerror = 0;
924         return 0;
925 }
926
927 /*
928  * c is a mounted non-creatable directory.  find a creatable one.
929  */
930 struct chan *createdir(struct chan *c, struct mhead *m)
931 {
932         ERRSTACK(1);
933         struct chan *nc;
934         struct mount *f;
935
936         rlock(&m->lock);
937         if (waserror()) {
938                 runlock(&m->lock);
939                 nexterror();
940         }
941         for (f = m->mount; f; f = f->next) {
942                 if (f->mflag & MCREATE) {
943                         nc = cclone(f->to);
944                         runlock(&m->lock);
945                         poperror();
946                         cclose(c);
947                         return nc;
948                 }
949         }
950         error(EPERM, ERROR_FIXME);
951         poperror();
952         return 0;
953 }
954
955 /*
956  * In place, rewrite name to compress multiple /, eliminate ., and process ..
957  */
958 void cleancname(struct cname *n)
959 {
960         char *p;
961
962         if (n->s[0] == '#') {
963                 p = strchr(n->s, '/');
964                 if (p == NULL)
965                         return;
966                 cleanname(p);
967
968                 /*
969                  * The correct name is #i rather than #i/,
970                  * but the correct name of #/ is #/.
971                  */
972                 if (strcmp(p, "/") == 0 && n->s[1] != '/')
973                         *p = '\0';
974         } else
975                 cleanname(n->s);
976         n->len = strlen(n->s);
977 }
978
979 static void growparse(Elemlist * e)
980 {
981         char **new;
982         int *inew;
983         enum { Delta = 8 };
984
985         if (e->ARRAY_SIZEs % Delta == 0) {
986                 new = kzmalloc((e->ARRAY_SIZEs + Delta) * sizeof(char *), 0);
987                 memmove(new, e->elems, e->ARRAY_SIZEs * sizeof(char *));
988                 kfree(e->elems);
989                 e->elems = new;
990                 inew = kzmalloc((e->ARRAY_SIZEs + Delta + 1) * sizeof(int), 0);
991                 memmove(inew, e->off, e->ARRAY_SIZEs * sizeof(int));
992                 kfree(e->off);
993                 e->off = inew;
994         }
995 }
996
997 /*
998  * The name is known to be valid.
999  * Copy the name so slashes can be overwritten.
1000  * An empty string will set ARRAY_SIZE=0.
1001  * A path ending in / or /. or /.//./ etc. will have
1002  * e.mustbedir = 1, so that we correctly
1003  * reject, e.g., "/adm/users/." when /adm/users is a file
1004  * rather than a directory.
1005  */
1006 static void parsename(char *name, Elemlist * e)
1007 {
1008         char *slash;
1009
1010         kstrdup(&e->name, name);
1011         name = e->name;
1012         e->ARRAY_SIZEs = 0;
1013         e->elems = NULL;
1014         e->off = kzmalloc(sizeof(int), 0);
1015         e->off[0] = skipslash(name) - name;
1016         for (;;) {
1017                 name = skipslash(name);
1018                 if (*name == '\0') {
1019                         e->mustbedir = 1;
1020                         break;
1021                 }
1022                 growparse(e);
1023
1024                 e->elems[e->ARRAY_SIZEs++] = name;
1025                 /* we may want to do this again some day
1026                    slash = utfrune(name, '/');
1027                  */
1028                 slash = strchr(name, '/');
1029                 if (slash == NULL) {
1030                         e->off[e->ARRAY_SIZEs] = name + strlen(name) - e->name;
1031                         e->mustbedir = 0;
1032                         break;
1033                 }
1034                 e->off[e->ARRAY_SIZEs] = slash - e->name;
1035                 *slash++ = '\0';
1036                 name = slash;
1037         }
1038 }
1039
1040 void *memrchr(void *va, int c, long n)
1041 {
1042         uint8_t *a, *e;
1043
1044         a = va;
1045         for (e = a + n - 1; e > a; e--)
1046                 if (*e == c)
1047                         return e;
1048         return NULL;
1049 }
1050
1051 /*
1052  * Turn a name into a channel.
1053  * &name[0] is known to be a valid address.  It may be a kernel address.
1054  *
1055  * Opening with amode Aopen, Acreate, or Aremove guarantees
1056  * that the result will be the only reference to that particular fid.
1057  * This is necessary since we might pass the result to
1058  * devtab[].remove().
1059  *
1060  * Opening Atodir, Amount, or Aaccess does not guarantee this.
1061  *
1062  * Opening Aaccess can, under certain conditions, return a
1063  * correct Chan* but with an incorrect struct cname attached.
1064  * Since the functions that open Aaccess (sysstat, syswstat, sys_stat)
1065  * do not use the struct cname*, this avoids an unnecessary clone.
1066  *
1067  * The classic namec() is broken into a front end to get the starting point and
1068  * a __namec_from, which does the guts of the lookup.  */
1069 static struct chan *__namec_from(struct chan *c, char *aname, int amode,
1070                                  int omode, uint32_t perm,
1071                                  struct walk_helper *wh, void *ext)
1072 {
1073         ERRSTACK(2);
1074         int len, npath;
1075         struct chan *cnew, *renamee;
1076         struct cname *cname;
1077         Elemlist e;
1078         struct mhead *m;
1079         char tmperrbuf[ERRMAX];
1080         int saved_errno;
1081         // Rune r;
1082
1083         static_assert(!(CINTERNAL_FLAGS & CEXTERNAL_FLAGS));
1084
1085         e.name = NULL;
1086         e.elems = NULL;
1087         e.off = NULL;
1088         e.ARRAY_SIZEs = 0;
1089         if (waserror()) {
1090                 cclose(c);
1091                 kfree(e.name);
1092                 kfree(e.elems);
1093                 kfree(e.off);
1094                 //dumpmount();
1095                 nexterror();
1096         }
1097
1098         /*
1099          * Build a list of elements in the path.
1100          */
1101         parsename(aname, &e);
1102
1103         if (e.mustbedir)
1104                 omode &= ~O_NOFOLLOW;
1105
1106         switch (amode) {
1107         case Acreate:
1108                 /* perm must have DMDIR if last element is / or /. */
1109                 if (e.mustbedir && !(perm & DMDIR)) {
1110                         npath = e.ARRAY_SIZEs;
1111                         error(EINVAL, "create without DMDIR");
1112                 }
1113                 /* don't try to walk the last path element just yet. */
1114                 if (e.ARRAY_SIZEs == 0)
1115                         error(EEXIST, ERROR_FIXME);
1116                 e.ARRAY_SIZEs--;
1117                 /* We're dropping the last element, which O_NOFOLLOW applied to.  Not
1118                  * sure if there are any legit reasons to have O_NOFOLLOW with create.*/
1119                 omode &= ~O_NOFOLLOW;
1120                 break;
1121         case Arename:
1122                 if (e.ARRAY_SIZEs == 0)
1123                         error(EINVAL, "rename needs at least one name");
1124                 e.ARRAY_SIZEs--;
1125                 omode &= ~O_NOFOLLOW;
1126                 break;
1127         /* the difference for stat and lstat (Aaccess) are handled in sysfile.c */
1128         case Abind:
1129         case Amount:
1130         case Aremove:
1131                 omode |= O_NOFOLLOW;
1132                 break;
1133         }
1134
1135         if (omode & O_NOFOLLOW)
1136                 wh->no_follow = true;
1137
1138         if (walk(&c, e.elems, e.ARRAY_SIZEs, wh, &npath) < 0) {
1139                 if (npath < 0 || npath > e.ARRAY_SIZEs) {
1140                         printd("namec %s walk error npath=%d\n", aname, npath);
1141                         error(EFAIL, "walk failed");
1142                 }
1143                 /* Old plan 9 errors would jump here for the magic error parsing. */
1144 NameError:
1145                 if (current_errstr()[0]) {
1146                         /* errstr is set, we'll just stick with it and error out */
1147                         error_jmp();
1148                 } else {
1149                         error(EFAIL, "Name to chan lookup failed");
1150                 }
1151                 /* brho: skipping the namec custom error string business, since it hides
1152                  * the underlying failure.  implement this if you want the old stuff. */
1153 #if 0
1154                 strlcpy(tmperrbuf, current->errstr, sizeof(tmperrbuf));
1155                 len = prefix + e.off[npath]; // prefix was name - aname, the start pt
1156                 if (len < ERRMAX / 3 || (name = memrchr(aname, '/', len)) == NULL
1157                         || name == aname)
1158                         snprintf(get_cur_genbuf(), sizeof current->genbuf, "%.*s", len,
1159                                          aname);
1160                 else
1161                         snprintf(get_cur_genbuf(), sizeof current->genbuf, "...%.*s",
1162                                          (int)(len - (name - aname)), name);
1163                 snprintf(current->errstr, ERRMAX, "%#q %s", get_cur_genbuf(),
1164                                  tmperrbuf);
1165 #endif
1166         }
1167
1168         if (e.mustbedir && !(c->qid.type & QTDIR)) {
1169                 npath = e.ARRAY_SIZEs;
1170                 error(ENOTDIR, "not a dir, but mustbedir.  trailing slash?");
1171         }
1172
1173         if ((amode == Aopen) && (omode & O_EXEC) && (c->qid.type & QTDIR)) {
1174                 npath = e.ARRAY_SIZEs;
1175                 error(EFAIL, "cannot exec directory");
1176         }
1177
1178         switch (amode) {
1179                 case Aaccess:
1180                         if (wh->can_mount)
1181                                 domount(&c, NULL);
1182                         break;
1183
1184                 case Abind:
1185                         m = NULL;
1186                         if (wh->can_mount)
1187                                 domount(&c, &m);
1188                         if (c->umh != NULL)
1189                                 putmhead(c->umh);
1190                         c->umh = m;
1191                         break;
1192
1193                 case Aremove:
1194                 case Aopen:
1195 Open:
1196                         /* save the name; domount might change c */
1197                         cname = c->name;
1198                         kref_get(&cname->ref, 1);
1199                         m = NULL;
1200                         if (wh->can_mount)
1201                                 domount(&c, &m);
1202
1203                         /* our own copy to open or remove */
1204                         c = cunique(c);
1205
1206                         /* now it's our copy anyway, we can put the name back */
1207                         cnameclose(c->name);
1208                         c->name = cname;
1209
1210                         switch (amode) {
1211                                 case Aremove:
1212                                         putmhead(m);
1213                                         break;
1214
1215                                 case Aopen:
1216                                 case Acreate:
1217                                         if (c->umh != NULL) {
1218                                                 printd("cunique umh\n");
1219                                                 putmhead(c->umh);
1220                                                 c->umh = NULL;
1221                                         }
1222
1223                                         /* only save the mount head if it's a multiple element union */
1224                                         if (m && m->mount && m->mount->next)
1225                                                 c->umh = m;
1226                                         else
1227                                                 putmhead(m);
1228                                         /* here is where convert omode/vfs flags to c->flags.
1229                                          * careful, O_CLOEXEC and O_REMCLO are in there.  might need
1230                                          * to change that. */
1231                                         c->flag |= omode & CEXTERNAL_FLAGS;
1232                                         c = devtab[c->type].open(c,
1233                                                                  omode & ~O_CLOEXEC);
1234                                         /* if you get this from a dev, in the dev's open, you are
1235                                          * probably saving mode directly, without passing it through
1236                                          * openmode. */
1237                                         if (c->mode & O_TRUNC)
1238                                                 error(EFAIL, "Device %s open failed to clear O_TRUNC",
1239                                                       devtab[c->type].name);
1240                                         break;
1241                         }
1242                         break;
1243
1244                 case Atodir:
1245                         /*
1246                          * Directories (e.g. for cd) are left before the mount point,
1247                          * so one may mount on / or . and see the effect.
1248                          */
1249                         if (!(c->qid.type & QTDIR))
1250                                 error(ENOTDIR, ERROR_FIXME);
1251                         break;
1252
1253                 case Amount:
1254                         /*
1255                          * When mounting on an already mounted upon directory,
1256                          * one wants subsequent mounts to be attached to the
1257                          * original directory, not the replacement.  Don't domount.
1258                          */
1259                         break;
1260
1261                 case Arename:
1262                         /* We already walked to the parent of new_path, which is in c.
1263                          * We're a lot like create here - need to find mounts, etc.  On the
1264                          * way out, we putmhead if we have an m, and clean up our chans.  On
1265                          * success, c becomes cnew (thus close the old c).  On failure, we
1266                          * just close cnew. */
1267                         e.ARRAY_SIZEs++;
1268                         m = NULL;
1269                         cnew = NULL;
1270                         if (waserror()) {
1271                                 /* rename or createdir failed */
1272                                 cclose(cnew);
1273                                 if (m)
1274                                         putmhead(m);
1275                                 nexterror();    /* safe since we're in a waserror() */
1276                         }
1277                         if (wh->can_mount && findmount(&cnew, &m, c->type, c->dev,
1278                                                        c->qid)) {
1279                                 cnew = createdir(cnew, m);
1280                         } else {
1281                                 cnew = c;
1282                                 chan_incref(cnew);
1283                         }
1284                         cnew = cunique(cnew);
1285                         cnameclose(cnew->name);
1286                         cnew->name = c->name;
1287                         kref_get(&cnew->name->ref, 1);
1288                         /* At this point, we have our new_path parent chan (cnew) and the
1289                          * renamee chan */
1290                         renamee = ext;
1291                         if (cnew->type != renamee->type)
1292                                 error(EXDEV, "can't rename across device types");
1293
1294                         devtab[cnew->type].rename(renamee, cnew,
1295                                                   e.elems[e.ARRAY_SIZEs - 1], 0);
1296                         poperror();
1297
1298                         if (m)
1299                                 putmhead(m);
1300                         cclose(c);
1301                         c = cnew;
1302                         c->name = addelem(c->name, e.elems[e.ARRAY_SIZEs - 1]);
1303                         break;
1304
1305                 case Acreate:
1306                         /*
1307                          * We've already walked all but the last element.
1308                          * If the last exists, try to open it OTRUNC.
1309                          * If omode&OEXCL is set, just give up.
1310                          */
1311                         e.ARRAY_SIZEs++;
1312                         if (walk(&c, e.elems + e.ARRAY_SIZEs - 1, 1, wh, NULL) == 0) {
1313                                 if (omode & O_EXCL)
1314                                         error(EEXIST, ERROR_FIXME);
1315                                 omode |= O_TRUNC;
1316                                 goto Open;
1317                         }
1318
1319                         /*
1320                          * The semantics of the create(2) system call are that if the
1321                          * file exists and can be written, it is to be opened with truncation.
1322                          * On the other hand, the create(5) message fails if the file exists.
1323                          * If we get two create(2) calls happening simultaneously,
1324                          * they might both get here and send create(5) messages, but only
1325                          * one of the messages will succeed.  To provide the expected create(2)
1326                          * semantics, the call with the failed message needs to try the above
1327                          * walk again, opening for truncation.  This correctly solves the
1328                          * create/create race, in the sense that any observable outcome can
1329                          * be explained as one happening before the other.
1330                          * The create/create race is quite common.  For example, it happens
1331                          * when two rc subshells simultaneously update the same
1332                          * environment variable.
1333                          *
1334                          * The implementation still admits a create/create/remove race:
1335                          * (A) walk to file, fails
1336                          * (B) walk to file, fails
1337                          * (A) create file, succeeds, returns
1338                          * (B) create file, fails
1339                          * (A) remove file, succeeds, returns
1340                          * (B) walk to file, return failure.
1341                          *
1342                          * This is hardly as common as the create/create race, and is really
1343                          * not too much worse than what might happen if (B) got a hold of a
1344                          * file descriptor and then the file was removed -- either way (B) can't do
1345                          * anything with the result of the create call.  So we don't care about this race.
1346                          *
1347                          * Applications that care about more fine-grained decision of the races
1348                          * can use the OEXCL flag to get at the underlying create(5) semantics;
1349                          * by default we provide the common case.
1350                          *
1351                          * We need to stay behind the mount point in case we
1352                          * need to do the first walk again (should the create fail).
1353                          *
1354                          * We also need to cross the mount point and find the directory
1355                          * in the union in which we should be creating.
1356                          *
1357                          * The channel staying behind is c, the one moving forward is cnew.
1358                          */
1359                         m = NULL;
1360                         cnew = NULL;    /* is this assignment necessary? */
1361                         /* discard error */
1362                         if (!waserror()) {      /* try create */
1363                                 if (wh->can_mount && findmount(&cnew, &m, c->type, c->dev,
1364                                                                c->qid))
1365                                         cnew = createdir(cnew, m);
1366                                 else {
1367                                         cnew = c;
1368                                         chan_incref(cnew);
1369                                 }
1370
1371                                 /*
1372                                  * We need our own copy of the Chan because we're
1373                                  * about to send a create, which will move it.  Once we have
1374                                  * our own copy, we can fix the name, which might be wrong
1375                                  * if findmount gave us a new Chan.
1376                                  */
1377                                 cnew = cunique(cnew);
1378                                 cnameclose(cnew->name);
1379                                 cnew->name = c->name;
1380                                 kref_get(&cnew->name->ref, 1);
1381
1382                                 cnew->flag |= omode & CEXTERNAL_FLAGS;
1383                                 devtab[cnew->type].create(cnew, e.elems[e.ARRAY_SIZEs - 1],
1384                                                                                   omode & ~(O_EXCL | O_CLOEXEC),
1385                                                                                   perm, ext);
1386                                 poperror();
1387
1388                                 if (m)
1389                                         putmhead(m);
1390                                 cclose(c);
1391                                 c = cnew;
1392                                 c->name = addelem(c->name, e.elems[e.ARRAY_SIZEs - 1]);
1393                                 break;
1394                         }
1395
1396                         /* create failed */
1397                         cclose(cnew);
1398                         if (m)
1399                                 putmhead(m);
1400                         if (omode & O_EXCL)
1401                                 nexterror();    /* safe since we're in a waserror() */
1402                         poperror();     /* matching the if(!waserror) */
1403
1404                         /* save error, so walk doesn't clobber our existing errstr */
1405                         strlcpy(tmperrbuf, current_errstr(), sizeof(tmperrbuf));
1406                         saved_errno = get_errno();
1407                         /* note: we depend that walk does not error */
1408                         if (walk(&c, e.elems + e.ARRAY_SIZEs - 1, 1, wh, NULL) < 0) {
1409                                 set_errno(saved_errno);
1410                                 /* Report the error we had originally */
1411                                 error(EFAIL, tmperrbuf);
1412                         }
1413                         strlcpy(current_errstr(), tmperrbuf, MAX_ERRSTR_LEN);
1414                         omode |= O_TRUNC;
1415                         goto Open;
1416
1417                 default:
1418                         panic("unknown namec access %d\n", amode);
1419         }
1420
1421         poperror();
1422
1423         if (e.ARRAY_SIZEs > 0)
1424                 strlcpy(get_cur_genbuf(), e.elems[e.ARRAY_SIZEs - 1], GENBUF_SZ);
1425         else
1426                 strlcpy(get_cur_genbuf(), ".", GENBUF_SZ);
1427
1428         kfree(e.name);
1429         kfree(e.elems);
1430         kfree(e.off);
1431
1432         return c;
1433 }
1434
1435 struct chan *namec(char *name, int amode, int omode, uint32_t perm, void *ext)
1436 {
1437         struct walk_helper wh = {.can_mount = true};
1438         struct chan *c;
1439         char *devname, *devspec;
1440         int n, devtype;
1441
1442         if (name[0] == '\0')
1443                 error(EFAIL, "empty file name");
1444         validname(name, 1);
1445         /*
1446          * Find the starting off point (the current slash, the root of
1447          * a device tree, or the current dot) as well as the name to
1448          * evaluate starting there.
1449          */
1450         switch (name[0]) {
1451                 case '/':
1452                         if (current)
1453                                 c = current->slash;
1454                         else
1455                                 c = kern_slash;
1456                         chan_incref(c);
1457                         break;
1458
1459                 case '#':
1460                         wh.can_mount = false;
1461                         devname = get_cur_genbuf();
1462                         devname[0] = '\0';
1463                         n = 0;
1464                         name++; /* drop the # */
1465                         while ((*name != '\0') && (*name != '/')) {
1466                                 if (n >= GENBUF_SZ - 1)
1467                                         error(ENAMETOOLONG, ERROR_FIXME);
1468                                 devname[n++] = *name++;
1469                         }
1470                         devname[n] = '\0';
1471                         /* for a name #foo.spec, devname = foo\0, devspec = spec\0.
1472                          * genbuf contains foo\0spec\0.  for no spec, devspec = \0 */
1473                         devspec = strchr(devname, '.');
1474                         if (devspec) {
1475                                 *devspec = '\0';
1476                                 devspec++;
1477                         } else {
1478                                 devspec = &devname[n];
1479                         }
1480                         /* These devices have special attach functions that treat the char *
1481                          * as a blob pointer */
1482                         if (!strcmp(devname, "mnt"))
1483                                 error(EINVAL, "can't namec-attach #mnt");
1484                         if (!strcmp(devname, "gtfs"))
1485                                 error(EINVAL, "can't namec-attach #gtfs");
1486                         /* TODO: deal with this "nodevs" business. */
1487                         #if 0
1488                         /*
1489                          *  the nodevs exceptions are
1490                          *  |  it only gives access to pipes you create
1491                          *  e  this process's environment
1492                          *  s  private file2chan creation space
1493                          *  D private secure sockets name space
1494                          *  a private TLS name space
1495                          */
1496                         if (current->pgrp->nodevs &&
1497                                 //          (utfrune("|esDa", r) == NULL
1498                                 ((strchr("|esDa", get_cur_genbuf()[1]) == NULL)
1499                                  || (get_cur_genbuf()[1] == 's' // || r == 's'
1500                                          && get_cur_genbuf()[n] != '\0')))
1501                                 error(EINVAL, ERROR_FIXME);
1502                         #endif
1503                         devtype = devno(devname, 1);
1504                         if (devtype == -1)
1505                                 error(EFAIL, "Unknown #device %s (spec %s)", devname, devspec);
1506                         c = devtab[devtype].attach(devspec);
1507                         break;
1508                 default:
1509                         /* this case also covers \0 */
1510                         c = current->dot;
1511                         if (!c)
1512                                 panic("no dot!");
1513                         chan_incref(c);
1514                         break;
1515         }
1516         return __namec_from(c, name, amode, omode, perm, &wh, ext);
1517 }
1518
1519 struct chan *namec_from(struct chan *c, char *name, int amode, int omode,
1520                         uint32_t perm, void *ext)
1521 {
1522         struct walk_helper wh = {.can_mount = true};
1523
1524         if (name[0] == '\0') {
1525                 /* Our responsibility to cclose 'c' on our error */
1526                 cclose(c);
1527                 error(EFAIL, "empty file name");
1528         }
1529         validname(name, 1);
1530         return __namec_from(c, name, amode, omode, perm, &wh, ext);
1531 }
1532
1533 /*
1534  * name is valid. skip leading / and ./ as much as possible
1535  */
1536 char *skipslash(char *name)
1537 {
1538         while (name[0] == '/'
1539                    || (name[0] == '.' && (name[1] == 0 || name[1] == '/')))
1540                 name++;
1541         return name;
1542 }
1543
1544 char isfrog[256] = {
1545          /*NUL*/ 1, 1, 1, 1, 1, 1, 1, 1,
1546          /*BKS*/ 1, 1, 1, 1, 1, 1, 1, 1,
1547          /*DLE*/ 1, 1, 1, 1, 1, 1, 1, 1,
1548          /*CAN*/ 1, 1, 1, 1, 1, 1, 1, 1,
1549         ['/'] 1,
1550         [0x7f] 1,
1551 };
1552
1553 /*
1554  * Check that the name
1555  *  a) is in valid memory.
1556  *  b) is shorter than 2^16 bytes, so it can fit in a 9P string field.
1557  *  c) contains no frogs.
1558  * The first byte is known to be addressible by the requester, so the
1559  * routine works for kernel and user memory both.
1560  * The parameter slashok flags whether a slash character is an error
1561  * or a valid character.
1562  */
1563 void validname(char *aname, int slashok)
1564 {
1565         char *ename, *name;
1566         int c;
1567
1568         name = aname;
1569         ename = memchr(name, 0, (1 << 16));
1570
1571         if (ename == NULL || ename - name >= (1 << 16))
1572                 error(EINVAL, "Name too long");
1573
1574         while (*name) {
1575                 /* all characters above '~' are ok */
1576                 c = *(uint8_t *) name;
1577 #if 0
1578                 if (c >= Runeself)
1579                         name += chartorune(&r, name);
1580 #endif
1581                 if (c >= 0x7f) {
1582                         error(EFAIL, "Akaros doesn't do UTF-8");
1583                 } else {
1584                         if (isfrog[c])
1585                                 if (!slashok || c != '/') {
1586                                         error(EINVAL, "%s (%p), at char %c", aname, aname, c);
1587                                 }
1588                         name++;
1589                 }
1590         }
1591 }
1592
1593 void isdir(struct chan *c)
1594 {
1595         if (c->qid.type & QTDIR)
1596                 return;
1597         error(ENOTDIR, ERROR_FIXME);
1598 }
1599
1600 /*
1601  * This is necessary because there are many
1602  * pointers to the top of a given mount list:
1603  *
1604  *      - the mhead in the namespace hash table
1605  *      - the mhead in chans returned from findmount:
1606  *        used in namec and then by unionread.
1607  *      - the mhead in chans returned from createdir:
1608  *        used in the open/create race protect, which is gone.
1609  *
1610  * The RWlock in the Mhead protects the mount list it contains.
1611  * The mount list is deleted when we cunmount.
1612  * The RWlock ensures that nothing is using the mount list at that time.
1613  *
1614  * It is okay to replace c->mh with whatever you want as
1615  * long as you are sure you have a unique reference to it.
1616  *
1617  * This comment might belong somewhere else.
1618  */
1619 void putmhead(struct mhead *m)
1620 {
1621         if (m)
1622                 kref_put(&m->ref);
1623 }
1624
1625 /* Given s, make a copy of a string with padding bytes in front.  Returns a
1626  * pointer to the start of the string and the memory to free in str_store.
1627  *
1628  * Free str_store with kfree. */
1629 static char *pad_and_strdup(char *s, int padding, char **str_store)
1630 {
1631         char *store = kzmalloc(strlen(s) + 1 + padding, MEM_WAIT);
1632
1633         strlcpy(store + padding, s, strlen(s) + 1);
1634         *str_store = store;
1635         return store + padding;
1636 }
1637
1638 /* Walks a symlink c.  Returns the target chan, which could be the symlink
1639  * itself, if we're NO_FOLLOW.  On success, we'll decref the symlink and give
1640  * you a ref counted result.
1641  *
1642  * Returns NULL on error, and does not close the symlink.  Like regular walk, it
1643  * is all or nothing. */
1644 static struct chan *walk_symlink(struct chan *symlink, struct walk_helper *wh,
1645                                  unsigned int nr_names_left)
1646 {
1647         struct dir *dir;
1648         char *link_name, *link_store;
1649         struct chan *from;
1650         Elemlist e = {0};
1651
1652         /* mildly expensive: need to rlock the namespace */
1653         if (is_mount_point(symlink))
1654                 return symlink;
1655         if (!nr_names_left && wh->no_follow)
1656                 return symlink;
1657         if (wh->nr_loops >= WALK_MAX_NR_LOOPS) {
1658                 set_error(ELOOP, "too many nested symlinks in walk");
1659                 return NULL;
1660         }
1661         dir = chandirstat(symlink);
1662         if (!dir) {
1663                 /* Should propagate the error from dev.stat() */
1664                 return NULL;
1665         }
1666         if (!(dir->mode & DMSYMLINK)) {
1667                 set_error(ELOOP, "symlink isn't a symlink!");
1668                 kfree(dir);
1669                 return NULL;
1670         }
1671         link_name = pad_and_strdup(dir->ext, 3, &link_store);
1672         kfree(dir);
1673
1674         if (link_name[0] == '/') {
1675                 if (current)
1676                         from = current->slash;
1677                 else
1678                         from = kern_slash;
1679         } else {
1680                 from = symlink;
1681                 link_name -= 3;
1682                 strncpy(link_name, "../", 3);
1683                 if (!from->name)
1684                         from->name = newcname("");
1685         }
1686         /* we close this ref on failure or it gets walked to the result. */
1687         chan_incref(from);
1688
1689         parsename(link_name, &e);
1690         kfree(link_store);
1691
1692         wh->nr_loops++;
1693         if (walk(&from, e.elems, e.ARRAY_SIZEs, wh, NULL) < 0) {
1694                 cclose(from);
1695                 from = NULL;
1696         } else {
1697                 cclose(symlink);
1698                 if (from->qid.type & QTSYMLINK) {
1699                         symlink = from;
1700                         from = walk_symlink(symlink, wh, nr_names_left);
1701                         if (!from)
1702                                 cclose(symlink);
1703                 }
1704         }
1705         wh->nr_loops--;
1706
1707         kfree(e.name);
1708         kfree(e.elems);
1709         kfree(e.off);
1710         return from;
1711 }