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