fs.c (2888B)
1 #include <u.h> 2 #include <libc.h> 3 #include <fcall.h> 4 #include <thread.h> 5 #include <9p.h> 6 7 #include <btr.h> 8 9 typedef struct Snek Snek; 10 struct Snek { 11 void *aux; 12 Snek* next; 13 }; 14 15 Snek *head, *tail; 16 17 18 typedef struct Cell Cell; 19 struct Cell { 20 int type; 21 long n; 22 char *p; 23 }; 24 25 char *mkmsg(int op, vlong id, long nbytes, vlong offset, char *data); 26 void pushmsg(char *msg); 27 char *pullmsg(void); 28 void msgerror(vlong id, char *str); 29 30 /* 31 Cell's type can be: 32 - Atom 33 arbitrary length bytestring 34 - NULL 35 technically equivalent to Atom of length 0 36 - Pair 37 required opeartions: 38 - fetch (id -> Cell *) 39 - store (id, Cell * -> _ ) 40 */ 41 42 Cell * 43 fetch(long id) 44 { 45 return nil; 46 } 47 48 void 49 store(long id, Cell *c) 50 { 51 } 52 53 void 54 usage(void) 55 { 56 fprint(2, "usage: %s\n", argv0); 57 exits("usage"); 58 } 59 60 void 61 fs_write(Req *r) 62 { 63 Btrmsgheader *m; 64 if (r->ifcall.count < sizeof(Btrmsgheader)) { 65 // msg too short, provide BTerror 66 msgerror(0, smprint("msg too short")); 67 r->ofcall.count = r->ifcall.count; 68 respond(r, nil); 69 return; 70 } 71 m = (Btrmsgheader *)r->ifcall.data; 72 switch (m->op) { 73 case BTstat: 74 // provide BRstat 75 msgerror(m->id, smprint("BTstat not implemented yet")); 76 r->ofcall.count = r->ifcall.count; 77 break; 78 default: 79 // unexpected op, provide BTerror 80 msgerror(m->id, smprint("unknown op %X", m->op)); 81 r->ofcall.count = r->ifcall.count; 82 } 83 respond(r, nil); 84 } 85 86 void 87 fs_read(Req *r) 88 { 89 char *msg = pullmsg(); 90 if (msg == nil) { 91 // TODO: should block instead of returning read of 0 length, probably? 92 respond(r, nil); 93 return; 94 } 95 Btrmsgheader *mh = (Btrmsgheader *)msg; 96 long count = mh->nbytes + sizeof(Btrmsgheader); 97 if (count > r->ifcall.count) { 98 // TODO: this should be an error, probably? 99 count = r->ifcall.count; 100 } 101 memcpy(r->ofcall.data, msg, count); 102 r->ofcall.count = count; 103 respond(r, nil); 104 } 105 106 void 107 main(int argc, char **argv) 108 { 109 ARGBEGIN{ 110 default: 111 usage(); 112 } ARGEND 113 if (argc > 0) usage(); 114 Srv btrsrv = { 115 .read = fs_read, 116 .write = fs_write, 117 }; 118 btrsrv.tree = alloctree("btr", "btr", DMDIR|0555, nil); 119 File *data = createfile(btrsrv.tree->root, "data", "btr", DMAPPEND|0666, nil); 120 postmountsrv(&btrsrv, "btr", "/mnt/btr", MREPL); 121 } 122 123 char * 124 mkmsg(int op, vlong id, long nbytes, vlong offset, char *data) 125 { 126 Btrmsgheader mh = { 127 .op = op, .id = id, .nbytes = nbytes, .offset = offset, 128 }; 129 char *msg = malloc(sizeof(Btrmsgheader) + nbytes); 130 memcpy(msg, &mh, sizeof(Btrmsgheader)); 131 memcpy(msg + sizeof(Btrmsgheader), data, nbytes); 132 return msg; 133 } 134 135 void 136 pushmsg(char *msg) 137 { 138 Snek *next = mallocz(sizeof(Snek), 1); 139 next->aux = msg; 140 if (head != nil) head->next = next; 141 else tail = next; 142 head = next; 143 } 144 145 char * 146 pullmsg(void) 147 { 148 if (tail == nil) return nil; 149 char *msg = tail->aux; 150 tail = tail->next; 151 if (tail == nil) head = nil; 152 return msg; 153 } 154 155 void 156 msgerror(vlong id, char *str) 157 { 158 pushmsg(mkmsg(BRerror, id, strlen(str), 0, str)); 159 }