domfs

Document Object Model as a filesystem for plan9 os
git clone git://nsmpr.xyz/domfs.git
Log | Files | Refs | README

commit aa1edf01351388f45df7e24e25183e8362cdb61b
parent d4333a45184d3612aa5041578891cd5336e95920
Author: Pavel Renev <an2qzavok@gmail.com>
Date:   Fri, 13 Nov 2020 22:00:30 +0000

rework of tree, current status

Diffstat:
Mdomfs.c | 285++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Anotes | 10++++++++++
2 files changed, 213 insertions(+), 82 deletions(-)

diff --git a/domfs.c b/domfs.c @@ -4,69 +4,129 @@ #include <thread.h> #include <9p.h> +typedef struct Finf Finf; /* file info */ +typedef struct DTree DTree; +typedef struct Node Node; -typedef struct Stack Stack; -typedef struct Dnode Dnode; +enum { /* file types */ + ROOT, + TREE, + NODE, + CTRL, + USER, +}; -struct Stack { - long length; - Dnode **list; +struct Finf { + uvlong id; + Qid qid; + int type; + void *aux; }; -struct Dnode { - long id; - Dnode *parent; +struct DTree { + Node **nodes; + uvlong id; + uvlong nidcount; + Finf *finf; }; -static Stack nodes; -static long qcount; -static long ncount; +struct Node { + Node *parent; + Node **children; + uvlong id; + Finf *finf; +}; -void -stackinit(Stack *S) +Finf **files, *rootf; + +DTree **trees; +static uvlong tcount; + +long +stacksize(void **v) { - S->length = 0; - S->list = nil; - return; + long n; + if (v == nil) return 0; + for (n = 0; *v != nil; v++) n++; + return n; } -Dnode * -stackpush(Stack *stack, Dnode *new) +void +stackpush(void ***v, void *new) { - stack->list = realloc(stack->list, sizeof(Dnode*) * (stack->length + 1)); - stack->list[stack->length] = new; - stack->length++; - return stack->list[stack->length - 1]; + long n; + n = stacksize(*v); + *v = realloc(*v, (n + 2) * sizeof(void*)); + (*v)[n] = new; + (*v)[n+1] = nil; } +Finf* +newfinf(int type, void *aux) +{ + static uvlong id; + Finf *new; + new = malloc(sizeof(Finf)); + switch (type) { + case ROOT: + case TREE: + case NODE: + new->qid = (Qid){id, 0, QTDIR}; + break; + case CTRL: + case USER: + new->qid = (Qid){id, 0, QTFILE}; + break; + default: + sysfatal("newfinf: unknown file type %d", type); + } + new->type = type; + new->aux = aux; + id++; + return new; +} -long -newnode(Dnode *parent) +DTree* +newtree(void) { - Dnode *ref; - Dnode *new; - new = malloc(sizeof(Dnode)); + static uvlong id; + DTree *new; + new = malloc(sizeof(DTree)); + new->nodes = nil; + new->id = ++id; + new->nidcount = 0; + new->finf = newfinf(TREE, new); + stackpush(&files, new->finf); + return new; +} - new->id = ncount, - new->parent = parent, - new->type = nil, - new->attr = nil, - new->text = nil, - new->q = (Qid){qcount, 0, QTDIR}, +DTree* +gettree(DTree **trees, uvlong id) +{ + DTree *tp; + for (tp = trees[0]; tp != nil; tp++) + if (tp->id == id) return tp; + return nil; +} - stackinit(&new->children); - ncount++; - qcount += 0x10; - ref = stackpush(&nodes, new); - stackpush(&parent->children, ref); - return ref->id; +Node* +newnode(DTree *T) +{ + Node *new; + new = malloc(sizeof(Node)); + new->parent = nil; + new->children = nil; + new->id = ++T->nidcount; + new->finf = newfinf(NODE, new); + stackpush(&files, new->finf); + return new; } -Dnode * -getnode(long n) +Node* +getnode(DTree *T, uvlong n) { - Dnode **np; - for (np = nodes.list; np < nodes.list + nodes.length; np++) { + Node **np; + for (np = T->nodes; np != nil; np++) { if ((*np)->id == n) { return *np; } @@ -77,44 +137,78 @@ getnode(long n) void fsattach(Req *r) { - r->fid->qid = getnode(0)->q; - r->fid->aux = getnode(0); + r->fid->qid = rootf->qid; + r->fid->aux = rootf; r->ofcall.qid = r->fid->qid; respond(r, nil); } int -dirgen(int n, Dir *dir, void* aux) +dirgenroot(int n, Dir *dir, void*) { - Dnode *N; - if (aux == nil) return -1; - N = aux; - // TODO: do it properly - - if (n >= N->children.length) return -1; - + DTree *t; + t = trees[n]; + if (t == nil) return -1; + nulldir(dir); + dir->qid = t->finf->qid; + dir->mode = 0777 | DMDIR; + dir->atime = time(0); + dir->mtime = time(0); + dir->length = 0; + dir->name = smprint("%ulld", t->id); dir->uid = strdup("domfs"); dir->gid = strdup("domfs"); - dir->name = smprint("%ld", N->children.list[n]->id); - dir->mode = 0555|DMDIR; - dir->qid = getnode(n)->q; + dir->muid = strdup(""); + return 0; +} +int +dirgentree(int n, Dir *dir, void *aux) +{ + DTree *tree; + Node *node; + tree = aux; + node = tree->nodes[n]; + if (node == nil) return -1; + nulldir(dir); + dir->qid = node->finf->qid; + dir->mode = 0777 | DMDIR; + dir->atime = time(0); + dir->mtime = time(0); + dir->length = 0; + dir->name = smprint("%ulld", node->id); + dir->uid = strdup("domfs"); + dir->gid = strdup("domfs"); + dir->muid = strdup(""); return 0; } void fsread(Req *r) { - Dnode *node; - node = r->fid->aux; - dirread9p(r, dirgen, node); + Finf *f; + f = r->fid->aux; + switch(f->type){ + case ROOT: + dirread9p(r, dirgenroot, nil); + break; + case TREE: + dirread9p(r, dirgentree, f->aux); + break; + case NODE: + case CTRL: + case USER: + default: + sysfatal("fsread: unknown file type: %d", f->type); + } + + //dirread9p(r, dirgen, nil); respond(r, nil); } char* fsclone(Fid *oldfid, Fid *newfid) { - //fprint(2, "fsclone oldfid=%p newfid=%p\n", oldfid->aux, newfid->aux); newfid->aux = oldfid->aux; return nil; } @@ -122,42 +216,65 @@ fsclone(Fid *oldfid, Fid *newfid) char* fswalk1(Fid *fid, char *name, Qid *qid) { - long id; char *chp; - Dnode *node; - // TODO: check if name is one of control files - id = strtol(name, &chp, 10); - if (chp == name) return "not found"; - node = getnode(id); - *qid = node->q; + uvlong id; + Finf *f, *nf; + f = fid->aux; + nf = nil; + switch (f->type){ + case ROOT: + id = strtoull(name, &chp, 10); + // TODO: check if parsed correctly + nf = gettree(trees, id)->finf; + break; + case TREE: + id = strtoull(name, &chp, 10); + nf = getnode(f->aux, id)->finf; + break; + case NODE: + case CTRL: + case USER: + default: + sysfatal("fswalk1: unknown file type %d", f->type); + } + if (nf == nil) return "fswalk1: nf = nil"; + *qid = nf->qid; fid->qid = *qid; - fid->aux = getnode(id); + fid->aux = nf; return nil; } void fsstat(Req *r) { + Finf *f; + f = r->fid->aux; nulldir(&r->d); r->d.type = L'M'; r->d.dev = 1; r->d.length = 0; - r->d.muid = strdup(""); r->d.atime = time(0); r->d.mtime = time(0); r->d.uid = strdup("domfs"); r->d.gid = strdup("domfs"); - switch(r->fid->qid.path){ - case 0: - r->d.qid = (Qid){0, 0, QTDIR}; + r->d.muid = strdup(""); + r->d.qid = f->qid; + + switch (f->type) { + case ROOT: r->d.name = strdup("/"); - r->fid->aux = getnode(0); + r->d.mode = 0777|DMDIR; break; + case TREE: + r->d.name = smprint("%ulld", ((DTree*)f->aux)->id); + r->d.mode = 0777|DMDIR; + break; + case NODE: + case CTRL: + case USER: default: - r->d.qid = r->fid->qid; - r->d.name = smprint("%ulld", r->fid->qid.path); - }; - r->d.mode = 0777|DMDIR; + sysfatal("fsstat: unknown file type %d", f->type); + } respond(r, nil); } @@ -189,12 +306,16 @@ main(int argc, char **argv) usage(); } ARGEND - stackinit(&nodes); - newnode(nodes.list[0]); - newnode(nodes.list[0]); - newnode(nodes.list[0]); - newnode(getnode(1)); + rootf = newfinf(ROOT, &trees); + stackpush(&files, rootf); + stackpush(&trees, newtree()); + stackpush(&trees, newtree()); + stackpush(&trees, newtree()); + + stackpush(&(trees[0]->nodes), newnode(trees[0])); + stackpush(&(trees[0]->nodes), newnode(trees[0])); + Srv fs = { .attach = fsattach, .read = fsread, diff --git a/notes b/notes @@ -0,0 +1,10 @@ +# Sketch of file tree: + +/tree/ + new ? +/tree/node/ + new ? + children ? + parent ? +/tree/node/child/ ? + ...