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 d3df3087 2003-12-06 devnull Fid *f, *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 d3df3087 2003-12-06 devnull for(f=fs->freefid; f; f=next){
97 d3df3087 2003-12-06 devnull next = f->next;
98 d3df3087 2003-12-06 devnull if(f->fid%Fidchunk == 0)
99 d3df3087 2003-12-06 devnull free(f);
100 d3df3087 2003-12-06 devnull }
101 d3df3087 2003-12-06 devnull free(fs);
102 d3df3087 2003-12-06 devnull }
103 d3df3087 2003-12-06 devnull qunlock(&fs->lk);
104 d3df3087 2003-12-06 devnull }
105 d3df3087 2003-12-06 devnull
106 d3df3087 2003-12-06 devnull int
107 d3df3087 2003-12-06 devnull fsversion(Fsys *fs, int msize, char *version, int nversion)
108 d3df3087 2003-12-06 devnull {
109 d3df3087 2003-12-06 devnull void *freep;
110 d3df3087 2003-12-06 devnull Fcall tx, rx;
111 d3df3087 2003-12-06 devnull
112 32f69c36 2003-12-11 devnull tx.tag = 0;
113 d3df3087 2003-12-06 devnull tx.type = Tversion;
114 d3df3087 2003-12-06 devnull tx.version = version;
115 d3df3087 2003-12-06 devnull tx.msize = msize;
116 d3df3087 2003-12-06 devnull
117 d3df3087 2003-12-06 devnull if(fsrpc(fs, &tx, &rx, &freep) < 0)
118 d3df3087 2003-12-06 devnull return -1;
119 d3df3087 2003-12-06 devnull strecpy(version, version+nversion, rx.version);
120 d3df3087 2003-12-06 devnull free(freep);
121 d3df3087 2003-12-06 devnull return rx.msize;
122 d3df3087 2003-12-06 devnull }
123 d3df3087 2003-12-06 devnull
124 d3df3087 2003-12-06 devnull Fid*
125 d3df3087 2003-12-06 devnull fsattach(Fsys *fs, Fid *afid, char *user, char *aname)
126 d3df3087 2003-12-06 devnull {
127 d3df3087 2003-12-06 devnull Fcall tx, rx;
128 d3df3087 2003-12-06 devnull Fid *fid;
129 d3df3087 2003-12-06 devnull
130 32f69c36 2003-12-11 devnull if(aname == nil)
131 32f69c36 2003-12-11 devnull aname = "";
132 32f69c36 2003-12-11 devnull
133 d3df3087 2003-12-06 devnull if((fid = _fsgetfid(fs)) == nil)
134 d3df3087 2003-12-06 devnull return nil;
135 d3df3087 2003-12-06 devnull
136 32f69c36 2003-12-11 devnull tx.tag = 0;
137 d3df3087 2003-12-06 devnull tx.type = Tattach;
138 d3df3087 2003-12-06 devnull tx.afid = afid ? afid->fid : NOFID;
139 d3df3087 2003-12-06 devnull tx.fid = fid->fid;
140 d3df3087 2003-12-06 devnull tx.uname = user;
141 d3df3087 2003-12-06 devnull tx.aname = aname;
142 d3df3087 2003-12-06 devnull
143 d3df3087 2003-12-06 devnull if(fsrpc(fs, &tx, &rx, 0) < 0){
144 d3df3087 2003-12-06 devnull _fsputfid(fid);
145 d3df3087 2003-12-06 devnull return nil;
146 d3df3087 2003-12-06 devnull }
147 d3df3087 2003-12-06 devnull fid->qid = rx.qid;
148 d3df3087 2003-12-06 devnull return fid;
149 d3df3087 2003-12-06 devnull }
150 d3df3087 2003-12-06 devnull
151 d3df3087 2003-12-06 devnull int
152 d3df3087 2003-12-06 devnull fsrpc(Fsys *fs, Fcall *tx, Fcall *rx, void **freep)
153 d3df3087 2003-12-06 devnull {
154 d3df3087 2003-12-06 devnull int n, nn;
155 d3df3087 2003-12-06 devnull void *tpkt, *rpkt;
156 d3df3087 2003-12-06 devnull
157 d3df3087 2003-12-06 devnull n = sizeS2M(tx);
158 d3df3087 2003-12-06 devnull tpkt = malloc(n);
159 ceb04770 2003-12-09 devnull if(freep)
160 ceb04770 2003-12-09 devnull *freep = nil;
161 d3df3087 2003-12-06 devnull if(tpkt == nil)
162 d3df3087 2003-12-06 devnull return -1;
163 32f69c36 2003-12-11 devnull //fprint(2, "<- %F\n", tx);
164 d3df3087 2003-12-06 devnull nn = convS2M(tx, tpkt, n);
165 d3df3087 2003-12-06 devnull if(nn != n){
166 d3df3087 2003-12-06 devnull free(tpkt);
167 d3df3087 2003-12-06 devnull werrstr("libfs: sizeS2M convS2M mismatch");
168 d3df3087 2003-12-06 devnull fprint(2, "%r\n");
169 d3df3087 2003-12-06 devnull return -1;
170 d3df3087 2003-12-06 devnull }
171 d3df3087 2003-12-06 devnull rpkt = muxrpc(&fs->mux, tpkt);
172 d3df3087 2003-12-06 devnull free(tpkt);
173 d3df3087 2003-12-06 devnull if(rpkt == nil)
174 d3df3087 2003-12-06 devnull return -1;
175 d3df3087 2003-12-06 devnull n = GBIT32((uchar*)rpkt);
176 d3df3087 2003-12-06 devnull nn = convM2S(rpkt, n, rx);
177 d3df3087 2003-12-06 devnull if(nn != n){
178 d3df3087 2003-12-06 devnull free(rpkt);
179 32f69c36 2003-12-11 devnull werrstr("libfs: convM2S packet size mismatch %d %d", n, nn);
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 32f69c36 2003-12-11 devnull //fprint(2, "-> %F\n", rx);
184 d3df3087 2003-12-06 devnull if(rx->type == Rerror){
185 d3df3087 2003-12-06 devnull werrstr("%s", rx->ename);
186 d3df3087 2003-12-06 devnull free(rpkt);
187 d3df3087 2003-12-06 devnull return -1;
188 d3df3087 2003-12-06 devnull }
189 d3df3087 2003-12-06 devnull if(rx->type != tx->type+1){
190 d3df3087 2003-12-06 devnull werrstr("packet type mismatch -- tx %d rx %d",
191 d3df3087 2003-12-06 devnull tx->type, rx->type);
192 d3df3087 2003-12-06 devnull free(rpkt);
193 d3df3087 2003-12-06 devnull return -1;
194 d3df3087 2003-12-06 devnull }
195 d3df3087 2003-12-06 devnull if(freep)
196 d3df3087 2003-12-06 devnull *freep = rpkt;
197 d3df3087 2003-12-06 devnull else
198 d3df3087 2003-12-06 devnull free(rpkt);
199 d3df3087 2003-12-06 devnull return 0;
200 d3df3087 2003-12-06 devnull }
201 d3df3087 2003-12-06 devnull
202 d3df3087 2003-12-06 devnull Fid*
203 d3df3087 2003-12-06 devnull _fsgetfid(Fsys *fs)
204 d3df3087 2003-12-06 devnull {
205 d3df3087 2003-12-06 devnull int i;
206 d3df3087 2003-12-06 devnull Fid *f;
207 d3df3087 2003-12-06 devnull
208 d3df3087 2003-12-06 devnull qlock(&fs->lk);
209 d3df3087 2003-12-06 devnull if(fs->freefid == nil){
210 e95a7088 2003-12-09 devnull f = mallocz(sizeof(Fid)*Fidchunk, 1);
211 d3df3087 2003-12-06 devnull if(f == nil){
212 d3df3087 2003-12-06 devnull qunlock(&fs->lk);
213 d3df3087 2003-12-06 devnull return nil;
214 d3df3087 2003-12-06 devnull }
215 d3df3087 2003-12-06 devnull for(i=0; i<Fidchunk; i++){
216 d3df3087 2003-12-06 devnull f[i].fid = fs->nextfid++;
217 d3df3087 2003-12-06 devnull f[i].next = &f[i+1];
218 d3df3087 2003-12-06 devnull f[i].fs = fs;
219 d3df3087 2003-12-06 devnull }
220 d3df3087 2003-12-06 devnull f[i-1].next = nil;
221 d3df3087 2003-12-06 devnull fs->freefid = f;
222 d3df3087 2003-12-06 devnull }
223 d3df3087 2003-12-06 devnull f = fs->freefid;
224 d3df3087 2003-12-06 devnull fs->freefid = f->next;
225 32f69c36 2003-12-11 devnull fs->ref++;
226 d3df3087 2003-12-06 devnull qunlock(&fs->lk);
227 d3df3087 2003-12-06 devnull return f;
228 d3df3087 2003-12-06 devnull }
229 d3df3087 2003-12-06 devnull
230 d3df3087 2003-12-06 devnull void
231 d3df3087 2003-12-06 devnull _fsputfid(Fid *f)
232 d3df3087 2003-12-06 devnull {
233 d3df3087 2003-12-06 devnull Fsys *fs;
234 d3df3087 2003-12-06 devnull
235 d3df3087 2003-12-06 devnull fs = f->fs;
236 d3df3087 2003-12-06 devnull qlock(&fs->lk);
237 d3df3087 2003-12-06 devnull f->next = fs->freefid;
238 d3df3087 2003-12-06 devnull fs->freefid = f;
239 d3df3087 2003-12-06 devnull qunlock(&fs->lk);
240 d3df3087 2003-12-06 devnull _fsdecref(fs);
241 d3df3087 2003-12-06 devnull }
242 d3df3087 2003-12-06 devnull
243 d3df3087 2003-12-06 devnull static int
244 d3df3087 2003-12-06 devnull _fsgettag(Mux *mux, void *pkt)
245 d3df3087 2003-12-06 devnull {
246 d3df3087 2003-12-06 devnull return GBIT16((uchar*)pkt+5);
247 d3df3087 2003-12-06 devnull }
248 d3df3087 2003-12-06 devnull
249 d3df3087 2003-12-06 devnull static int
250 d3df3087 2003-12-06 devnull _fssettag(Mux *mux, void *pkt, uint tag)
251 d3df3087 2003-12-06 devnull {
252 d3df3087 2003-12-06 devnull PBIT16((uchar*)pkt+5, tag);
253 d3df3087 2003-12-06 devnull return 0;
254 d3df3087 2003-12-06 devnull }
255 d3df3087 2003-12-06 devnull
256 d3df3087 2003-12-06 devnull static int
257 d3df3087 2003-12-06 devnull _fssend(Mux *mux, void *pkt)
258 d3df3087 2003-12-06 devnull {
259 d3df3087 2003-12-06 devnull Fsys *fs;
260 d3df3087 2003-12-06 devnull
261 d3df3087 2003-12-06 devnull fs = mux->aux;
262 2277c5d7 2004-03-21 devnull return threadwrite(fs->fd, pkt, GBIT32((uchar*)pkt));
263 d3df3087 2003-12-06 devnull }
264 d3df3087 2003-12-06 devnull
265 d3df3087 2003-12-06 devnull static void*
266 d3df3087 2003-12-06 devnull _fsrecv(Mux *mux)
267 d3df3087 2003-12-06 devnull {
268 d3df3087 2003-12-06 devnull uchar *pkt;
269 d3df3087 2003-12-06 devnull uchar buf[4];
270 32f69c36 2003-12-11 devnull int n, nfd;
271 d3df3087 2003-12-06 devnull Fsys *fs;
272 d3df3087 2003-12-06 devnull
273 d3df3087 2003-12-06 devnull fs = mux->aux;
274 5a8e63b2 2004-02-29 devnull n = threadreadn(fs->fd, buf, 4);
275 d3df3087 2003-12-06 devnull if(n != 4)
276 d3df3087 2003-12-06 devnull return nil;
277 d3df3087 2003-12-06 devnull n = GBIT32(buf);
278 d3df3087 2003-12-06 devnull pkt = malloc(n+4);
279 d3df3087 2003-12-06 devnull if(pkt == nil){
280 d3df3087 2003-12-06 devnull fprint(2, "libfs out of memory reading 9p packet; here comes trouble\n");
281 d3df3087 2003-12-06 devnull return nil;
282 d3df3087 2003-12-06 devnull }
283 ceb04770 2003-12-09 devnull PBIT32(pkt, n);
284 5a8e63b2 2004-02-29 devnull if(threadreadn(fs->fd, pkt+4, n-4) != n-4){
285 d3df3087 2003-12-06 devnull free(pkt);
286 d3df3087 2003-12-06 devnull return nil;
287 d3df3087 2003-12-06 devnull }
288 d3df3087 2003-12-06 devnull if(pkt[4] == Ropenfd){
289 5a8e63b2 2004-02-29 devnull if((nfd=threadrecvfd(fs->fd)) < 0){
290 32f69c36 2003-12-11 devnull fprint(2, "recv fd error: %r\n");
291 32f69c36 2003-12-11 devnull free(pkt);
292 32f69c36 2003-12-11 devnull return nil;
293 32f69c36 2003-12-11 devnull }
294 32f69c36 2003-12-11 devnull PBIT32(pkt+n-4, nfd);
295 d3df3087 2003-12-06 devnull }
296 d3df3087 2003-12-06 devnull return pkt;
297 d3df3087 2003-12-06 devnull }