Blame


1 46f79934 2005-01-04 devnull /* Copyright (C) 2003 Russ Cox, Massachusetts Institute of Technology */
2 46f79934 2005-01-04 devnull /* See COPYRIGHT */
3 46f79934 2005-01-04 devnull
4 46f79934 2005-01-04 devnull #include <u.h>
5 46f79934 2005-01-04 devnull #include <libc.h>
6 46f79934 2005-01-04 devnull #include <fcall.h>
7 46f79934 2005-01-04 devnull #include <9pclient.h>
8 46f79934 2005-01-04 devnull #include <thread.h>
9 46f79934 2005-01-04 devnull #include "fsimpl.h"
10 46f79934 2005-01-04 devnull
11 46f79934 2005-01-04 devnull static int _fssend(Mux*, void*);
12 46f79934 2005-01-04 devnull static void *_fsrecv(Mux*);
13 46f79934 2005-01-04 devnull static int _fsgettag(Mux*, void*);
14 46f79934 2005-01-04 devnull static int _fssettag(Mux*, void*, uint);
15 46f79934 2005-01-04 devnull
16 59518849 2005-02-11 devnull int chatty9pclient;
17 73a5509a 2006-07-23 devnull int eofkill9pclient;
18 59518849 2005-02-11 devnull
19 46f79934 2005-01-04 devnull enum
20 46f79934 2005-01-04 devnull {
21 46f79934 2005-01-04 devnull CFidchunk = 32
22 46f79934 2005-01-04 devnull };
23 46f79934 2005-01-04 devnull
24 46f79934 2005-01-04 devnull CFsys*
25 46f79934 2005-01-04 devnull fsinit(int fd)
26 46f79934 2005-01-04 devnull {
27 46f79934 2005-01-04 devnull CFsys *fs;
28 59518849 2005-02-11 devnull int n;
29 fa325e9b 2020-01-10 cross
30 46f79934 2005-01-04 devnull fmtinstall('F', fcallfmt);
31 46f79934 2005-01-04 devnull fmtinstall('D', dirfmt);
32 46f79934 2005-01-04 devnull fmtinstall('M', dirmodefmt);
33 46f79934 2005-01-04 devnull
34 46f79934 2005-01-04 devnull fs = mallocz(sizeof(CFsys), 1);
35 2d70c581 2005-07-13 devnull if(fs == nil){
36 2d70c581 2005-07-13 devnull werrstr("mallocz: %r");
37 46f79934 2005-01-04 devnull return nil;
38 2d70c581 2005-07-13 devnull }
39 46f79934 2005-01-04 devnull fs->fd = fd;
40 46f79934 2005-01-04 devnull fs->ref = 1;
41 46f79934 2005-01-04 devnull fs->mux.aux = fs;
42 46f79934 2005-01-04 devnull fs->mux.mintag = 0;
43 46f79934 2005-01-04 devnull fs->mux.maxtag = 256;
44 46f79934 2005-01-04 devnull fs->mux.send = _fssend;
45 46f79934 2005-01-04 devnull fs->mux.recv = _fsrecv;
46 46f79934 2005-01-04 devnull fs->mux.gettag = _fsgettag;
47 46f79934 2005-01-04 devnull fs->mux.settag = _fssettag;
48 46f79934 2005-01-04 devnull fs->iorecv = ioproc();
49 46f79934 2005-01-04 devnull fs->iosend = ioproc();
50 46f79934 2005-01-04 devnull muxinit(&fs->mux);
51 fa325e9b 2020-01-10 cross
52 74dd0321 2010-12-07 rsc strcpy(fs->version, "9P2000");
53 59518849 2005-02-11 devnull if((n = fsversion(fs, 8192, fs->version, sizeof fs->version)) < 0){
54 2d70c581 2005-07-13 devnull werrstr("fsversion: %r");
55 59518849 2005-02-11 devnull _fsunmount(fs);
56 59518849 2005-02-11 devnull return nil;
57 59518849 2005-02-11 devnull }
58 59518849 2005-02-11 devnull fs->msize = n;
59 46f79934 2005-01-04 devnull return fs;
60 46f79934 2005-01-04 devnull }
61 46f79934 2005-01-04 devnull
62 46f79934 2005-01-04 devnull CFid*
63 46f79934 2005-01-04 devnull fsroot(CFsys *fs)
64 46f79934 2005-01-04 devnull {
65 46f79934 2005-01-04 devnull /* N.B. no incref */
66 46f79934 2005-01-04 devnull return fs->root;
67 46f79934 2005-01-04 devnull }
68 46f79934 2005-01-04 devnull
69 46f79934 2005-01-04 devnull CFsys*
70 46f79934 2005-01-04 devnull fsmount(int fd, char *aname)
71 46f79934 2005-01-04 devnull {
72 46f79934 2005-01-04 devnull CFsys *fs;
73 46f79934 2005-01-04 devnull CFid *fid;
74 46f79934 2005-01-04 devnull
75 46f79934 2005-01-04 devnull fs = fsinit(fd);
76 46f79934 2005-01-04 devnull if(fs == nil)
77 46f79934 2005-01-04 devnull return nil;
78 46f79934 2005-01-04 devnull
79 59518849 2005-02-11 devnull if((fid = fsattach(fs, nil, getuser(), aname)) == nil){
80 59518849 2005-02-11 devnull _fsunmount(fs);
81 59518849 2005-02-11 devnull return nil;
82 59518849 2005-02-11 devnull }
83 46f79934 2005-01-04 devnull fssetroot(fs, fid);
84 46f79934 2005-01-04 devnull return fs;
85 59518849 2005-02-11 devnull }
86 59518849 2005-02-11 devnull
87 59518849 2005-02-11 devnull void
88 59518849 2005-02-11 devnull _fsunmount(CFsys *fs)
89 59518849 2005-02-11 devnull {
90 59518849 2005-02-11 devnull fs->fd = -1;
91 59518849 2005-02-11 devnull fsunmount(fs);
92 46f79934 2005-01-04 devnull }
93 46f79934 2005-01-04 devnull
94 46f79934 2005-01-04 devnull void
95 46f79934 2005-01-04 devnull fsunmount(CFsys *fs)
96 46f79934 2005-01-04 devnull {
97 46f79934 2005-01-04 devnull fsclose(fs->root);
98 46f79934 2005-01-04 devnull fs->root = nil;
99 46f79934 2005-01-04 devnull _fsdecref(fs);
100 46f79934 2005-01-04 devnull }
101 46f79934 2005-01-04 devnull
102 46f79934 2005-01-04 devnull void
103 46f79934 2005-01-04 devnull _fsdecref(CFsys *fs)
104 46f79934 2005-01-04 devnull {
105 46f79934 2005-01-04 devnull CFid *f, **l, *next;
106 46f79934 2005-01-04 devnull
107 46f79934 2005-01-04 devnull qlock(&fs->lk);
108 46f79934 2005-01-04 devnull --fs->ref;
109 cbeb0b26 2006-04-01 devnull /*fprint(2, "fsdecref %p to %d\n", fs, fs->ref); */
110 46f79934 2005-01-04 devnull if(fs->ref == 0){
111 6135dd69 2005-01-19 devnull if(fs->fd >= 0)
112 6135dd69 2005-01-19 devnull close(fs->fd);
113 46f79934 2005-01-04 devnull /* trim the list down to just the first in each chunk */
114 46f79934 2005-01-04 devnull for(l=&fs->freefid; *l; ){
115 46f79934 2005-01-04 devnull if((*l)->fid%CFidchunk == 0)
116 46f79934 2005-01-04 devnull l = &(*l)->next;
117 46f79934 2005-01-04 devnull else
118 46f79934 2005-01-04 devnull *l = (*l)->next;
119 46f79934 2005-01-04 devnull }
120 46f79934 2005-01-04 devnull /* now free the list */
121 46f79934 2005-01-04 devnull for(f=fs->freefid; f; f=next){
122 46f79934 2005-01-04 devnull next = f->next;
123 46f79934 2005-01-04 devnull free(f);
124 46f79934 2005-01-04 devnull }
125 46f79934 2005-01-04 devnull closeioproc(fs->iorecv);
126 46f79934 2005-01-04 devnull closeioproc(fs->iosend);
127 46f79934 2005-01-04 devnull free(fs);
128 46f79934 2005-01-04 devnull return;
129 46f79934 2005-01-04 devnull }
130 46f79934 2005-01-04 devnull qunlock(&fs->lk);
131 46f79934 2005-01-04 devnull }
132 46f79934 2005-01-04 devnull
133 46f79934 2005-01-04 devnull int
134 46f79934 2005-01-04 devnull fsversion(CFsys *fs, int msize, char *version, int nversion)
135 46f79934 2005-01-04 devnull {
136 46f79934 2005-01-04 devnull void *freep;
137 46f79934 2005-01-04 devnull int r, oldmintag, oldmaxtag;
138 46f79934 2005-01-04 devnull Fcall tx, rx;
139 46f79934 2005-01-04 devnull
140 46f79934 2005-01-04 devnull tx.tag = 0;
141 46f79934 2005-01-04 devnull tx.type = Tversion;
142 46f79934 2005-01-04 devnull tx.version = version;
143 46f79934 2005-01-04 devnull tx.msize = msize;
144 46f79934 2005-01-04 devnull
145 46f79934 2005-01-04 devnull /*
146 46f79934 2005-01-04 devnull * bit of a clumsy hack -- force libmux to use NOTAG as tag.
147 46f79934 2005-01-04 devnull * version can only be sent when there are no other messages
148 46f79934 2005-01-04 devnull * outstanding on the wire, so this is more reasonable than it looks.
149 46f79934 2005-01-04 devnull */
150 46f79934 2005-01-04 devnull oldmintag = fs->mux.mintag;
151 46f79934 2005-01-04 devnull oldmaxtag = fs->mux.maxtag;
152 46f79934 2005-01-04 devnull fs->mux.mintag = NOTAG;
153 46f79934 2005-01-04 devnull fs->mux.maxtag = NOTAG+1;
154 46f79934 2005-01-04 devnull r = _fsrpc(fs, &tx, &rx, &freep);
155 46f79934 2005-01-04 devnull fs->mux.mintag = oldmintag;
156 46f79934 2005-01-04 devnull fs->mux.maxtag = oldmaxtag;
157 2d70c581 2005-07-13 devnull if(r < 0){
158 2d70c581 2005-07-13 devnull werrstr("fsrpc: %r");
159 46f79934 2005-01-04 devnull return -1;
160 2d70c581 2005-07-13 devnull }
161 46f79934 2005-01-04 devnull
162 46f79934 2005-01-04 devnull strecpy(version, version+nversion, rx.version);
163 46f79934 2005-01-04 devnull free(freep);
164 80ecfd24 2005-02-08 devnull fs->msize = rx.msize;
165 46f79934 2005-01-04 devnull return rx.msize;
166 46f79934 2005-01-04 devnull }
167 46f79934 2005-01-04 devnull
168 46f79934 2005-01-04 devnull CFid*
169 46f79934 2005-01-04 devnull fsattach(CFsys *fs, CFid *afid, char *user, char *aname)
170 46f79934 2005-01-04 devnull {
171 46f79934 2005-01-04 devnull Fcall tx, rx;
172 46f79934 2005-01-04 devnull CFid *fid;
173 46f79934 2005-01-04 devnull
174 46f79934 2005-01-04 devnull if(aname == nil)
175 46f79934 2005-01-04 devnull aname = "";
176 46f79934 2005-01-04 devnull
177 46f79934 2005-01-04 devnull if((fid = _fsgetfid(fs)) == nil)
178 46f79934 2005-01-04 devnull return nil;
179 46f79934 2005-01-04 devnull
180 46f79934 2005-01-04 devnull tx.tag = 0;
181 46f79934 2005-01-04 devnull tx.type = Tattach;
182 46f79934 2005-01-04 devnull tx.afid = afid ? afid->fid : NOFID;
183 46f79934 2005-01-04 devnull tx.fid = fid->fid;
184 46f79934 2005-01-04 devnull tx.uname = user;
185 46f79934 2005-01-04 devnull tx.aname = aname;
186 46f79934 2005-01-04 devnull
187 46f79934 2005-01-04 devnull if(_fsrpc(fs, &tx, &rx, 0) < 0){
188 46f79934 2005-01-04 devnull _fsputfid(fid);
189 46f79934 2005-01-04 devnull return nil;
190 46f79934 2005-01-04 devnull }
191 46f79934 2005-01-04 devnull fid->qid = rx.qid;
192 46f79934 2005-01-04 devnull return fid;
193 46f79934 2005-01-04 devnull }
194 46f79934 2005-01-04 devnull
195 46f79934 2005-01-04 devnull void
196 46f79934 2005-01-04 devnull fssetroot(CFsys *fs, CFid *fid)
197 46f79934 2005-01-04 devnull {
198 46f79934 2005-01-04 devnull if(fs->root)
199 46f79934 2005-01-04 devnull _fsputfid(fs->root);
200 46f79934 2005-01-04 devnull fs->root = fid;
201 46f79934 2005-01-04 devnull }
202 46f79934 2005-01-04 devnull
203 46f79934 2005-01-04 devnull int
204 46f79934 2005-01-04 devnull _fsrpc(CFsys *fs, Fcall *tx, Fcall *rx, void **freep)
205 46f79934 2005-01-04 devnull {
206 46f79934 2005-01-04 devnull int n, nn;
207 46f79934 2005-01-04 devnull void *tpkt, *rpkt;
208 46f79934 2005-01-04 devnull
209 74dd0321 2010-12-07 rsc n = sizeS2M(tx);
210 46f79934 2005-01-04 devnull tpkt = malloc(n);
211 46f79934 2005-01-04 devnull if(freep)
212 46f79934 2005-01-04 devnull *freep = nil;
213 46f79934 2005-01-04 devnull if(tpkt == nil)
214 46f79934 2005-01-04 devnull return -1;
215 59518849 2005-02-11 devnull tx->tag = 0;
216 59518849 2005-02-11 devnull if(chatty9pclient)
217 59518849 2005-02-11 devnull fprint(2, "<- %F\n", tx);
218 74dd0321 2010-12-07 rsc nn = convS2M(tx, tpkt, n);
219 46f79934 2005-01-04 devnull if(nn != n){
220 46f79934 2005-01-04 devnull free(tpkt);
221 2d70c581 2005-07-13 devnull werrstr("lib9pclient: sizeS2M convS2M mismatch");
222 46f79934 2005-01-04 devnull fprint(2, "%r\n");
223 46f79934 2005-01-04 devnull return -1;
224 46f79934 2005-01-04 devnull }
225 46f79934 2005-01-04 devnull rpkt = muxrpc(&fs->mux, tpkt);
226 46f79934 2005-01-04 devnull free(tpkt);
227 2d70c581 2005-07-13 devnull if(rpkt == nil){
228 2d70c581 2005-07-13 devnull werrstr("muxrpc: %r");
229 46f79934 2005-01-04 devnull return -1;
230 2d70c581 2005-07-13 devnull }
231 46f79934 2005-01-04 devnull n = GBIT32((uchar*)rpkt);
232 74dd0321 2010-12-07 rsc nn = convM2S(rpkt, n, rx);
233 46f79934 2005-01-04 devnull if(nn != n){
234 46f79934 2005-01-04 devnull free(rpkt);
235 2d70c581 2005-07-13 devnull werrstr("lib9pclient: convM2S packet size mismatch %d %d", n, nn);
236 46f79934 2005-01-04 devnull fprint(2, "%r\n");
237 46f79934 2005-01-04 devnull return -1;
238 46f79934 2005-01-04 devnull }
239 59518849 2005-02-11 devnull if(chatty9pclient)
240 59518849 2005-02-11 devnull fprint(2, "-> %F\n", rx);
241 46f79934 2005-01-04 devnull if(rx->type == Rerror){
242 46f79934 2005-01-04 devnull werrstr("%s", rx->ename);
243 46f79934 2005-01-04 devnull free(rpkt);
244 46f79934 2005-01-04 devnull return -1;
245 46f79934 2005-01-04 devnull }
246 46f79934 2005-01-04 devnull if(rx->type != tx->type+1){
247 46f79934 2005-01-04 devnull werrstr("packet type mismatch -- tx %d rx %d",
248 46f79934 2005-01-04 devnull tx->type, rx->type);
249 46f79934 2005-01-04 devnull free(rpkt);
250 46f79934 2005-01-04 devnull return -1;
251 46f79934 2005-01-04 devnull }
252 46f79934 2005-01-04 devnull if(freep)
253 46f79934 2005-01-04 devnull *freep = rpkt;
254 46f79934 2005-01-04 devnull else
255 46f79934 2005-01-04 devnull free(rpkt);
256 46f79934 2005-01-04 devnull return 0;
257 46f79934 2005-01-04 devnull }
258 46f79934 2005-01-04 devnull
259 46f79934 2005-01-04 devnull CFid*
260 46f79934 2005-01-04 devnull _fsgetfid(CFsys *fs)
261 46f79934 2005-01-04 devnull {
262 46f79934 2005-01-04 devnull int i;
263 46f79934 2005-01-04 devnull CFid *f;
264 46f79934 2005-01-04 devnull
265 46f79934 2005-01-04 devnull qlock(&fs->lk);
266 46f79934 2005-01-04 devnull if(fs->freefid == nil){
267 46f79934 2005-01-04 devnull f = mallocz(sizeof(CFid)*CFidchunk, 1);
268 46f79934 2005-01-04 devnull if(f == nil){
269 46f79934 2005-01-04 devnull qunlock(&fs->lk);
270 46f79934 2005-01-04 devnull return nil;
271 46f79934 2005-01-04 devnull }
272 46f79934 2005-01-04 devnull for(i=0; i<CFidchunk; i++){
273 46f79934 2005-01-04 devnull f[i].fid = fs->nextfid++;
274 46f79934 2005-01-04 devnull f[i].next = &f[i+1];
275 46f79934 2005-01-04 devnull f[i].fs = fs;
276 46f79934 2005-01-04 devnull }
277 46f79934 2005-01-04 devnull f[i-1].next = nil;
278 46f79934 2005-01-04 devnull fs->freefid = f;
279 46f79934 2005-01-04 devnull }
280 46f79934 2005-01-04 devnull f = fs->freefid;
281 46f79934 2005-01-04 devnull fs->freefid = f->next;
282 46f79934 2005-01-04 devnull fs->ref++;
283 46f79934 2005-01-04 devnull qunlock(&fs->lk);
284 33baa59e 2005-01-28 devnull f->offset = 0;
285 33baa59e 2005-01-28 devnull f->mode = -1;
286 33baa59e 2005-01-28 devnull f->qid.path = 0;
287 33baa59e 2005-01-28 devnull f->qid.vers = 0;
288 33baa59e 2005-01-28 devnull f->qid.type = 0;
289 46f79934 2005-01-04 devnull return f;
290 46f79934 2005-01-04 devnull }
291 46f79934 2005-01-04 devnull
292 46f79934 2005-01-04 devnull void
293 46f79934 2005-01-04 devnull _fsputfid(CFid *f)
294 46f79934 2005-01-04 devnull {
295 46f79934 2005-01-04 devnull CFsys *fs;
296 46f79934 2005-01-04 devnull
297 46f79934 2005-01-04 devnull fs = f->fs;
298 46f79934 2005-01-04 devnull qlock(&fs->lk);
299 46f79934 2005-01-04 devnull f->next = fs->freefid;
300 46f79934 2005-01-04 devnull fs->freefid = f;
301 46f79934 2005-01-04 devnull qunlock(&fs->lk);
302 46f79934 2005-01-04 devnull _fsdecref(fs);
303 46f79934 2005-01-04 devnull }
304 46f79934 2005-01-04 devnull
305 46f79934 2005-01-04 devnull static int
306 46f79934 2005-01-04 devnull _fsgettag(Mux *mux, void *pkt)
307 46f79934 2005-01-04 devnull {
308 46f79934 2005-01-04 devnull return GBIT16((uchar*)pkt+5);
309 46f79934 2005-01-04 devnull }
310 46f79934 2005-01-04 devnull
311 46f79934 2005-01-04 devnull static int
312 46f79934 2005-01-04 devnull _fssettag(Mux *mux, void *pkt, uint tag)
313 46f79934 2005-01-04 devnull {
314 46f79934 2005-01-04 devnull PBIT16((uchar*)pkt+5, tag);
315 46f79934 2005-01-04 devnull return 0;
316 46f79934 2005-01-04 devnull }
317 46f79934 2005-01-04 devnull
318 46f79934 2005-01-04 devnull static int
319 46f79934 2005-01-04 devnull _fssend(Mux *mux, void *pkt)
320 46f79934 2005-01-04 devnull {
321 46f79934 2005-01-04 devnull CFsys *fs;
322 73a5509a 2006-07-23 devnull int n;
323 46f79934 2005-01-04 devnull
324 46f79934 2005-01-04 devnull fs = mux->aux;
325 73a5509a 2006-07-23 devnull n = iowrite(fs->iosend, fs->fd, pkt, GBIT32((uchar*)pkt));
326 73a5509a 2006-07-23 devnull if(n < 0 && eofkill9pclient)
327 73a5509a 2006-07-23 devnull threadexitsall(nil);
328 73a5509a 2006-07-23 devnull return n;
329 46f79934 2005-01-04 devnull }
330 46f79934 2005-01-04 devnull
331 46f79934 2005-01-04 devnull static void*
332 46f79934 2005-01-04 devnull _fsrecv(Mux *mux)
333 46f79934 2005-01-04 devnull {
334 46f79934 2005-01-04 devnull uchar *pkt;
335 46f79934 2005-01-04 devnull uchar buf[4];
336 46f79934 2005-01-04 devnull int n, nfd;
337 46f79934 2005-01-04 devnull CFsys *fs;
338 46f79934 2005-01-04 devnull
339 46f79934 2005-01-04 devnull fs = mux->aux;
340 46f79934 2005-01-04 devnull n = ioreadn(fs->iorecv, fs->fd, buf, 4);
341 73a5509a 2006-07-23 devnull if(n != 4){
342 73a5509a 2006-07-23 devnull if(eofkill9pclient)
343 73a5509a 2006-07-23 devnull threadexitsall(nil);
344 46f79934 2005-01-04 devnull return nil;
345 73a5509a 2006-07-23 devnull }
346 46f79934 2005-01-04 devnull n = GBIT32(buf);
347 46f79934 2005-01-04 devnull pkt = malloc(n+4);
348 46f79934 2005-01-04 devnull if(pkt == nil){
349 2d70c581 2005-07-13 devnull fprint(2, "lib9pclient out of memory reading 9p packet; here comes trouble\n");
350 46f79934 2005-01-04 devnull return nil;
351 46f79934 2005-01-04 devnull }
352 46f79934 2005-01-04 devnull PBIT32(pkt, n);
353 46f79934 2005-01-04 devnull if(ioreadn(fs->iorecv, fs->fd, pkt+4, n-4) != n-4){
354 46f79934 2005-01-04 devnull free(pkt);
355 46f79934 2005-01-04 devnull return nil;
356 46f79934 2005-01-04 devnull }
357 46f79934 2005-01-04 devnull if(pkt[4] == Ropenfd){
358 46f79934 2005-01-04 devnull if((nfd=iorecvfd(fs->iorecv, fs->fd)) < 0){
359 46f79934 2005-01-04 devnull fprint(2, "recv fd error: %r\n");
360 46f79934 2005-01-04 devnull free(pkt);
361 46f79934 2005-01-04 devnull return nil;
362 46f79934 2005-01-04 devnull }
363 46f79934 2005-01-04 devnull PBIT32(pkt+n-4, nfd);
364 46f79934 2005-01-04 devnull }
365 46f79934 2005-01-04 devnull return pkt;
366 46f79934 2005-01-04 devnull }
367 73a5509a 2006-07-23 devnull
368 73a5509a 2006-07-23 devnull Qid
369 73a5509a 2006-07-23 devnull fsqid(CFid *fid)
370 73a5509a 2006-07-23 devnull {
371 73a5509a 2006-07-23 devnull return fid->qid;
372 73a5509a 2006-07-23 devnull }