Not very good implementation of root file system
authorRonald G. Minnich <rminnich@google.com>
Mon, 27 Jan 2014 19:51:05 +0000 (11:51 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 29 Jan 2014 20:00:26 +0000 (12:00 -0800)
mkdir sort of works. A lot else doesn't but I need to tend
to some other fires. If you don't agree with my bias against
linked lists then feel free to redo.

Sorry, wish this were better.

Signed-off-by: Ronald G. Minnich <rminnich@google.com>
kern/drivers/dev/root.c
kern/include/ns.h

index 1e8886d..b23ecdf 100644 (file)
 #include <ip.h>
 
 /* courtesy of the inferno mkroot script. */
-int rootmaxq = 13;
-struct dirtab roottab[13] = {
-       {"",    {0, 0, QTDIR},   0,     0555},
-       {"chan",        {1, 0, QTDIR},   0,     0555},
-       {"dev", {2, 0, QTDIR},   0,     0555},
-       {"fd",  {3, 0, QTDIR},   0,     0555},
-       {"prog",        {4, 0, QTDIR},   0,     0555},
-       {"prof",        {5, 0, QTDIR},   0,     0555},
-       {"net", {6, 0, QTDIR},   0,     0555},
-       {"net.alt",     {7, 0, QTDIR},   0,     0555},
-       {"nvfs",        {8, 0, QTDIR},   0,     0555},
-       {"env", {9, 0, QTDIR},   0,     0555},
-       {"root",        {10, 0, QTDIR},  0,     0555},
-       {"srv", {11, 0, QTDIR},  0,     0555},
+/* make it a power of 2 and nobody gets hurt */
+#define MAXFILE 1024
+int rootmaxq = MAXFILE;
+int inumber = 13;
+/* 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.
+ */
+/* we pack the qid as follows: path is the index, vers is ., and type is type */
+struct dirtab roottab[MAXFILE] = {
+       {"",    {0, 0, QTDIR},   0,     0777},
+       {"chan",        {1, 0, QTDIR},   0,     0777},
+       {"dev", {2, 0, QTDIR},   0,     0777},
+       {"fd",  {3, 0, QTDIR},   0,     0777},
+       {"prog",        {4, 0, QTDIR},   0,     0777},
+       {"prof",        {5, 0, QTDIR},   0,     0777},
+       {"net", {6, 0, QTDIR},   0,     0777},
+       {"net.alt",     {7, 0, QTDIR},   0,     0777},
+       {"nvfs",        {8, 0, QTDIR},   0,     0777},
+       {"env", {9, 0, QTDIR},   0,     0777},
+       {"root",        {10, 0, QTDIR},  0,     0777},
+       {"srv", {11, 0, QTDIR},  0,     0777},
        /* not courtesy of mkroot */
-       {"mnt", {12, 0, QTDIR},  0,     0555},
+       {"mnt", {12, 0, QTDIR},  0,     0777},
+};
+
+struct rootdata
+{
+       int     dotdot;
+       void    *ptr;
+       int     size;
+       int     *sizep;
 };
-struct rootdata rootdata[13] = {
+
+struct rootdata rootdata[MAXFILE] = {
        {0,      &roottab[1],    12,    NULL},
        {0,      NULL,   0,      NULL},
        {0,      NULL,   0,      NULL},
@@ -86,23 +105,39 @@ rootgen(struct chan *c, char *name,
                                        break;
                                }
                }
-               devdir(c, c->qid, name, 0, eve, 0555, dp);
+               devdir(c, c->qid, name, 0, eve, 0777, dp);
                return 1;
        }
+
        if(name != NULL){
+               int path = c->qid.path;
                isdir(c);
-               r = &rootdata[(int)c->qid.path];
+               r = &rootdata[path];
                tab = r->ptr;
+               /* it's almost always at or after your current spot. */
                for(i=0; i<r->size; i++, tab++)
                        if(strcmp(tab->name, name) == 0){
                                devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp);
                                return 1;
                        }
+               /* well we tried. */
+               /* Round up the usual suspects. Search every level. */
+               /* luckily this is pretty fast. */
+               tab = roottab;
+               r = rootdata;
+               for(i=0; i<path; i++, tab++, r++)
+                       if(tab->name && (roottab[r->dotdot].qid.path == c->qid.path) &&
+                          (strcmp(tab->name, name) == 0)){
+                               devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp);
+                               return 1;
+                       }
                return -1;
        }
+
        if(s >= nd)
                return -1;
        tab += s;
+
        devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp);
        return 1;
 }
