⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 exportfs.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 + -