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:
M | domfs.c | | | 285 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------- |
A | notes | | | 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/ ?
+ ...