@@ -111,7 +146,15 @@ static struct walkqid*
 rootwalk(struct chan *c, struct chan *nc, char **name, int nname)
 {
        uint32_t p;
-
+       if (0){
+               printk("rootwalk: c %p. ", c);
+               if (nname){
+                       int i;
+                       for(i = 0; i < nname-1; i++)
+                               printk("%s/", name[i]);
+                       printk("%s", name[i]);
+               }
+       }
        p = c->qid.path;
        if(nname == 0)
                p = rootdata[p].dotdot;
@@ -136,6 +179,34 @@ rootopen(struct chan *c, int omode)
        return devopen(c, omode, rootdata[p].ptr, rootdata[p].size, rootgen);
 }
 
+static void
+rootcreate(struct chan *c, char *name, int omode, uint32_t perm)
+{
+       struct dirtab *r = &roottab[c->qid.path], *newr;
+       struct rootdata *rd = &rootdata[c->qid.path], *newrd;
+       if (0)printk("rootcreate: c %p, name %s, omode %o, perm %x\n", 
+              c, name, omode, perm);
+       /* find an empty slot */
+       //wlock(&root)
+       int path = c->qid.path;
+       int newfile = inumber++; // kref
+       newr = &roottab[newfile];
+       strncpy(newr->name, name, sizeof(newr->name));
+       mkqid(&newr->qid, newfile, newfile, perm&DMDIR);
+       newr->length = 0;
+       newr->perm = perm;
+       newrd = &rootdata[newfile];
+       newrd->dotdot = path;
+       newrd->ptr = newr;
+       newrd->size = 0;
+       newrd->sizep = &newrd->size;
+       rd->size++;
+       if (newfile > rootmaxq)
+               rootmaxq = newfile;
+       if (1) printk("create: %s, newfile %d, dotdot %d, rootmaxq %d\n", name, newfile,
+                 newrd->dotdot, rootmaxq);
+}
+
 /*
  * sysremove() knows this is a nop
  */
@@ -163,6 +234,7 @@ rootread(struct chan *c, void *buf, long n, int64_t offset)
        return n;
 }
 
+
 static long     
 rootwrite(struct chan *c, void *a, long n, int64_t off)
 {
@@ -170,6 +242,23 @@ rootwrite(struct chan *c, void *a, long n, int64_t off)
        return 0;
 }
 
+void dumprootdev(void)
+{
+       struct dirtab *r = roottab;
+       struct rootdata *rd = rootdata;
+       int i;
+
+       for(i = 0; i < rootmaxq; i++){
+               if (! r->name[0])
+                       continue;
+               printk("%s: [%d, %d, %d], %d, %o; ",
+                      r->name, r->qid.path, r->qid.vers, r->qid.type,
+                      r->length, r->perm);
+               printk("dotdot %d, ptr %p, size %d, sizep %p\n", 
+                      rd->dotdot, rd->ptr, rd->size, rd->sizep);
+       }
+}
+
 struct dev rootdevtab __devtab = {
        'r',
        "root",
@@ -180,7 +269,7 @@ struct dev rootdevtab __devtab = {
        rootwalk,
        rootstat,
        rootopen,
-       devcreate,
+       rootcreate,
        rootclose,
        rootread,
        devbread,
index a192201..ef2e9ab 100644 (file)
@@ -295,14 +295,6 @@ struct alarms
        struct proc*    head;
 };
 
-struct rootdata
-{
-       int     dotdot;
-       void    *ptr;
-       int     size;
-       int     *sizep;
-};
-
 /*
  * Access types in namec & channel flags
  */
@@ -584,7 +576,8 @@ enum
        READSTR =       1000,           /* temporary buffer size for device reads */
 };
 
-extern struct dev      devtab[];
+extern struct dev      devtab
+[];
 extern struct dev      __devtabend[];
 
 struct cmdbuf
@@ -674,11 +667,11 @@ struct chan*              devattach( int unused_int, char *unused_char_p_t);
 struct block*          devbread(struct chan*, long, uint32_t);
 long           devbwrite(struct chan*, struct block*, uint32_t);
 struct chan*           devclone(struct chan*);
-void           devcreate(struct chan*, char *unused_char_p_t, int unused_int, uint32_t);
-void           devdir(struct chan*, struct qid, char *unused_char_p_t, int64_t, char*, long,
+void           devcreate(struct chan*, char *name, int mode, uint32_t perm);
+void           devdir(struct chan*, struct qid, char *, int64_t, char*, long,
                           struct dir*);
-long           devdirread(struct chan*, char *unused_char_p_t, long,
-                              struct dirtab*, int unused_int, Devgen*);
+long           devdirread(struct chan*, char *, long,
+                              struct dirtab*, int , Devgen*);
 Devgen         devgen;
 void           devinit(void);
 int            devno( int unused_int, int);