ramfs.c (2611B)
1 #include <u.h> 2 #include <libc.h> 3 #include <fcall.h> 4 #include <thread.h> 5 #include <9p.h> 6 7 static char Ebad[] = "something bad happened"; 8 static char Enomem[] = "no memory"; 9 10 typedef struct Ramfile Ramfile; 11 struct Ramfile { 12 char *data; 13 int ndata; 14 }; 15 16 void 17 fsread(Req *r) 18 { 19 Ramfile *rf; 20 vlong offset; 21 long count; 22 23 rf = r->fid->file->aux; 24 offset = r->ifcall.offset; 25 count = r->ifcall.count; 26 27 /*print("read %ld %lld\n", *count, offset); */ 28 if(offset >= rf->ndata){ 29 r->ofcall.count = 0; 30 respond(r, nil); 31 return; 32 } 33 34 if(offset+count >= rf->ndata) 35 count = rf->ndata - offset; 36 37 memmove(r->ofcall.data, rf->data+offset, count); 38 r->ofcall.count = count; 39 respond(r, nil); 40 } 41 42 void 43 fswrite(Req *r) 44 { 45 void *v; 46 Ramfile *rf; 47 vlong offset; 48 long count; 49 50 rf = r->fid->file->aux; 51 offset = r->ifcall.offset; 52 count = r->ifcall.count; 53 54 if(offset+count >= rf->ndata){ 55 v = realloc(rf->data, offset+count); 56 if(v == nil){ 57 respond(r, Enomem); 58 return; 59 } 60 rf->data = v; 61 rf->ndata = offset+count; 62 r->fid->file->dir.length = rf->ndata; 63 } 64 memmove(rf->data+offset, r->ifcall.data, count); 65 r->ofcall.count = count; 66 respond(r, nil); 67 } 68 69 void 70 fscreate(Req *r) 71 { 72 Ramfile *rf; 73 File *f; 74 75 if(f = createfile(r->fid->file, r->ifcall.name, r->fid->uid, r->ifcall.perm, nil)){ 76 rf = emalloc9p(sizeof *rf); 77 f->aux = rf; 78 r->fid->file = f; 79 r->ofcall.qid = f->dir.qid; 80 respond(r, nil); 81 return; 82 } 83 respond(r, Ebad); 84 } 85 86 void 87 fsopen(Req *r) 88 { 89 Ramfile *rf; 90 91 rf = r->fid->file->aux; 92 93 if(rf && (r->ifcall.mode&OTRUNC)){ 94 rf->ndata = 0; 95 r->fid->file->dir.length = 0; 96 } 97 98 respond(r, nil); 99 } 100 101 void 102 fsdestroyfile(File *f) 103 { 104 Ramfile *rf; 105 106 /*fprint(2, "clunk\n"); */ 107 rf = f->aux; 108 if(rf){ 109 free(rf->data); 110 free(rf); 111 } 112 } 113 114 Srv fs = { 115 .open= fsopen, 116 .read= fsread, 117 .write= fswrite, 118 .create= fscreate, 119 }; 120 121 void 122 usage(void) 123 { 124 fprint(2, "usage: ramfs [-D] [-s srvname] [-m mtpt]\n"); 125 threadexitsall("usage"); 126 } 127 128 int 129 threadmaybackground(void) 130 { 131 return 1; 132 } 133 134 void 135 threadmain(int argc, char **argv) 136 { 137 char *srvname = nil; 138 char *mtpt = nil; 139 Qid q; 140 141 fs.tree = alloctree(nil, nil, DMDIR|0777, fsdestroyfile); 142 q = fs.tree->root->dir.qid; 143 144 ARGBEGIN{ 145 case 'D': 146 chatty9p++; 147 break; 148 case 's': 149 srvname = EARGF(usage()); 150 break; 151 case 'm': 152 mtpt = EARGF(usage()); 153 break; 154 default: 155 usage(); 156 }ARGEND; 157 158 if(argc) 159 usage(); 160 161 if(chatty9p) 162 fprint(2, "ramsrv.nopipe %d srvname %s mtpt %s\n", fs.nopipe, srvname, mtpt); 163 if(srvname == nil && mtpt == nil) 164 sysfatal("you should at least specify a -s or -m option"); 165 166 threadpostmountsrv(&fs, srvname, mtpt, MREPL|MCREATE); 167 threadexits(0); 168 }