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