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

📄 cfs.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
}voidrclunk(Mfile *mf){	if(!mf->busy){		sendreply(0);		return;	}	mf->busy = 0;	delegate();}voidrremove(Mfile *mf){	if(statson && ctltest(mf)){		sendreply("not removed");		return;	}	mf->busy = 0;	delegate();}voidrread(Mfile *mf){	int cnt;	long off, first;	char *cp;	Ibuf *b;	long n;	char data[MAXFDATA];	int done;	first = off = c.thdr.offset;	cnt = c.thdr.count;	if(statson && ctltest(mf)){		if(cnt > statlen-off)			c.rhdr.count = statlen-off;		else			c.rhdr.count = cnt;		if((int)c.rhdr.count < 0){			sendreply("eof");			return;		}		c.rhdr.data = statbuf + off;		sendreply(0);		return;	}	if(mf->qid.type & (QTDIR|QTAUTH)){		delegate();		if (statson) {			cfsstat.ndirread++;			if(c.rhdr.count > 0){				cfsstat.bytesread += c.rhdr.count;				cfsstat.bytesfromdirs += c.rhdr.count;			}		}		return;	}	b = iget(&ic, mf->qid);	if(b == 0){		DPRINT(2, "delegating read\n");		delegate();		if (statson){			cfsstat.ndelegateread++;			if(c.rhdr.count > 0){				cfsstat.bytesread += c.rhdr.count;				cfsstat.bytesfromserver += c.rhdr.count;			}		}		return;	}	cp = data;	done = 0;	while(cnt>0 && !done){		if(off >= b->inode.length){			DPRINT(2, "offset %ld greater than length %lld\n", off, b->inode.length);			break;		}		n = fread(&ic, b, cp, off, cnt);		if(n <= 0){			n = -n;			if(n==0 || n>cnt)				n = cnt;			DPRINT(2, "fetch %ld bytes of data from server at offset %ld\n", n, off);			s.thdr.type = c.thdr.type;			s.thdr.fid = c.thdr.fid;			s.thdr.tag = c.thdr.tag;			s.thdr.offset = off;			s.thdr.count = n;			if(statson){				cfsstat.ndelegateread++;			}			if(askserver() < 0){				sendreply(s.rhdr.ename);				return;			}			if(s.rhdr.count != n)				done = 1;			n = s.rhdr.count;			if(n == 0){				/* end of file */				if(b->inode.length > off){					DPRINT(2, "file %llud.%ld, length %ld\n",						b->inode.qid.path, b->inode.qid.vers, off);					b->inode.length = off;				}				break;			}			memmove(cp, s.rhdr.data, n);			fwrite(&ic, b, cp, off, n);			if (statson){				cfsstat.bytestocache += n;				cfsstat.bytesfromserver += n;			}		}else{			DPRINT(2, "fetched %ld bytes from cache\n", n);			if(statson){				cfsstat.bytesfromcache += n;			}		}		cnt -= n;		off += n;		cp += n;	}	c.rhdr.data = data;	c.rhdr.count = off - first;	if(statson){		cfsstat.bytesread += c.rhdr.count;	}	sendreply(0);}voidrwrite(Mfile *mf){	Ibuf *b;	char buf[MAXFDATA];	if(statson && ctltest(mf)){		sendreply("read only");		return;	}	if(mf->qid.type & (QTDIR|QTAUTH)){		delegate();		if(statson && c.rhdr.count > 0)			cfsstat.byteswritten += c.rhdr.count;		return;	}	memmove(buf, c.thdr.data, c.thdr.count);	if(delegate() < 0)		return;	if(s.rhdr.count > 0)		cfsstat.byteswritten += s.rhdr.count;	if(mf->qid.type & QTAPPEND)	/* don't modify our cache for append-only data; always read from server*/		return;	b = iget(&ic, mf->qid);	if(b == 0)		return;	if (b->inode.length < c.thdr.offset + s.rhdr.count)		b->inode.length = c.thdr.offset + s.rhdr.count;	mf->qid.vers++;	if (s.rhdr.count != c.thdr.count)		syslog(0, "cfslog", "rhdr.count %ud, thdr.count %ud\n",			s.rhdr.count, c.thdr.count);	if(fwrite(&ic, b, buf, c.thdr.offset, s.rhdr.count) == s.rhdr.count){		iinc(&ic, b);		if(statson)			cfsstat.bytestocache += s.rhdr.count;	}}voidrstat(Mfile *mf){	Dir d;		if(statson && ctltest(mf)){		genstats();		d.qid = ctlqid;		d.mode = 0444;		d.length = statlen;	/* would be nice to do better */		d.name = "cfsctl";		d.uid = "none";		d.gid = "none";		d.muid = "none";		d.atime = time(nil);		d.mtime = d.atime;		c.rhdr.nstat = convD2M(&d, c.rhdr.stat, sizeof(c.rhdr) - (c.rhdr.stat - (uchar*)&c.rhdr));		sendreply(0);		return;	}	if(delegate() == 0){		Ibuf *b;		convM2D(s.rhdr.stat, s.rhdr.nstat , &d, nil);		mf->qid = d.qid;		b = iget(&ic, mf->qid);		if(b)			b->inode.length = d.length;	}}voidrwstat(Mfile *mf){	Ibuf *b;	if(statson && ctltest(mf)){		sendreply("read only");		return;	}	delegate();	if(b = iget(&ic, mf->qid))		b->inode.length = MAXLEN;}voiderror(char *fmt, ...) {	va_list arg;	static char buf[2048];	va_start(arg, fmt);	vseprint(buf, buf+sizeof(buf), fmt, arg);	va_end(arg);	fprint(2, "%s: %s\n", argv0, buf);	exits("error");}voidwarning(char *s){	fprint(2, "cfs: %s: %r\n", s);}/* *  send a reply to the client */voidsendreply(char *err){	if(err){		c.rhdr.type = Rerror;		c.rhdr.ename = err;	}else{		c.rhdr.type = c.thdr.type+1;		c.rhdr.fid = c.thdr.fid;	}	c.rhdr.tag = c.thdr.tag;	sendmsg(&c, &c.rhdr);}/* *  send a request to the server, get the reply, and send that to *  the client */intdelegate(void){	int type;	type = c.thdr.type;	if(statson){		cfsstat.sm[type].n++;		cfsstat.sm[type].s = nsec();	}	sendmsg(&s, &c.thdr);	rcvmsg(&s, &s.rhdr);	if(statson){		cfsstat.sm[type].t += nsec() - cfsstat.sm[type].s;	}	sendmsg(&c, &s.rhdr);	return c.thdr.type+1 == s.rhdr.type ? 0 : -1;}/* *  send a request to the server and get a reply */intaskserver(void){	int type;	s.thdr.tag = c.thdr.tag;	type = s.thdr.type;	if(statson){		cfsstat.sm[type].n++;		cfsstat.sm[type].s = nsec();	}	sendmsg(&s, &s.thdr);	rcvmsg(&s, &s.rhdr);	if(statson){		cfsstat.sm[type].t += nsec() - cfsstat.sm[type].s;	}	return s.thdr.type+1 == s.rhdr.type ? 0 : -1;}/* *  send/receive messages with logging */voidsendmsg(P9fs *p, Fcall *f){	DPRINT(2, "->%s: %F\n", p->name, f);	p->len = convS2M(f, datasnd, messagesize);	if(p->len <= 0)		error("convS2M");	if(write(p->fd[1], datasnd, p->len)!=p->len)		error("sendmsg");}voiddump(uchar *p, int len){	fprint(2, "%d bytes", len);	while(len > 0){		fprint(2, " %.2ux", *p++);		len--;	}	fprint(2, "\n");}voidrcvmsg(P9fs *p, Fcall *f){	int olen, rlen;	char buf[128];	olen = p->len;	p->len = read9pmsg(p->fd[0], datarcv, sizeof(datarcv));	if(p->len <= 0){		sprint(buf, "read9pmsg(%d)->%ld: %r", p->fd[0], p->len);		error(buf);	}	if((rlen = convM2S(datarcv, p->len, f)) != p->len)		error("rcvmsg format error, expected length %d, got %d", rlen, p->len);	if(f->fid >= Nfid){		fprint(2, "<-%s: %d %s on %d\n", p->name, f->type,			mname[f->type]? mname[f->type] : "mystery",			f->fid);		dump((uchar*)datasnd, olen);		dump((uchar*)datarcv, p->len);		error("rcvmsg fid out of range");	}	DPRINT(2, "<-%s: %F\n", p->name, f);}intctltest(Mfile *mf){	return mf->busy && mf->qid.type == ctlqid.type && mf->qid.path == ctlqid.path;}voidgenstats(void){	int i;	char *p;	p = statbuf;	p += snprint(p, sizeof(statbuf)+statbuf-p, "        Client                          Server\n");	p += snprint(p, sizeof(statbuf)+statbuf-p, "   #calls     Δ  ms/call    Δ      #calls     Δ  ms/call    Δ\n");	for (i = 0; i < nelem(cfsstat.cm); i++)		if(cfsstat.cm[i].n || cfsstat.sm[i].n) {			p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud ",				cfsstat.cm[i].n, cfsstat.cm[i].n - cfsprev.cm[i].n);			if (cfsstat.cm[i].n)				p += snprint(p, sizeof(statbuf)+statbuf-p, "%7.3f ",					0.000001*cfsstat.cm[i].t/cfsstat.cm[i].n);			else				p += snprint(p, sizeof(statbuf)+statbuf-p, "        ");			if(cfsstat.cm[i].n - cfsprev.cm[i].n)				p += snprint(p, sizeof(statbuf)+statbuf-p, "%7.3f ",					0.000001*(cfsstat.cm[i].t - cfsprev.cm[i].t)/(cfsstat.cm[i].n - cfsprev.cm[i].n));			else				p += snprint(p, sizeof(statbuf)+statbuf-p, "        ");			p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud ",				cfsstat.sm[i].n, cfsstat.sm[i].n - cfsprev.sm[i].n);			if (cfsstat.sm[i].n)				p += snprint(p, sizeof(statbuf)+statbuf-p, "%7.3f ",					0.000001*cfsstat.sm[i].t/cfsstat.sm[i].n);			else				p += snprint(p, sizeof(statbuf)+statbuf-p, "        ");			if(cfsstat.sm[i].n - cfsprev.sm[i].n)				p += snprint(p, sizeof(statbuf)+statbuf-p, "%7.3f ",					0.000001*(cfsstat.sm[i].t - cfsprev.sm[i].t)/(cfsstat.sm[i].n - cfsprev.sm[i].n));			else				p += snprint(p, sizeof(statbuf)+statbuf-p, "        ");			p += snprint(p, sizeof(statbuf)+statbuf-p, "%s\n", mname[i]);		}	p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud ndirread\n",		cfsstat.ndirread, cfsstat.ndirread - cfsprev.ndirread);	p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud ndelegateread\n",		cfsstat.ndelegateread, cfsstat.ndelegateread - cfsprev.ndelegateread);	p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud ninsert\n",		cfsstat.ninsert, cfsstat.ninsert - cfsprev.ninsert);	p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud ndelete\n",		cfsstat.ndelete, cfsstat.ndelete - cfsprev.ndelete);	p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud nupdate\n",		cfsstat.nupdate, cfsstat.nupdate - cfsprev.nupdate);	p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud bytesread\n",		cfsstat.bytesread, cfsstat.bytesread - cfsprev.bytesread);	p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud byteswritten\n",		cfsstat.byteswritten, cfsstat.byteswritten - cfsprev.byteswritten);	p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud bytesfromserver\n",		cfsstat.bytesfromserver, cfsstat.bytesfromserver - cfsprev.bytesfromserver);	p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud bytesfromdirs\n",		cfsstat.bytesfromdirs, cfsstat.bytesfromdirs - cfsprev.bytesfromdirs);	p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud bytesfromcache\n",		cfsstat.bytesfromcache, cfsstat.bytesfromcache - cfsprev.bytesfromcache);	p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud bytestocache\n",		cfsstat.bytestocache, cfsstat.bytestocache - cfsprev.bytestocache);	statlen = p - statbuf;	cfsprev = cfsstat;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -