Not very good implementation of root file system
[akaros.git] / kern / drivers / dev / root.c
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,