fs.c (2290B)
1 #include <u.h> 2 #include <libc.h> 3 #include <fcall.h> 4 #include <thread.h> 5 #include <9p.h> 6 7 #include "octree.h" 8 #define GROWDELTA 8 9 10 /* TODO: possibly replace these with enum in file->aux and switch 11 statement instead of if/else in fsread/fswrite */ 12 File *data; 13 File *stream; 14 15 Node *db = nil; 16 long nodes = 0; 17 long dbsize = 0; 18 19 int 20 pushnode(void *v) 21 { 22 Node *n, *np; 23 n = v; 24 if (dbsize <= nodes * NODESIZE) { 25 dbsize = (nodes + GROWDELTA) * NODESIZE; 26 db = realloc(db, dbsize); 27 if (db == nil) sysfatal("%r"); 28 } 29 if (nodes == 0) { 30 memmove(&db[0], n, NODESIZE); 31 nodes = 1; 32 } else { 33 for (np = db; 34 (np < db + nodes) && (np->id < n->id); 35 np++); 36 if (np->id != n->id) { 37 if (np != db+nodes) memmove(np + 1, np, NODESIZE * (nodes + np - db)); 38 nodes++; 39 } 40 memmove(np, n, NODESIZE); 41 } 42 return 0; 43 } 44 45 void 46 fsread(Req *r) 47 { 48 File *f; 49 f = r->fid->file; 50 if (f == data) { 51 readbuf(r, db, nodes * NODESIZE); 52 respond(r, nil); 53 } else if (f == stream) { 54 readstr(r, r->fid->aux); 55 respond(r, nil); 56 } 57 else respond(r, "unidentified file"); 58 } 59 60 void 61 fswrite(Req *r) 62 { 63 File *f; 64 f = r->fid->file; 65 if (f == stream) { 66 pushnode(r->ifcall.data); 67 r->ofcall.count = NODESIZE; 68 respond(r, nil); 69 } 70 else { 71 fprint(2, "tttt\n"); 72 respond(r, "not implemented"); 73 } 74 } 75 76 void 77 fsflush(Req *r) 78 { 79 fprint(2, "flush\n"); 80 respond(r->oldreq, "when does flush happen?"); 81 respond(r, nil); 82 } 83 84 void 85 fsopen(Req *r) 86 { 87 r->fid->aux = smprint("fid=%uld\n", r->fid->fid); 88 respond(r, nil); 89 } 90 91 void 92 fsdestroyfid(Fid *fid) 93 { 94 free(fid->aux); 95 } 96 97 void 98 usage(void) 99 { 100 fprint(2, "usage: %s [-D][-m /mnt/octree][-s service]\n", argv0); 101 exits("usage"); 102 } 103 104 Srv fs = { 105 .open = fsopen, 106 .destroyfid = fsdestroyfid, 107 .read = fsread, 108 .write = fswrite, 109 .flush = fsflush, 110 }; 111 112 void 113 main (int argc, char **argv) 114 { 115 char *srv, *mtpt; 116 srv = nil; 117 mtpt = "/mnt/octree"; 118 119 ARGBEGIN { 120 case 'm': 121 mtpt = EARGF(usage()); 122 break; 123 case 's': 124 srv = EARGF(usage()); 125 break; 126 case 'D': 127 chatty9p++; 128 break; 129 default: 130 usage(); 131 }ARGEND 132 133 if (argc > 0) usage(); 134 135 fs.tree = alloctree("octree", "octree", 0777|DMDIR, nil), 136 data = createfile(fs.tree->root, "data", "octree", 0666, nil); 137 stream = createfile(fs.tree->root, "stream", "octree", 0666, nil); 138 postmountsrv(&fs, srv, mtpt, MREPL); 139 exits(nil); 140 }