9ns: Remove #root
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 7 Mar 2018 01:10:25 +0000 (17:10 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Mon, 30 Apr 2018 18:31:44 +0000 (14:31 -0400)
Everything it did is done better by #kfs.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/drivers/dev/Kbuild
kern/drivers/dev/root.c [deleted file]
kern/src/ns/sysfile.c

index 82bf78b..f144034 100644 (file)
@@ -14,7 +14,6 @@ obj-y                                         += pipe.o
 obj-y                                          += proc.o
 obj-y                                          += random.o
 obj-$(CONFIG_REGRESS)          += regress.o
-obj-y                                          += root.o
 obj-y                                          += sd.o
 obj-y                                          += sdscsi.o
 obj-y                                          += sdiahci.o
diff --git a/kern/drivers/dev/root.c b/kern/drivers/dev/root.c
deleted file mode 100644 (file)
index 09832bf..0000000
+++ /dev/null
@@ -1,474 +0,0 @@
-/* Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
- * Portions Copyright © 1997-1999 Vita Nuova Limited
- * Portions Copyright © 2000-2007 Vita Nuova Holdings Limited
- *                                (www.vitanuova.com)
- * Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
- *
- * Modified for the Akaros operating system:
- * Copyright (c) 2013-2014 The Regents of the University of California
- * Copyright (c) 2013-2015 Google Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE. */
-
-#include <vfs.h>
-#include <kfs.h>
-#include <slab.h>
-#include <kmalloc.h>
-#include <kref.h>
-#include <string.h>
-#include <stdio.h>
-#include <assert.h>
-#include <error.h>
-#include <cpio.h>
-#include <pmap.h>
-#include <smp.h>
-#include <net/ip.h>
-#include <umem.h>
-
-struct dev rootdevtab;
-
-static char *devname(void)
-{
-       return rootdevtab.name;
-}
-
-/* make it a power of 2 and nobody gets hurt */
-#define MAXFILE 1024
-int rootmaxq = MAXFILE;
-
-/* TODO:
- *  - synchronization!  what needs protection from concurrent use, etc.
- *     - clean up documentation and whatnot
- *     - does remove, mkdir, rmdir work?
- *     - fill this with cpio stuff
- *     - figure out how to use the page cache
- *     - atime/ctime/mtime/etctime
- */
-
-/* this gives you some idea of how much I like linked lists. Just make
- * a big old table. Later on we can put next and prev indices into the
- * data if we want but, our current kfs is 1-3 levels deep and very small
- * (< 200 entries) so I doubt we'll need to do that. It just makes debugging
- * memory a tad easier.
- */
-/* Da Rules.
- * The roottab contains [name, qid, length, perm].
- * Length is filesize for files, # children/elements for dirs
- * Qid is [path, vers, type]. Path is me. vers is next. Type is QTDIR for dir
- * and QTFILE for file and 0 for empty.
- *
- * We have rootdata to help out with a couple things, notably storing the 'data'
- * of the object (file or dir) and the first child index/qid.path for
- * directories.
- *
- * Data is [dotdot, child, ptr]
- * dotdot is ..
- * ptr is data for files, first child for dirs.
- * child is the qid.path of the first child of a directory.
- * Possibly 0 == no child.
- * To find the next sibling (in a directory), look at roottab[i].qid.vers.
- */
-
-/* we pack the qid as follows: path is the index, vers is ., and type is type */
-
-/* Inferno seems to want to: perm |= DMDIR.  It gets checked in other places.
- * NxM didn't want this, IIRC.
- *
- * Also note that "" (/, #root, whatever) has no vers/next/sibling.
- *
- * If you want to add new entries, add it to the roottab such that the linked
- * list of indexes is a cycle (change the last current one), then add an entry
- * to rootdata, and then change the first rootdata entry to have another entry.
- * Yeah, it's a pain in the ass.
- *
- * To add subdirectories, or any child of a directory, the files (e.g. env_dir1)
- * go in roottab.  Children of a parent are linked with their vers (note
- * env_dir1 points to env_dir2), and the last item's vers = 0.  These files need
- * their dotdot set in rootdata to the qid of their parent.  The directory that
- * has children needs its child pointer set to the first qid in the list, and
- * its data pointer must point to the roottab entry for the child.  This also
- * means that all child entries in roottab for a parent must be contiguous.
- *
- * Yeah, it's a pain in the ass.  And, given this structure, it probably can't
- * grow dynamically (I think we assume roottab[i] = entry for qid.path all over
- * the place - imagine what happens if we wanted to squeeze in a new entry). */
-struct dirtab roottab[MAXFILE] = {
-       {"",                            { 0,  0, QTDIR}, 13, DMDIR | 0777},
-       {"chan",                        { 1,  2, QTDIR},  0, DMDIR | 0777},
-       {"dev",                         { 2,  3, QTDIR},  0, DMDIR | 0777},
-       {"fd",                          { 3,  4, QTDIR},  0, DMDIR | 0777},
-       {"prog",                        { 4,  5, QTDIR},  0, DMDIR | 0777},
-       {"prof",                        { 5,  6, QTDIR},  0, DMDIR | 0777},
-       {"net",                         { 6,  7, QTDIR},  0, DMDIR | 0777},
-       {"net.alt",                     { 7,  8, QTDIR},  0, DMDIR | 0777},
-       {"nvfs",                        { 8,  9, QTDIR},  0, DMDIR | 0777},
-       {"env",                         { 9, 10, QTDIR},  2, DMDIR | 0777},
-       {"root",                        {10, 11, QTDIR},  0, DMDIR | 0777},
-       {"srv",                         {11, 12, QTDIR},  0, DMDIR | 0777},
-       {"mnt",                         {12, 13, QTDIR},  0, DMDIR | 0777},
-       {"proc",                        {13,  0, QTDIR},  0, DMDIR | 0777},
-       {"env_dir1",            {14, 15, QTDIR},  0, DMDIR | 0777},
-       {"env_dir2",            {15,  0, QTDIR},  0, DMDIR | 0777},
-};
-
-struct rootdata {
-       int dotdot;
-       int child;
-       void *ptr;
-};
-
-struct rootdata rootdata[MAXFILE] = {
-       {0,     1,       &roottab[1]},
-       {0,     0,       NULL},
-       {0,     0,       NULL},
-       {0,     0,       NULL},
-       {0,     0,       NULL},
-       {0,     0,       NULL},
-       {0,     0,       NULL},
-       {0,     0,       NULL},
-       {0,     0,       NULL},
-       {0,     14,      &roottab[14]},
-       {0,     0,       NULL},
-       {0,     0,       NULL},
-       {0,     0,       NULL},
-       {0,     0,       NULL},
-       {9,     0,       NULL},
-       {9,     0,       NULL},
-};
-
-/* this is super useful */
-void dumprootdev(void)
-{
-       struct dirtab *r = roottab;
-       struct rootdata *rd = rootdata;
-       int i;
-
-       printk("[       dirtab     ]                          name: [pth, ver, typ],   len,        perm,  .., chld,       data pointer\n");
-       for (i = 0; i < rootmaxq; i++, r++, rd++) {
-               if (i && (!r->name[0]))
-                       continue;
-               printk("[%p]%30s: [%3d, %3d, %3d], %5d, %11o,",
-                          r,
-                          r->name, r->qid.path, r->qid.vers, r->qid.type,
-                          r->length, r->perm);
-               printk(" %3d, %4d, %p\n", rd->dotdot, rd->child, rd->ptr);
-       }
-}
-
-static int findempty(void)
-{
-       int i;
-       for (i = 0; i < rootmaxq; i++) {
-               if (!roottab[i].qid.type) {
-                       memset(&roottab[i], 0, sizeof(roottab[i]));
-                       return i;
-               }
-       }
-       return -1;
-}
-
-static void freeempty(int i)
-{
-       roottab[i].qid.type = 0;
-}
-
-static int newentry(int parent)
-{
-       int n = findempty();
-       int sib;
-       if (n < 0)
-               error(EFAIL, "#root. No more");
-       printd("new entry is %d\n", n);
-       /* add the new one to the head of the linked list.  vers is 'next' */
-       roottab[n].qid.vers = rootdata[parent].child;
-       rootdata[parent].child = n;
-       return n;
-}
-
-static int createentry(int dir, char *name, int omode, int perm)
-{
-       int n = newentry(dir);
-       strlcpy(roottab[n].name, name, sizeof(roottab[n].name));
-       roottab[n].length = 0;
-       roottab[n].perm = perm;
-       /* vers is already properly set. */
-       mkqid(&roottab[n].qid, n, roottab[n].qid.vers,
-             perm & DMDIR ? QTDIR : QTFILE);
-       rootdata[n].dotdot = roottab[dir].qid.path;
-       rootdata[dir].ptr = &roottab[n];
-       return n;
-}
-
-static void rootinit(void)
-{
-}
-
-static struct chan *rootattach(char *spec)
-{
-       struct chan *c;
-       if (*spec)
-               error(EINVAL, ERROR_FIXME);
-       c = devattach(devname(), spec);
-       mkqid(&c->qid, roottab[0].qid.path, roottab[0].qid.vers, QTDIR);
-       return c;
-}
-
-/* rootgen is unlike other gens when it comes to the dirtab (tab) and ntab (nd).
- * We actually are a linked list of entries that happen to be in a table.  We
- * can figure out where to start based on the chan's qid.path and start the gen
- * from there.  So we don't need the 'tab' from dev.  Likewise, for directories,
- * we can figure out nd - our length in the dirtab. */
-static int rootgen(struct chan *c, char *name, struct dirtab *tab_unused,
-                   int nd_unused, int s, struct dir *dp)
-{
-       int p, i;
-       struct rootdata *r;
-       int iter;
-       struct dirtab *tab;
-
-       printd("rootgen from %s, for %s, s %d\n", roottab[c->qid.path].name, name,
-              s);
-       if (s == DEVDOTDOT) {
-               p = rootdata[c->qid.path].dotdot;
-               c->qid = roottab[p].qid;
-               name = roottab[p].name;
-               devdir(c, c->qid, name, 0, eve.name, 0777, dp);
-               return 1;
-       }
-
-       if (c->qid.type != QTDIR) {
-               /* return ourselved the first time; after that, -1 */
-               if (s)
-                       return -1;
-               tab = &roottab[c->qid.path];
-               devdir(c, tab->qid, tab->name, tab->length, eve.name, tab->perm, dp);
-               return 1;
-       }
-
-       if (name != NULL) {
-               int path = c->qid.path;
-               isdir(c);
-               tab = &roottab[rootdata[path].child];
-               /* we're starting at a directory. It might be '.' */
-               for (iter = 0, i = rootdata[path].child; /* break */; iter++) {
-                       if (strncmp(tab->name, name, KNAMELEN) == 0) {
-                               printd("Rootgen returns 1 for %s\n", name);
-                               devdir(c, tab->qid, tab->name, tab->length, eve.name, tab->perm,
-                                      dp);
-                               printd("return 1 with [%d, %d, %d]\n", dp->qid.path,
-                                      dp->qid.vers, dp->qid.type);
-                               return 1;
-                       }
-                       if (iter > rootmaxq) {
-                               printk("BUG:");
-                               dumprootdev();
-                               printk("name %s\n", name);
-                               return -1;
-                       }
-                       i = roottab[i].qid.vers;
-                       if (!i)
-                               break;
-                       tab = &roottab[i];
-               }
-               printd("rootgen: :%s: failed at path %d\n", name, path);
-               return -1;
-       }
-       /* Note we do not provide a "direct gen" for directories, which normally I'd
-        * do here.  If we do, that will confuse devdirread, which expects us to
-        * list our children, not ourselves.  stat() wants a "direct gen", e.g. for
-        * ls -l or stat of a directory.  We can handle that in rootstat(). */
-       if (s >= roottab[c->qid.path].length)
-               return -1;
-       for (i = rootdata[c->qid.path].child; i; i = roottab[i].qid.vers) {
-               tab = &roottab[i];
-               if (s-- == 0)
-                       break;
-       }
-       if (!i) {
-               warn("#root overflowed 'i', probably a bug");
-               return -1;
-       }
-       printd("root scan find returns path %p name %s\n", tab->qid.path, tab->name);
-       devdir(c, tab->qid, tab->name, tab->length, eve.name, tab->perm, dp);
-       return 1;
-}
-
-static struct walkqid *rootwalk(struct chan *c, struct chan *nc, char **name,
-                                                               unsigned int nname)
-{
-       return devwalk(c, nc, name, nname, NULL, 0, rootgen);
-}
-
-/* Instead of using devstat, we use our own.  This allows us to have stats on
- * directories.  devstat() just fakes it.  Note that gen cannot return a direct
- * gen for a directory, since that would break devdirread(). */
-static size_t rootstat(struct chan *c, uint8_t *dp, size_t n)
-{
-       struct dir dir[1];
-       size_t ret;
-       struct dirtab *entry = &roottab[c->qid.path];
-
-       /* TODO: this assumes eve is the user, which is what synthetic devices do.
-        * Likewise, it sets atime/mtime like a synth device.  There might be other
-        * weird things, like qid.type and mode. */
-       devdir(c, entry->qid, entry->name, entry->length, eve.name, entry->perm,
-              dir);
-       ret = convD2M(dir, dp, n);
-       if (!ret)
-               error(EFAIL, "#root failed to convert stat object to M");
-       return ret;
-}
-
-static struct chan *rootopen(struct chan *c, int omode)
-{
-       return devopen(c, omode, NULL, 0, rootgen);
-}
-
-static void rootcreate(struct chan *c, char *name, int omode, uint32_t perm,
-                       char *ext)
-{
-       struct dirtab *r = &roottab[c->qid.path], *newr;
-       struct rootdata *rd = &rootdata[c->qid.path];
-
-       if (perm & DMSYMLINK)
-               error(EINVAL, "#%s doesn't support symlinks", devname());
-       /* need to filter openmode so that it gets only the access-type bits */
-       omode = openmode(omode);
-       c->mode = openmode(omode);
-       printd("rootcreate: c %p, name %s, omode %o, perm %x\n",
-              c, name, omode, perm);
-       /* find an empty slot */
-       int path = c->qid.path;
-       int newfile;
-       newfile = createentry(path, name, omode, perm);
-       c->qid = roottab[newfile].qid;  /* need to update c */
-       r->length++;
-       if (newfile > rootmaxq)
-               rootmaxq = newfile;
-       printd("create: %s, newfile %d, dotdot %d, rootmaxq %d\n", name, newfile,
-              rootdata[newfile].dotdot, rootmaxq);
-}
-
-/*
- * sysremove() knows this is a nop
- *             fyi, this isn't true anymore!  they need to set c->type = -1;
- */
-static void rootclose(struct chan *c)
-{
-}
-
-static size_t rootread(struct chan *c, void *buf, size_t n, off64_t offset)
-{
-       uint32_t p, len;
-       uint8_t *data;
-
-       p = c->qid.path;
-       if (c->qid.type & QTDIR)
-               return devdirread(c, buf, n, NULL, 0, rootgen);
-       len = roottab[p].length;
-       if (offset < 0 || offset >= len) {
-               return 0;
-       }
-       if (offset + n > len)
-               n = len - offset;
-       data = rootdata[p].ptr;
-       /* we can't really claim it has to be a user address. Lots of
-        * kernel things read directly, e.g. /dev/reboot, #nix, etc.
-        * Address validation should be done in the syscall layer.
-        */
-       memcpy(buf, data + offset, n);
-       return n;
-}
-
-/* For now, just kzmalloc the right amount. Later, we should use
- * pages so mmap will go smoothly. Would be really nice to have a
- * kpagemalloc ... barret?
- *             we have kpage_alloc (gives a page) and kpage_alloc_addr (void*)
- */
-static size_t rootwrite(struct chan *c, void *a, size_t n, off64_t off)
-{
-       struct rootdata *rd = &rootdata[c->qid.path];
-       struct dirtab *r = &roottab[c->qid.path];
-
-       if (off < 0)
-               error(EFAIL, "rootwrite: offset < 0!");
-
-       if (off + n > r->length) {
-               void *p;
-               p = krealloc(rd->ptr, off + n, MEM_WAIT);
-               if (! p)
-                       error(EFAIL, "rootwrite: could not grow the file to %d bytes",
-                                 off + n);
-               rd->ptr = p;
-               r->length = off + n;
-       }
-       assert(current);
-       if (memcpy_from_user_errno(current, rd->ptr + off, a, n) < 0)
-               error(EFAIL, "%s: bad user addr %p", __FUNCTION__, a);
-
-       return n;
-}
-
-static size_t rootwstat(struct chan *c, uint8_t *m_buf, size_t m_buf_sz)
-{
-       struct dirtab *file = &roottab[c->qid.path];
-       struct dir *dir;
-       int m_sz;
-
-       /* TODO: some security check, Eperm on error */
-
-       /* common trick in wstats.  we want the dir and any strings in the M.  the
-        * strings are smaller than entire M (strings plus other M).  the strings
-        * will be placed right after the dir (dir[1]) */
-       dir = kzmalloc(sizeof(struct dir) + m_buf_sz, MEM_WAIT);
-       m_sz = convM2D(m_buf, m_buf_sz, &dir[0], (char*)&dir[1]);
-       if (!m_sz) {
-               kfree(dir);
-               error(ENODATA, ERROR_FIXME);
-       }
-       /* TODO: handle more things than just the mode */
-       if (!emptystr(dir->name))
-               printk("[%s] attempted rename of %s to %s\n", __FUNCTION__,
-                      file->name, dir->name);  /* strncpy for this btw */
-       if (dir->mode != -1)
-               file->perm = dir->mode | (file->qid.type == QTDIR ? DMDIR : 0);
-       kfree(dir);
-       return m_sz;
-}
-
-struct dev rootdevtab __devtab = {
-       .name = "root",
-       .reset = devreset,
-       .init = rootinit,
-       .shutdown = devshutdown,
-       .attach = rootattach,
-       .walk = rootwalk,
-       .stat = rootstat,
-       .open = rootopen,
-       .create = rootcreate,
-       .close = rootclose,
-       .read = rootread,
-       .bread = devbread,
-       .write = rootwrite,
-       .bwrite = devbwrite,
-       .remove = devremove,
-       .wstat = rootwstat,
-       .power = devpower,
-       .chaninfo = devchaninfo,
-};
index ea7a4c6..7899700 100644 (file)
@@ -1360,10 +1360,10 @@ int plan9setup(struct proc *new_proc, struct proc *parent, int flags)
                /* We are probably spawned by the kernel directly, and have no parent to
                 * inherit from. */
                new_proc->pgrp = newpgrp();
-               new_proc->slash = namec("#root", Atodir, 0, 0, NULL);
+               new_proc->slash = namec("#kfs", Atodir, 0, 0, NULL);
                if (!new_proc->slash)
-                       panic("no root device");
-               /* Want the name to be "/" instead of "#root" */
+                       panic("no kfs device");
+               /* Want the name to be "/" instead of "#kfs" */
                cnameclose(new_proc->slash->name);
                new_proc->slash->name = newcname("/");
                new_proc->dot = cclone(new_proc->slash);