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

📄 cfs.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <u.h>#include <libc.h>#include <auth.h>#include <fcall.h>#include "cformat.h"#include "lru.h"#include "bcache.h"#include "disk.h"#include "inode.h"#include "file.h"#include "stats.h"enum{	Nfid=		10240,};/* maximum length of a file */#define MAXLEN 0x7fffffffffffffffLLtypedef struct Mfile Mfile;typedef struct Ram Ram;typedef struct P9fs P9fs;struct Mfile{	Qid	qid;	char	busy;};Mfile	mfile[Nfid];Icache	ic;int	debug, statson;struct P9fs{	int	fd[2];	Fcall	rhdr;	Fcall	thdr;	long	len;	char	*name;};P9fs	c;	/* client conversation */P9fs	s;	/* server conversation */struct Cfsstat  cfsstat, cfsprev;char	statbuf[2048];int	statlen;#define	MAXFDATA	8192	/* i/o size for read/write */int		messagesize = MAXFDATA+IOHDRSZ;uchar	datasnd[MAXFDATA + IOHDRSZ];uchar	datarcv[MAXFDATA + IOHDRSZ];Qid	rootqid;Qid	ctlqid = {0x5555555555555555LL, 0, 0};void	rversion(void);void	rauth(Mfile*);void	rflush(void);void	rattach(Mfile*);void	rwalk(Mfile*);void	ropen(Mfile*);void	rcreate(Mfile*);void	rread(Mfile*);void	rwrite(Mfile*);void	rclunk(Mfile*);void	rremove(Mfile*);void	rstat(Mfile*);void	rwstat(Mfile*);void	error(char*, ...);void	warning(char*);void	mountinit(char*, char*);void	io(void);void	sendreply(char*);void	sendmsg(P9fs*, Fcall*);void	rcvmsg(P9fs*, Fcall*);int	delegate(void);int	askserver(void);void	cachesetup(int, char*);int	ctltest(Mfile*);void	genstats(void);char *mname[]={	[Tversion]		"Tversion",	[Tauth]	"Tauth",	[Tflush]	"Tflush",	[Tattach]	"Tattach",	[Twalk]		"Twalk",	[Topen]		"Topen",	[Tcreate]	"Tcreate",	[Tclunk]	"Tclunk",	[Tread]		"Tread",	[Twrite]	"Twrite",	[Tremove]	"Tremove",	[Tstat]		"Tstat",	[Twstat]	"Twstat",	[Rversion]	"Rversion",	[Rauth]	"Rauth",	[Rerror]	"Rerror",	[Rflush]	"Rflush",	[Rattach]	"Rattach",	[Rwalk]		"Rwalk",	[Ropen]		"Ropen",	[Rcreate]	"Rcreate",	[Rclunk]	"Rclunk",	[Rread]		"Rread",	[Rwrite]	"Rwrite",	[Rremove]	"Rremove",	[Rstat]		"Rstat",	[Rwstat]	"Rwstat",			0,};voidusage(void){	fprint(2, "usage:\tcfs -s [-rd] [-f partition]");	fprint(2, "\tcfs [-rd] [-f partition] [-a netaddr] [mt-pt]\n");	exits("usage");}voidmain(int argc, char *argv[]){	int std;	int format;	char *part;	char *server;	char *mtpt;	std = 0;	format = 0;	part = "/dev/sdC0/cache";	server = "il!emelie";	mtpt = "/tmp";	ARGBEGIN{	case 'a':		server = ARGF();		if(server == 0)			usage();		break;	case 'S':		statson = 1;		break;	case 's':		std = 1;		break;	case 'r':		format = 1;		break;	case 'f':		part = ARGF();		if(part == 0)			usage();		break;	case 'd':		debug = 1;		break;	default:		usage();	}ARGEND	if(argc && *argv)		mtpt = *argv;	if(debug)		fmtinstall('F', fcallfmt);	cachesetup(format, part);	c.name = "client";	s.name = "server";	if(std){		c.fd[0] = c.fd[1] = 1;		s.fd[0] = s.fd[1] = 0;	}else		mountinit(server, mtpt);	switch(fork()){	case 0:		io();		exits("");	case -1:		error("fork");	default:		exits("");	}}voidcachesetup(int format, char *partition){	int f;	int secsize;	int inodes;	int blocksize;	secsize = 512;	inodes = 1024;	blocksize = 4*1024;	f = open(partition, ORDWR);	if(f < 0)		error("opening partition");	if(format || iinit(&ic, f, secsize)<0){		if(iformat(&ic, f, inodes, "bootes", blocksize, secsize) < 0)			error("formatting failed");	}}voidmountinit(char *server, char *mountpoint){	int p[2];	/*	 *  grab a channel and call up the file server	 */	s.fd[0] = s.fd[1] = dial(netmkaddr(server, 0, "9fs"), 0, 0, 0);	if(s.fd[0] < 0)		error("opening data");	/* 	 *  mount onto name space	 */	if(pipe(p) < 0)		error("pipe failed");	switch(fork()){	case 0:		break;	default:		if(amount(p[1], mountpoint, MREPL|MCREATE, "") < 0)			error("mount failed");		exits(0);	case -1:		error("fork failed\n");/*BUG: no wait!*/	}	c.fd[0] = c.fd[1] = p[0];}voidio(void){	int type;	Mfile *mf;    loop:	rcvmsg(&c, &c.thdr);	type = c.thdr.type;	if(statson){		cfsstat.cm[type].n++;		cfsstat.cm[type].s = nsec();	}	mf = &mfile[c.thdr.fid];	switch(type){	default:		error("type");		break;	case Tversion:		rversion();		break;	case Tauth:		mf = &mfile[c.thdr.afid];		rauth(mf);		break;	case Tflush:		rflush();		break;	case Tattach:		rattach(mf);		break;	case Twalk:		rwalk(mf);		break;	case Topen:		ropen(mf);		break;	case Tcreate:		rcreate(mf);		break;	case Tread:		rread(mf);		break;	case Twrite:		rwrite(mf);		break;	case Tclunk:		rclunk(mf);		break;	case Tremove:		rremove(mf);		break;	case Tstat:		rstat(mf);		break;	case Twstat:		rwstat(mf);		break;	}	if(statson){		cfsstat.cm[type].t += nsec() -cfsstat.cm[type].s;	}	goto loop;}voidrversion(void){	if(messagesize > c.thdr.msize)		messagesize = c.thdr.msize;	c.thdr.msize = messagesize;	/* set downstream size */	delegate();}voidrauth(Mfile *mf){	if(mf->busy)		error("auth to used channel");	if(delegate() == 0){		mf->qid = s.rhdr.aqid;		mf->busy = 1;	}}voidrflush(void)		/* synchronous so easy */{	sendreply(0);}voidrattach(Mfile *mf){	if(delegate() == 0){		mf->qid = s.rhdr.qid;		mf->busy = 1;		if (statson == 1){			statson++;			rootqid = mf->qid;		}	}}voidrwalk(Mfile *mf){	Mfile *nmf;	nmf = nil;	if(statson	  && mf->qid.type == rootqid.type && mf->qid.path == rootqid.path	  && c.thdr.nwname == 1 && strcmp(c.thdr.wname[0], "cfsctl") == 0){		/* This is the ctl file */		nmf = &mfile[c.thdr.newfid];		if(c.thdr.newfid != c.thdr.fid && nmf->busy)			error("clone to used channel");		nmf = &mfile[c.thdr.newfid];		nmf->qid = ctlqid;		nmf->busy = 1;		c.rhdr.nwqid = 1;		c.rhdr.wqid[0] = ctlqid;		sendreply(0);		return;	}	if(c.thdr.newfid != c.thdr.fid){		if(c.thdr.newfid >= Nfid)			error("clone nfid out of range");		nmf = &mfile[c.thdr.newfid];		if(nmf->busy)			error("clone to used channel");		nmf = &mfile[c.thdr.newfid];		nmf->qid = mf->qid;		nmf->busy = 1;		mf = nmf; /* Walk mf */	}	if(delegate() < 0){	/* complete failure */		if(nmf)			nmf->busy = 0;		return;	}	if(s.rhdr.nwqid == c.thdr.nwname){	/* complete success */		if(s.rhdr.nwqid > 0)			mf->qid = s.rhdr.wqid[s.rhdr.nwqid-1];		return;	}	/* partial success; release fid */	if(nmf)		nmf->busy = 0;}voidropen(Mfile *mf){	if(statson && ctltest(mf)){		/* Opening ctl file */		if(c.thdr.mode != OREAD){			sendreply("does not exist");			return;		}		c.rhdr.qid = ctlqid;		c.rhdr.iounit = 0;		sendreply(0);		genstats();		return;	}	if(delegate() == 0){		mf->qid = s.rhdr.qid;		if(c.thdr.mode & OTRUNC)			iget(&ic, mf->qid);	}}voidrcreate(Mfile *mf){	if(statson && ctltest(mf)){		sendreply("exists");		return;	}	if(delegate() == 0){		mf->qid = s.rhdr.qid;		mf->qid.vers++;	}

⌨️ 快捷键说明

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