7 #define QIDPATH ((1LL<<48)-1)
10 void (*fcalls[])(Fsrpc*) =
27 /* accounting and debugging counters */
36 * Start serving file requests from the network
46 n = read9pmsg(0, r->buf, messagesize);
49 if(convM2S(r->buf, n, &r->work) != n)
50 fatal("convM2S format error");
52 DEBUG(2, "%F\n", &r->work);
53 (fcalls[r->work.type])(r);
58 reply(Fcall *r, Fcall *t, char *err)
70 t->type = r->type + 1;
72 DEBUG(2, "\t%F\n", t);
74 data = malloc(messagesize); /* not mallocz; no need to clear */
77 n = convS2M(t, data, messagesize);
78 if(write(1, data, n) != n){
79 /* not fatal, might have got a note due to flush */
80 fprint(2, "exportfs: short write in reply: %r\n");
94 r->work.type = Rerror;
96 n = convS2M(&r->work, r->buf, messagesize);
106 for(f = fidhash(nr); f != nil; f = f->next)
120 for(f = *l; f != nil; f = f->next) {
123 snprint(buf, sizeof(buf), "/mnt/exportfs/%d", f->mid);
153 for(new = *l; new != nil; new = new->next)
158 fidfree = emallocz(sizeof(Fid) * Fidchunk);
160 for(i = 0; i < Fidchunk-1; i++)
161 fidfree[i].next = &fidfree[i+1];
163 fidfree[Fidchunk-1].next = nil;
169 memset(new, 0, sizeof(Fid));
196 sbufalloc.free = w->next;
203 w = emallocz(sizeof(*w) + messagesize);
214 w->next = sbufalloc.free;
223 File *parent, *child;
225 while(--f->ref == 0){
227 DEBUG(2, "free %s\n", f->name);
228 /* delete from parent */
230 if(parent->child == f)
231 parent->child = f->childlist;
233 for(child = parent->child; child->childlist != f; child = child->childlist) {
234 if(child->childlist == nil)
235 fatal("bad child list");
237 child->childlist = f->childlist;
247 file(File *parent, char *name)
253 DEBUG(2, "\tfile: 0x%p %s name %s\n", parent, parent->name, name);
255 path = makepath(parent, name);
256 if(patternfile != nil && excludefile(path)){
265 for(f = parent->child; f != nil; f = f->childlist)
266 if(strcmp(name, f->name) == 0)
270 f = emallocz(sizeof(File));
271 f->name = estrdup(name);
274 f->childlist = parent->child;
281 f->qid.type = dir->qid.type;
282 f->qid.vers = dir->qid.vers;
283 f->qidt = uniqueqid(dir);
284 f->qid.path = f->qidt->uniqpath;
298 root = emallocz(sizeof(File));
299 root->name = estrdup(".");
301 dir = dirstat(root->name);
306 root->qid.vers = dir->qid.vers;
307 root->qidt = uniqueqid(dir);
308 root->qid.path = root->qidt->uniqpath;
309 root->qid.type = QTDIR;
312 psmpt = emallocz(sizeof(File));
313 psmpt->name = estrdup("/");
315 dir = dirstat(psmpt->name);
320 psmpt->qid.vers = dir->qid.vers;
321 psmpt->qidt = uniqueqid(dir);
322 psmpt->qid.path = psmpt->qidt->uniqpath;
325 psmpt = file(psmpt, "mnt");
328 psmpt = file(psmpt, "exportfs");
332 makepath(File *p, char *name)
335 char *c, *s, *path, *seg[256];
339 for(i = 1; i < 256 && p; i++, p = p->parent){
341 n += strlen(p->name)+1;
347 for(c = seg[i]; *c; c++)
364 for(n=0; n<64; n+=Nqidbits){
368 return h & (Nqidtab-1);
380 h = qidhash(q->path);
384 for(l=qidtab[h]; l->next!=q; l=l->next)
386 fatal("bad qid list");
398 h = qidhash(d->qid.path);
399 for(q=qidtab[h]; q!=nil; q=q->next)
400 if(q->type==d->type && q->dev==d->dev && q->path==d->qid.path)
406 qidexists(vlong path)
411 for(h=0; h<Nqidtab; h++)
412 for(q=qidtab[h]; q!=nil; q=q->next)
413 if(q->uniqpath == path)
431 while(qidexists(path)){
432 DEBUG(2, "collision on %s\n", d->name);
433 /* collision: find a new one */
437 if(newqid >= (1<<16)){
438 DEBUG(2, "collision wraparound\n");
442 DEBUG(2, "assign qid %.16llux\n", path);
445 q = emallocz(sizeof(Qidtab));
449 q->path = d->qid.path;
451 h = qidhash(d->qid.path);
466 vsnprint(buf, ERRMAX, s, arg);
470 /* Clear away the slave children */
471 for(m = Proclist; m != nil; m = m->next)
472 postnote(PNPROC, m->pid, "kill");
475 DEBUG(2, "%s\n", buf);
476 sysfatal("%s", buf); /* caution: buf could contain '%' */
489 setmalloctag(p, getcallerpc(&n));
501 setmalloctag(t, getcallerpc(&s));