Blame


1 d3df3087 2003-12-06 devnull /* Copyright (C) 2003 Russ Cox, Massachusetts Institute of Technology */
2 d3df3087 2003-12-06 devnull /* See COPYRIGHT */
3 d3df3087 2003-12-06 devnull
4 d3df3087 2003-12-06 devnull #include <u.h>
5 d3df3087 2003-12-06 devnull #include <libc.h>
6 d3df3087 2003-12-06 devnull #include <fcall.h>
7 d3df3087 2003-12-06 devnull #include <fs.h>
8 5a8e63b2 2004-02-29 devnull #include <thread.h>
9 d3df3087 2003-12-06 devnull #include "fsimpl.h"
10 d3df3087 2003-12-06 devnull
11 d3df3087 2003-12-06 devnull static int _fssend(Mux*, void*);
12 d3df3087 2003-12-06 devnull static void *_fsrecv(Mux*);
13 d3df3087 2003-12-06 devnull static int _fsgettag(Mux*, void*);
14 d3df3087 2003-12-06 devnull static int _fssettag(Mux*, void*, uint);
15 d3df3087 2003-12-06 devnull
16 d3df3087 2003-12-06 devnull enum
17 d3df3087 2003-12-06 devnull {
18 d3df3087 2003-12-06 devnull Fidchunk = 32
19 d3df3087 2003-12-06 devnull };
20 d3df3087 2003-12-06 devnull
21 d3df3087 2003-12-06 devnull Fsys*
22 d3df3087 2003-12-06 devnull fsinit(int fd)
23 d3df3087 2003-12-06 devnull {
24 d3df3087 2003-12-06 devnull Fsys *fs;
25 d3df3087 2003-12-06 devnull
26 ceb04770 2003-12-09 devnull fmtinstall('F', fcallfmt);
27 ceb04770 2003-12-09 devnull fmtinstall('D', dirfmt);
28 ceb04770 2003-12-09 devnull fmtinstall('M', dirmodefmt);
29 ceb04770 2003-12-09 devnull
30 d3df3087 2003-12-06 devnull fs = mallocz(sizeof(Fsys), 1);
31 d3df3087 2003-12-06 devnull if(fs == nil)
32 d3df3087 2003-12-06 devnull return nil;
33 d3df3087 2003-12-06 devnull fs->fd = fd;
34 d3df3087 2003-12-06 devnull fs->ref = 1;
35 d3df3087 2003-12-06 devnull fs->mux.aux = fs;
36 d3df3087 2003-12-06 devnull fs->mux.mintag = 0;
37 d3df3087 2003-12-06 devnull fs->mux.maxtag = 256;
38 d3df3087 2003-12-06 devnull fs->mux.send = _fssend;
39 d3df3087 2003-12-06 devnull fs->mux.recv = _fsrecv;
40 d3df3087 2003-12-06 devnull fs->mux.gettag = _fsgettag;
41 d3df3087 2003-12-06 devnull fs->mux.settag = _fssettag;
42 94235a8b 2004-12-27 devnull fs->iorecv = ioproc();
43 94235a8b 2004-12-27 devnull fs->iosend = ioproc();
44 d3df3087 2003-12-06 devnull muxinit(&fs->mux);
45 d3df3087 2003-12-06 devnull return fs;
46 d3df3087 2003-12-06 devnull }
47 d3df3087 2003-12-06 devnull
48 d3df3087 2003-12-06 devnull Fid*
49 d3df3087 2003-12-06 devnull fsroot(Fsys *fs)
50 d3df3087 2003-12-06 devnull {
51 d3df3087 2003-12-06 devnull /* N.B. no incref */
52 d3df3087 2003-12-06 devnull return fs->root;
53 d3df3087 2003-12-06 devnull }
54 d3df3087 2003-12-06 devnull
55 d3df3087 2003-12-06 devnull Fsys*
56 32f69c36 2003-12-11 devnull fsmount(int fd, char *aname)
57 d3df3087 2003-12-06 devnull {
58 d3df3087 2003-12-06 devnull int n;
59 d3df3087 2003-12-06 devnull char *user;
60 d3df3087 2003-12-06 devnull Fsys *fs;
61 d3df3087 2003-12-06 devnull
62 d3df3087 2003-12-06 devnull fs = fsinit(fd);
63 d3df3087 2003-12-06 devnull if(fs == nil)
64 d3df3087 2003-12-06 devnull return nil;
65 d3df3087 2003-12-06 devnull strcpy(fs->version, "9P2000");
66 d3df3087 2003-12-06 devnull if((n = fsversion(fs, 8192, fs->version, sizeof fs->version)) < 0){
67 d3df3087 2003-12-06 devnull Error:
68 32f69c36 2003-12-11 devnull fs->fd = -1;
69 d3df3087 2003-12-06 devnull fsunmount(fs);
70 d3df3087 2003-12-06 devnull return nil;
71 d3df3087 2003-12-06 devnull }
72 d3df3087 2003-12-06 devnull fs->msize = n;
73 d3df3087 2003-12-06 devnull
74 d3df3087 2003-12-06 devnull user = getuser();
75 32f69c36 2003-12-11 devnull if((fs->root = fsattach(fs, nil, getuser(), aname)) == nil)
76 d3df3087 2003-12-06 devnull goto Error;
77 d3df3087 2003-12-06 devnull return fs;
78 d3df3087 2003-12-06 devnull }
79 d3df3087 2003-12-06 devnull
80 d3df3087 2003-12-06 devnull void
81 d3df3087 2003-12-06 devnull fsunmount(Fsys *fs)
82 d3df3087 2003-12-06 devnull {
83 32f69c36 2003-12-11 devnull fsclose(fs->root);
84 32f69c36 2003-12-11 devnull fs->root = nil;
85 d3df3087 2003-12-06 devnull _fsdecref(fs);
86 d3df3087 2003-12-06 devnull }
87 d3df3087 2003-12-06 devnull
88 d3df3087 2003-12-06 devnull void
89 d3df3087 2003-12-06 devnull _fsdecref(Fsys *fs)
90 d3df3087 2003-12-06 devnull {
91 1a8f27c3 2004-05-14 devnull Fid *f, **l, *next;
92 d3df3087 2003-12-06 devnull
93 d3df3087 2003-12-06 devnull qlock(&fs->lk);
94 32f69c36 2003-12-11 devnull --fs->ref;
95 32f69c36 2003-12-11 devnull //fprint(2, "fsdecref %p to %d\n", fs, fs->ref);
96 32f69c36 2003-12-11 devnull if(fs->ref == 0){
97 d3df3087 2003-12-06 devnull close(fs->fd);
98 1a8f27c3 2004-05-14 devnull /* trim the list down to just the first in each chunk */
99 1a8f27c3 2004-05-14 devnull for(l=&fs->freefid; *l; ){
100 1a8f27c3 2004-05-14 devnull if((*l)->fid%Fidchunk == 0)
101 1a8f27c3 2004-05-14 devnull l = &(*l)->next;
102 1a8f27c3 2004-05-14 devnull else
103 1a8f27c3 2004-05-14 devnull *l = (*l)->next;
104 1a8f27c3 2004-05-14 devnull }
105 1a8f27c3 2004-05-14 devnull /* now free the list */
106 d3df3087 2003-12-06 devnull for(f=fs->freefid; f; f=next){
107 d3df3087 2003-12-06 devnull next = f->next;
108 1a8f27c3 2004-05-14 devnull free(f);
109 d3df3087 2003-12-06 devnull }
110 94235a8b 2004-12-27 devnull closeioproc(fs->iorecv);
111 94235a8b 2004-12-27 devnull closeioproc(fs->iosend);
112 d3df3087 2003-12-06 devnull free(fs);
113 1a8f27c3 2004-05-14 devnull return;
114 d3df3087 2003-12-06 devnull }
115 d3df3087 2003-12-06 devnull qunlock(&fs->lk);
116 d3df3087 2003-12-06 devnull }
117 d3df3087 2003-12-06 devnull
118 d3df3087 2003-12-06 devnull int
119 d3df3087 2003-12-06 devnull fsversion(Fsys *fs, int msize, char *version, int nversion)
120 d3df3087 2003-12-06 devnull {
121 d3df3087 2003-12-06 devnull void *freep;
122 d3df3087 2003-12-06 devnull Fcall tx, rx;
123 d3df3087 2003-12-06 devnull
124 32f69c36 2003-12-11 devnull tx.tag = 0;
125 d3df3087 2003-12-06 devnull tx.type = Tversion;
126 d3df3087 2003-12-06 devnull tx.version = version;
127 d3df3087 2003-12-06 devnull tx.msize = msize;
128 d3df3087 2003-12-06 devnull
129 d3df3087 2003-12-06 devnull if(fsrpc(fs, &tx, &rx, &freep) < 0)
130 d3df3087 2003-12-06 devnull return -1;
131 d3df3087 2003-12-06 devnull strecpy(version, version+nversion, rx.version);
132 d3df3087 2003-12-06 devnull free(freep);
133 d3df3087 2003-12-06 devnull return rx.msize;
134 d3df3087 2003-12-06 devnull }
135 d3df3087 2003-12-06 devnull
136 d3df3087 2003-12-06 devnull Fid*
137 d3df3087 2003-12-06 devnull fsattach(Fsys *fs, Fid *afid, char *user, char *aname)
138 d3df3087 2003-12-06 devnull {
139 d3df3087 2003-12-06 devnull Fcall tx, rx;
140 d3df3087 2003-12-06 devnull Fid *fid;
141 d3df3087 2003-12-06 devnull
142 32f69c36 2003-12-11 devnull if(aname == nil)
143 32f69c36 2003-12-11 devnull aname = "";
144 32f69c36 2003-12-11 devnull
145 d3df3087 2003-12-06 devnull if((fid = _fsgetfid(fs)) == nil)
146 d3df3087 2003-12-06 devnull return nil;
147 d3df3087 2003-12-06 devnull
148 32f69c36 2003-12-11 devnull tx.tag = 0;
149 d3df3087 2003-12-06 devnull tx.type = Tattach;
150 d3df3087 2003-12-06 devnull tx.afid = afid ? afid->fid : NOFID;
151 d3df3087 2003-12-06 devnull tx.fid = fid->fid;
152 d3df3087 2003-12-06 devnull tx.uname = user;
153 d3df3087 2003-12-06 devnull tx.aname = aname;
154 d3df3087 2003-12-06 devnull
155 d3df3087 2003-12-06 devnull if(fsrpc(fs, &tx, &rx, 0) < 0){
156 d3df3087 2003-12-06 devnull _fsputfid(fid);
157 d3df3087 2003-12-06 devnull return nil;
158 d3df3087 2003-12-06 devnull }
159 d3df3087 2003-12-06 devnull fid->qid = rx.qid;
160 d3df3087 2003-12-06 devnull return fid;
161 d3df3087 2003-12-06 devnull }
162 d3df3087 2003-12-06 devnull
163 d3df3087 2003-12-06 devnull int
164 d3df3087 2003-12-06 devnull fsrpc(Fsys *fs, Fcall *tx, Fcall *rx, void **freep)
165 d3df3087 2003-12-06 devnull {
166 d3df3087 2003-12-06 devnull int n, nn;
167 d3df3087 2003-12-06 devnull void *tpkt, *rpkt;
168 d3df3087 2003-12-06 devnull
169 d3df3087 2003-12-06 devnull n = sizeS2M(tx);
170 d3df3087 2003-12-06 devnull tpkt = malloc(n);
171 ceb04770 2003-12-09 devnull if(freep)
172 ceb04770 2003-12-09 devnull *freep = nil;
173 d3df3087 2003-12-06 devnull if(tpkt == nil)
174 d3df3087 2003-12-06 devnull return -1;
175 32f69c36 2003-12-11 devnull //fprint(2, "<- %F\n", tx);
176 d3df3087 2003-12-06 devnull nn = convS2M(tx, tpkt, n);
177 d3df3087 2003-12-06 devnull if(nn != n){
178 d3df3087 2003-12-06 devnull free(tpkt);
179 d3df3087 2003-12-06 devnull werrstr("libfs: sizeS2M convS2M mismatch");
180 d3df3087 2003-12-06 devnull fprint(2, "%r\n");
181 d3df3087 2003-12-06 devnull return -1;
182 d3df3087 2003-12-06 devnull }
183 d3df3087 2003-12-06 devnull rpkt = muxrpc(&fs->mux, tpkt);
184 d3df3087 2003-12-06 devnull free(tpkt);
185 d3df3087 2003-12-06 devnull if(rpkt == nil)
186 d3df3087 2003-12-06 devnull return -1;
187 d3df3087 2003-12-06 devnull n = GBIT32((uchar*)rpkt);
188 d3df3087 2003-12-06 devnull nn = convM2S(rpkt, n, rx);
189 d3df3087 2003-12-06 devnull if(nn != n){
190 d3df3087 2003-12-06 devnull free(rpkt);
191 32f69c36 2003-12-11 devnull werrstr("libfs: convM2S packet size mismatch %d %d", n, nn);
192 d3df3087 2003-12-06 devnull fprint(2, "%r\n");
193 d3df3087 2003-12-06 devnull return -1;
194 d3df3087 2003-12-06 devnull }
195 32f69c36 2003-12-11 devnull //fprint(2, "-> %F\n", rx);
196 d3df3087 2003-12-06 devnull if(rx->type == Rerror){
197 d3df3087 2003-12-06 devnull werrstr("%s", rx->ename);
198 d3df3087 2003-12-06 devnull free(rpkt);
199 d3df3087 2003-12-06 devnull return -1;
200 d3df3087 2003-12-06 devnull }
201 d3df3087 2003-12-06 devnull if(rx->type != tx->type+1){
202 d3df3087 2003-12-06 devnull werrstr("packet type mismatch -- tx %d rx %d",
203 d3df3087 2003-12-06 devnull tx->type, rx->type);
204 d3df3087 2003-12-06 devnull free(rpkt);
205 d3df3087 2003-12-06 devnull return -1;
206 d3df3087 2003-12-06 devnull }
207 d3df3087 2003-12-06 devnull if(freep)
208 d3df3087 2003-12-06 devnull *freep = rpkt;
209 d3df3087 2003-12-06 devnull else
210 d3df3087 2003-12-06 devnull free(rpkt);
211 d3df3087 2003-12-06 devnull return 0;
212 d3df3087 2003-12-06 devnull }
213 d3df3087 2003-12-06 devnull
214 d3df3087 2003-12-06 devnull Fid*
215 d3df3087 2003-12-06 devnull _fsgetfid(Fsys *fs)
216 d3df3087 2003-12-06 devnull {
217 d3df3087 2003-12-06 devnull int i;
218 d3df3087 2003-12-06 devnull Fid *f;
219 d3df3087 2003-12-06 devnull
220 d3df3087 2003-12-06 devnull qlock(&fs->lk);
221 d3df3087 2003-12-06 devnull if(fs->freefid == nil){
222 e95a7088 2003-12-09 devnull f = mallocz(sizeof(Fid)*Fidchunk, 1);
223 d3df3087 2003-12-06 devnull if(f == nil){
224 d3df3087 2003-12-06 devnull qunlock(&fs->lk);
225 d3df3087 2003-12-06 devnull return nil;
226 d3df3087 2003-12-06 devnull }
227 d3df3087 2003-12-06 devnull for(i=0; i<Fidchunk; i++){
228 d3df3087 2003-12-06 devnull f[i].fid = fs->nextfid++;
229 d3df3087 2003-12-06 devnull f[i].next = &f[i+1];
230 d3df3087 2003-12-06 devnull f[i].fs = fs;
231 d3df3087 2003-12-06 devnull }
232 d3df3087 2003-12-06 devnull f[i-1].next = nil;
233 d3df3087 2003-12-06 devnull fs->freefid = f;
234 d3df3087 2003-12-06 devnull }
235 d3df3087 2003-12-06 devnull f = fs->freefid;
236 d3df3087 2003-12-06 devnull fs->freefid = f->next;
237 32f69c36 2003-12-11 devnull fs->ref++;
238 d3df3087 2003-12-06 devnull qunlock(&fs->lk);
239 d3df3087 2003-12-06 devnull return f;
240 d3df3087 2003-12-06 devnull }
241 d3df3087 2003-12-06 devnull
242 d3df3087 2003-12-06 devnull void
243 d3df3087 2003-12-06 devnull _fsputfid(Fid *f)
244 d3df3087 2003-12-06 devnull {
245 d3df3087 2003-12-06 devnull Fsys *fs;
246 d3df3087 2003-12-06 devnull
247 d3df3087 2003-12-06 devnull fs = f->fs;
248 d3df3087 2003-12-06 devnull qlock(&fs->lk);
249 d3df3087 2003-12-06 devnull f->next = fs->freefid;
250 d3df3087 2003-12-06 devnull fs->freefid = f;
251 d3df3087 2003-12-06 devnull qunlock(&fs->lk);
252 d3df3087 2003-12-06 devnull _fsdecref(fs);
253 d3df3087 2003-12-06 devnull }
254 d3df3087 2003-12-06 devnull
255 d3df3087 2003-12-06 devnull static int
256 d3df3087 2003-12-06 devnull _fsgettag(Mux *mux, void *pkt)
257 d3df3087 2003-12-06 devnull {
258 d3df3087 2003-12-06 devnull return GBIT16((uchar*)pkt+5);
259 d3df3087 2003-12-06 devnull }
260 d3df3087 2003-12-06 devnull
261 d3df3087 2003-12-06 devnull static int
262 d3df3087 2003-12-06 devnull _fssettag(Mux *mux, void *pkt, uint tag)
263 d3df3087 2003-12-06 devnull {
264 d3df3087 2003-12-06 devnull PBIT16((uchar*)pkt+5, tag);
265 d3df3087 2003-12-06 devnull return 0;
266 d3df3087 2003-12-06 devnull }
267 d3df3087 2003-12-06 devnull
268 d3df3087 2003-12-06 devnull static int
269 d3df3087 2003-12-06 devnull _fssend(Mux *mux, void *pkt)
270 d3df3087 2003-12-06 devnull {
271 d3df3087 2003-12-06 devnull Fsys *fs;
272 d3df3087 2003-12-06 devnull
273 d3df3087 2003-12-06 devnull fs = mux->aux;
274 94235a8b 2004-12-27 devnull return iowrite(fs->iosend, fs->fd, pkt, GBIT32((uchar*)pkt));
275 d3df3087 2003-12-06 devnull }
276 d3df3087 2003-12-06 devnull
277 d3df3087 2003-12-06 devnull static void*
278 d3df3087 2003-12-06 devnull _fsrecv(Mux *mux)
279 d3df3087 2003-12-06 devnull {
280 d3df3087 2003-12-06 devnull uchar *pkt;
281 d3df3087 2003-12-06 devnull uchar buf[4];
282 32f69c36 2003-12-11 devnull int n, nfd;
283 d3df3087 2003-12-06 devnull Fsys *fs;
284 d3df3087 2003-12-06 devnull
285 d3df3087 2003-12-06 devnull fs = mux->aux;
286 94235a8b 2004-12-27 devnull n = ioreadn(fs->iorecv, fs->fd, buf, 4);
287 d3df3087 2003-12-06 devnull if(n != 4)
288 d3df3087 2003-12-06 devnull return nil;
289 d3df3087 2003-12-06 devnull n = GBIT32(buf);
290 d3df3087 2003-12-06 devnull pkt = malloc(n+4);
291 d3df3087 2003-12-06 devnull if(pkt == nil){
292 d3df3087 2003-12-06 devnull fprint(2, "libfs out of memory reading 9p packet; here comes trouble\n");
293 d3df3087 2003-12-06 devnull return nil;
294 d3df3087 2003-12-06 devnull }
295 ceb04770 2003-12-09 devnull PBIT32(pkt, n);
296 94235a8b 2004-12-27 devnull if(ioreadn(fs->iorecv, fs->fd, pkt+4, n-4) != n-4){
297 d3df3087 2003-12-06 devnull free(pkt);
298 d3df3087 2003-12-06 devnull return nil;
299 d3df3087 2003-12-06 devnull }
300 d3df3087 2003-12-06 devnull if(pkt[4] == Ropenfd){
301 94235a8b 2004-12-27 devnull if((nfd=iorecvfd(fs->iorecv, fs->fd)) < 0){
302 32f69c36 2003-12-11 devnull fprint(2, "recv fd error: %r\n");
303 32f69c36 2003-12-11 devnull free(pkt);
304 32f69c36 2003-12-11 devnull return nil;
305 32f69c36 2003-12-11 devnull }
306 32f69c36 2003-12-11 devnull PBIT32(pkt+n-4, nfd);
307 d3df3087 2003-12-06 devnull }
308 d3df3087 2003-12-06 devnull return pkt;
309 d3df3087 2003-12-06 devnull }