1 d3df3087 2003-12-06 devnull /* Copyright (C) 2003 Russ Cox, Massachusetts Institute of Technology */
2 d3df3087 2003-12-06 devnull /* See COPYRIGHT */
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"
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);
18 d3df3087 2003-12-06 devnull Fidchunk = 32
22 d3df3087 2003-12-06 devnull fsinit(int fd)
24 d3df3087 2003-12-06 devnull Fsys *fs;
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);
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;
49 d3df3087 2003-12-06 devnull fsroot(Fsys *fs)
51 d3df3087 2003-12-06 devnull /* N.B. no incref */
52 d3df3087 2003-12-06 devnull return fs->root;
56 32f69c36 2003-12-11 devnull fsmount(int fd, char *aname)
59 d3df3087 2003-12-06 devnull char *user;
60 d3df3087 2003-12-06 devnull Fsys *fs;
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){
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;
72 d3df3087 2003-12-06 devnull fs->msize = n;
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;
81 d3df3087 2003-12-06 devnull fsunmount(Fsys *fs)
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);
89 d3df3087 2003-12-06 devnull _fsdecref(Fsys *fs)
91 1a8f27c3 2004-05-14 devnull Fid *f, **l, *next;
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;
103 1a8f27c3 2004-05-14 devnull *l = (*l)->next;
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);
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);
115 d3df3087 2003-12-06 devnull qunlock(&fs->lk);
119 d3df3087 2003-12-06 devnull fsversion(Fsys *fs, int msize, char *version, int nversion)
121 d3df3087 2003-12-06 devnull void *freep;
122 d3df3087 2003-12-06 devnull Fcall tx, rx;
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;
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;
137 d3df3087 2003-12-06 devnull fsattach(Fsys *fs, Fid *afid, char *user, char *aname)
139 d3df3087 2003-12-06 devnull Fcall tx, rx;
140 d3df3087 2003-12-06 devnull Fid *fid;
142 32f69c36 2003-12-11 devnull if(aname == nil)
143 32f69c36 2003-12-11 devnull aname = "";
145 d3df3087 2003-12-06 devnull if((fid = _fsgetfid(fs)) == nil)
146 d3df3087 2003-12-06 devnull return nil;
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;
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;
159 d3df3087 2003-12-06 devnull fid->qid = rx.qid;
160 d3df3087 2003-12-06 devnull return fid;
164 d3df3087 2003-12-06 devnull fsrpc(Fsys *fs, Fcall *tx, Fcall *rx, void **freep)
166 d3df3087 2003-12-06 devnull int n, nn;
167 d3df3087 2003-12-06 devnull void *tpkt, *rpkt;
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;
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;
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;
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;
207 d3df3087 2003-12-06 devnull if(freep)
208 d3df3087 2003-12-06 devnull *freep = rpkt;
210 d3df3087 2003-12-06 devnull free(rpkt);
211 d3df3087 2003-12-06 devnull return 0;
215 d3df3087 2003-12-06 devnull _fsgetfid(Fsys *fs)
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;
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;
232 d3df3087 2003-12-06 devnull f[i-1].next = nil;
233 d3df3087 2003-12-06 devnull fs->freefid = f;
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;
243 d3df3087 2003-12-06 devnull _fsputfid(Fid *f)
245 d3df3087 2003-12-06 devnull Fsys *fs;
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);
255 d3df3087 2003-12-06 devnull static int
256 d3df3087 2003-12-06 devnull _fsgettag(Mux *mux, void *pkt)
258 d3df3087 2003-12-06 devnull return GBIT16((uchar*)pkt+5);
261 d3df3087 2003-12-06 devnull static int
262 d3df3087 2003-12-06 devnull _fssettag(Mux *mux, void *pkt, uint tag)
264 d3df3087 2003-12-06 devnull PBIT16((uchar*)pkt+5, tag);
265 d3df3087 2003-12-06 devnull return 0;
268 d3df3087 2003-12-06 devnull static int
269 d3df3087 2003-12-06 devnull _fssend(Mux *mux, void *pkt)
271 d3df3087 2003-12-06 devnull Fsys *fs;
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));
277 d3df3087 2003-12-06 devnull static void*
278 d3df3087 2003-12-06 devnull _fsrecv(Mux *mux)
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;
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;
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;
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;
306 32f69c36 2003-12-11 devnull PBIT32(pkt+n-4, nfd);
308 d3df3087 2003-12-06 devnull return pkt;