📄 exportfs.c
字号:
char buf[128]; l = &fidhash(nr); for(f = *l; f; f = f->next) { if(f->nr == nr) { if(f->mid) { sprint(buf, "/mnt/exportfs/%d", f->mid); unmount(0, buf); psmap[f->mid] = 0; } if(f->f) { freefile(f->f); f->f = nil; } if(f->dir){ free(f->dir); f->dir = nil; } *l = f->next; f->next = fidfree; fidfree = f; return 1; } l = &f->next; } return 0; }Fid *newfid(int nr){ Fid *new, **l; int i; l = &fidhash(nr); for(new = *l; new; new = new->next) if(new->nr == nr) return 0; if(fidfree == 0) { fidfree = emallocz(sizeof(Fid) * Fidchunk); for(i = 0; i < Fidchunk-1; i++) fidfree[i].next = &fidfree[i+1]; fidfree[Fidchunk-1].next = 0; } new = fidfree; fidfree = new->next; memset(new, 0, sizeof(Fid)); new->next = *l; *l = new; new->nr = nr; new->fid = -1; new->mid = 0; return new; }Fsrpc *getsbuf(void){ static int ap; int look, rounds; Fsrpc *wb; int small_instead_of_fast = 1; if(small_instead_of_fast) ap = 0; /* so we always start looking at the beginning and reuse buffers */ for(rounds = 0; rounds < 10; rounds++) { for(look = 0; look < Nr_workbufs; look++) { if(++ap == Nr_workbufs) ap = 0; if(Workq[ap].busy == 0) break; } if(look == Nr_workbufs){ sleep(10 * rounds); continue; } wb = &Workq[ap]; wb->pid = 0; wb->canint = 0; wb->flushtag = NOTAG; wb->busy = 1; if(wb->buf == nil) /* allocate buffers dynamically to keep size down */ wb->buf = emallocz(messagesize); return wb; } fatal("No more work buffers"); return nil;}voidfreefile(File *f){ File *parent, *child;Loop: f->ref--; if(f->ref > 0) return; freecnt++; if(f->ref < 0) abort(); DEBUG(DFD, "free %s\n", f->name); /* delete from parent */ parent = f->parent; if(parent->child == f) parent->child = f->childlist; else{ for(child=parent->child; child->childlist!=f; child=child->childlist) if(child->childlist == nil) fatal("bad child list"); child->childlist = f->childlist; } freeqid(f->qidt); free(f->name); f->name = nil; free(f); f = parent; if(f != nil) goto Loop;}File *file(File *parent, char *name){ Dir *dir; char *path; File *f; DEBUG(DFD, "\tfile: 0x%p %s name %s\n", parent, parent->name, name); path = makepath(parent, name); if(patternfile != nil && excludefile(path)){ free(path); return nil; } dir = dirstat(path); free(path); if(dir == nil) return nil; for(f = parent->child; f; f = f->childlist) if(strcmp(name, f->name) == 0) break; if(f == nil){ f = emallocz(sizeof(File)); f->name = estrdup(name); f->parent = parent; f->childlist = parent->child; parent->child = f; parent->ref++; f->ref = 0; filecnt++; } f->ref++; f->qid.type = dir->qid.type; f->qid.vers = dir->qid.vers; f->qidt = uniqueqid(dir); f->qid.path = f->qidt->uniqpath; f->inval = 0; free(dir); return f;}voidinitroot(void){ Dir *dir; root = emallocz(sizeof(File)); root->name = estrdup("."); dir = dirstat(root->name); if(dir == nil) fatal("root stat"); root->ref = 1; root->qid.vers = dir->qid.vers; root->qidt = uniqueqid(dir); root->qid.path = root->qidt->uniqpath; root->qid.type = QTDIR; free(dir); psmpt = emallocz(sizeof(File)); psmpt->name = estrdup("/"); dir = dirstat(psmpt->name); if(dir == nil) return; psmpt->ref = 1; psmpt->qid.vers = dir->qid.vers; psmpt->qidt = uniqueqid(dir); psmpt->qid.path = psmpt->qidt->uniqpath; free(dir); psmpt = file(psmpt, "mnt"); if(psmpt == 0) return; psmpt = file(psmpt, "exportfs");}char*makepath(File *p, char *name){ int i, n; char *c, *s, *path, *seg[256]; seg[0] = name; n = strlen(name)+2; for(i = 1; i < 256 && p; i++, p = p->parent){ seg[i] = p->name; n += strlen(p->name)+1; } path = malloc(n); if(path == nil) fatal("out of memory"); s = path; while(i--) { for(c = seg[i]; *c; c++) *s++ = *c; *s++ = '/'; } while(s[-1] == '/') s--; *s = '\0'; return path;}intqidhash(vlong path){ int h, n; h = 0; for(n=0; n<64; n+=Nqidbits){ h ^= path; path >>= Nqidbits; } return h & (Nqidtab-1);}voidfreeqid(Qidtab *q){ ulong h; Qidtab *l; q->ref--; if(q->ref > 0) return; qfreecnt++; h = qidhash(q->path); if(qidtab[h] == q) qidtab[h] = q->next; else{ for(l=qidtab[h]; l->next!=q; l=l->next) if(l->next == nil) fatal("bad qid list"); l->next = q->next; } free(q);}Qidtab*qidlookup(Dir *d){ ulong h; Qidtab *q; h = qidhash(d->qid.path); for(q=qidtab[h]; q!=nil; q=q->next) if(q->type==d->type && q->dev==d->dev && q->path==d->qid.path) return q; return nil;}intqidexists(vlong path){ int h; Qidtab *q; for(h=0; h<Nqidtab; h++) for(q=qidtab[h]; q!=nil; q=q->next) if(q->uniqpath == path) return 1; return 0;}Qidtab*uniqueqid(Dir *d){ ulong h; vlong path; Qidtab *q; q = qidlookup(d); if(q != nil){ q->ref++; return q; } path = d->qid.path; while(qidexists(path)){ DEBUG(DFD, "collision on %s\n", d->name); /* collision: find a new one */ ncollision++; path &= QIDPATH; ++newqid; if(newqid >= (1<<16)){ DEBUG(DFD, "collision wraparound\n"); newqid = 1; } path |= newqid<<48; DEBUG(DFD, "assign qid %.16llux\n", path); } q = mallocz(sizeof(Qidtab), 1); if(q == nil) fatal("no memory for qid table"); qidcnt++; q->ref = 1; q->type = d->type; q->dev = d->dev; q->path = d->qid.path; q->uniqpath = path; h = qidhash(d->qid.path); q->next = qidtab[h]; qidtab[h] = q; return q;}voidfatal(char *s, ...){ char buf[ERRMAX]; va_list arg; Proc *m; if (s) { va_start(arg, s); vsnprint(buf, ERRMAX, s, arg); va_end(arg); } /* Clear away the slave children */ for(m = Proclist; m; m = m->next) postnote(PNPROC, m->pid, "kill"); DEBUG(DFD, "%s\n", buf); if (s) sysfatal(buf); else exits(nil);}void*emallocz(uint n){ void *p; p = mallocz(n, 1); if(p == nil) fatal(Enomem); return p;}char*estrdup(char *s){ char *t; t = strdup(s); if(t == nil) fatal(Enomem); return t;}/* Network on fd1, mount driver on fd0 */intfilter(int fd, char *cmd){ int p[2], lfd, len, nb, argc; char newport[128], buf[128], devdir[40], *s, *file, *argv[16]; // Get a free port and post it to the client. if (announce(anstring, devdir) < 0) sysfatal("filter: Cannot announce %s: %r\n", anstring); snprint(buf, sizeof(buf), "%s/local", devdir); buf[sizeof buf - 1] = '\0'; if ((lfd = open(buf, OREAD)) < 0) sysfatal("filter: Cannot open %s: %r\n", buf); if ((len = read(lfd, newport, sizeof newport - 1)) < 0) sysfatal("filter: Cannot read %s: %r\n", buf); close(lfd); newport[len] = '\0'; if ((s = strchr(newport, '\n')) != nil) *s = '\0'; if ((nb = write(fd, newport, len)) < 0) sysfatal("getport; cannot write port; %r"); assert(nb == len); argc = tokenize(cmd, argv, nelem(argv)-2); if (argc == 0) sysfatal("filter: empty command"); argv[argc++] = buf; argv[argc] = nil; file = argv[0]; if (s = strrchr(argv[0], '/')) argv[0] = s+1; if(pipe(p) < 0) fatal("pipe"); switch(rfork(RFNOWAIT|RFPROC|RFFDG)) { case -1: fatal("rfork record module"); case 0: if (dup(p[0], 1) < 0) fatal("filter: Cannot dup to 1; %r\n"); if (dup(p[0], 0) < 0) fatal("filter: Cannot dup to 0; %r\n"); close(p[0]); close(p[1]); exec(file, argv); fatal("exec record module"); default: close(fd); close(p[0]); } return p[1]; }static voidmksecret(char *t, uchar *f){ sprint(t, "%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux", f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7], f[8], f[9]);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -