devroot is a mess. I think it can't grow dynamically very well. There are already well-known issues (in the TODO section).
For now, this allows us to do something like "ls /env/..". Previously that would crash. I took it a step farther and added subdirectories to env, just to make sure DOTDOT worked for non-root DOTDOTs. That was a huge pain. Now you can do things like this without crashing the kernel: / $ ls /nvfs/../ chan env mnt net.alt proc prog srv dev fd net nvfs prof root / $ ls /env/ env_dir1 env_dir2 / $ ls /env/../ chan env mnt net.alt proc prog srv dev fd net nvfs prof root / $ ls /env/env_dir2/../ env_dir1 env_dir2 We used to have some code that would, for when we weren't at the top-of-device entry (e.g. ""), appear to walk all siblings of roottab[p], until we found the one whose qid.path matched whatever we found via rootdata[].dotdot. That seemed busted. Ultimately, we need a dynamically changeable ramfs. #root might not be it. Signed-off-by: Barret Rhoden <[email protected]> --- kern/drivers/dev/root.c | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/kern/drivers/dev/root.c b/kern/drivers/dev/root.c index 85a5f7b26f2a..de394735858a 100644 --- a/kern/drivers/dev/root.c +++ b/kern/drivers/dev/root.c @@ -54,7 +54,6 @@ int rootmaxq = MAXFILE; int inumber = 13; /* TODO: - * - fix DOTDOT in gen. * - synchronization! what needs protection from concurrent use, etc. * - clean up documentation and whatnot * - does remove, mkdir, rmdir work? @@ -76,7 +75,10 @@ int inumber = 13; * dotdot is .., ptr is data (for files) * size is # elements (for dirs) * *sizep is a pointer for reasons not understood. - * next is the sibling. For a dir, it's the first element after '.'. + * 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. + * * int dotdot; * int child; * void *ptr; @@ -95,7 +97,19 @@ int inumber = 13; * 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. */ + * 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}, 0, DMDIR | 0777}, {"chan", {1, 2, QTDIR}, 0, DMDIR | 0777}, @@ -111,6 +125,8 @@ struct dirtab roottab[MAXFILE] = { {"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 { @@ -131,11 +147,13 @@ struct rootdata rootdata[MAXFILE] = { {0, 0, NULL, 0, NULL}, {0, 0, NULL, 0, NULL}, {0, 0, NULL, 0, NULL}, + {0, 14, &roottab[14], 2, NULL}, {0, 0, NULL, 0, NULL}, {0, 0, NULL, 0, NULL}, {0, 0, NULL, 0, NULL}, {0, 0, NULL, 0, NULL}, - {0, 0, NULL, 0, NULL}, + {9, 0, NULL, 0, NULL}, + {9, 0, NULL, 0, NULL}, }; /* this is super useful */ @@ -247,25 +265,9 @@ rootgen(struct chan *c, char *name, tab, nd, s, name); if (s == DEVDOTDOT) { - panic("this is busted"); p = rootdata[c->qid.path].dotdot; - // XXX we need to set the vers too. equiv to mkqid(&c->qid, ...) - c->qid.path = p; - c->qid.type = QTDIR; - name = devname(); - if (p != 0) { - /* TODO: what is this doing? do we want to walk the entire table, - * or are we just walking the siblings of our parent? */ - for (i = p;;) { - if (roottab[i].qid.path == c->qid.path) { - name = roottab[i].name; - break; - } - i = roottab[i].qid.vers; - if (!i) - break; - } - } + c->qid = roottab[p].qid; + name = roottab[p].name; devdir(c, c->qid, name, 0, eve, 0777, dp); return 1; } -- 2.9.0 -- You received this message because you are subscribed to the Google Groups "Akaros" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. For more options, visit https://groups.google.com/d/optout.
