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

📄 ext2fs.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <fcall.h>#include <thread.h>#include <9p.h>#include "dat.h"#include "fns.h"#define thdr	r->ifcall#define rhdr	r->ofcallextern int	errno;static voidresponse(Req *r){	char *err;	if (errno) {		err = xerrstr(errno);		chat("%s\n", err);		respond(r, err);	} else {		chat("OK\n");		respond(r, nil);	}}static voidrattach(Req *r){	Xfs *xf;	Xfile *root;	chat("attach(fid=%d,uname=\"%s\",aname=\"%s\",afid=\"%d\")...",		thdr.fid, thdr.uname, thdr.aname, thdr.afid);		errno = 0;	root = xfile(r->fid, Clean);	if(!root){		errno = Enomem;		goto error;	}	root->xf = xf = getxfs(thdr.aname);	if(!xf)		goto error;		/* now attach root inode */	if( get_inode(root, EXT2_ROOT_INODE) < 0 )		goto error;		r->fid->qid.type = QTDIR;	r->fid->qid.vers = 0;	root->xf->rootqid = r->fid->qid;	root->pinbr = EXT2_ROOT_INODE;	root->root = 1;	rhdr.qid = r->fid->qid;	error:	response(r);}static char *rclone(Fid *fid, Fid *newfid){	Xfile *of = xfile(fid, Asis);	Xfile *nf = xfile(newfid, Clean);	chat("clone(fid=%d,newfid=%d)...", fid->fid, newfid->fid);	errno = 0;	if(!of)		errno = Eio;	else if(!nf)		errno = Enomem;	else{		Xfile *next = nf->next;		*nf = *of;		nf->next = next;		nf->fid = newfid->fid;		nf->root = 0;	}	chat("%s\n", errno? xerrstr(errno) : "OK");	return errno ? xerrstr(errno) : 0;}static char *rwalk1(Fid *fid, char *name, Qid *qid){	Xfile *f=xfile(fid, Asis);	int nr, sinbr = 0;	chat("walk1(fid=%d,name=\"%s\")...", fid->fid, name);	errno = 0;	if( !f ){		chat("no xfile...");		goto error;	}	if( !(fid->qid.type & QTDIR) ){		chat("qid.type=0x%x...", fid->qid.type);		goto error;	}	sinbr = f->pinbr;	if( name == 0 || name[0] == 0 || !strcmp(name, ".") ){		*qid = fid->qid;		goto ok;	}else if( !strcmp(name, "..") ){		if( fid->qid.path == f->xf->rootqid.path ){			chat("walkup from root...");			*qid = fid->qid;			goto ok;		}		if( get_inode(f, f->pinbr) < 0 )			goto error;		if( f->pinbr == EXT2_ROOT_INODE ){			*qid = f->xf->rootqid;			f->pinbr = EXT2_ROOT_INODE;		} else {			*qid = (Qid){f->pinbr,0,QTDIR};			f->inbr = f->pinbr;			if( (nr = get_file(f, "..")) < 0 )				goto error;			f->pinbr = nr;		}	}else{		f->pinbr = f->inbr;		if( (nr = get_file(f, name)) < 0 )			goto error;		if( get_inode(f, nr) < 0 )			goto error;		*qid = (Qid){nr,0,0};		if( nr == EXT2_ROOT_INODE )			*qid = f->xf->rootqid;		else if( S_ISDIR(getmode(f)) )			 qid->type = QTDIR;		/*strcpy(f->name, thdr.name);*/	}ok:	chat("OK\n");	return 0;error:	f->pinbr = sinbr;	chat("%s\n", xerrstr(Enonexist));	return xerrstr(Enonexist);}static voidrstat(Req *r){	Xfile *f=xfile(r->fid, Asis);	chat("stat(fid=%d)...", thdr.fid);	errno = 0;	if( !f )		errno = Eio;	else{		dostat(r->fid->qid, f, &r->d);	}	response(r);}static voidrwstat(Req *r){	Xfile *f=xfile(r->fid, Asis);	chat("wstat(fid=%d)...", thdr.fid);	errno = 0;	if( !f )		errno = Eio;	else		dowstat(f, &r->d);	response(r);	}static voidrread(Req *r){	Xfile *f; 	int nr;	chat("read(fid=%d,offset=%lld,count=%d)...",		thdr.fid, thdr.offset, thdr.count);	errno = 0;	if ( !(f=xfile(r->fid, Asis)) )		goto error;	if( r->fid->qid.type & QTDIR ){		nr = readdir(f, r->rbuf, thdr.offset, thdr.count);	}else		nr = readfile(f, r->rbuf, thdr.offset, thdr.count);		if(nr >= 0){		rhdr.count = nr;		chat("rcnt=%d...OK\n", nr);		respond(r, nil);		return;	}error:	errno = Eio;	response(r);}static voidrwrite(Req *r){	Xfile *f; int nr;		chat("write(fid=%d,offset=%lld,count=%d)...",		thdr.fid, thdr.offset, thdr.count);	errno = 0;	if (!(f=xfile(r->fid, Asis)) ){		errno = Eio;		goto error;	}	if( !S_ISREG(getmode(f)) ){		errno = Elink;		goto error;	}	nr = writefile(f, thdr.data, thdr.offset, thdr.count);	if(nr >= 0){			rhdr.count = nr;		chat("rcnt=%d...OK\n", nr);		respond(r, nil);		return;	}	errno = Eio;error:	response(r);}static voiddestroyfid(Fid *fid){	chat("destroy(fid=%d)\n", fid->fid);	xfile(fid, Clunk);	/*syncbuf(xf);*/}static voidropen(Req *r){	Xfile *f;	chat("open(fid=%d,mode=%d)...", thdr.fid, thdr.mode);	errno = 0;	f = xfile(r->fid, Asis);	if( !f ){		errno = Eio;		goto error;	}		if(thdr.mode & OTRUNC){		if( !S_ISREG(getmode(f)) ){			errno = Eperm;			goto error;		}		if(truncfile(f) < 0){			goto error;		}	}	chat("f->qid=0x%8.8lux...", r->fid->qid.path);	rhdr.qid = r->fid->qid;error:	response(r);}static voidrcreate(Req *r){	Xfile *f;	int inr, perm;	chat("create(fid=%d,name=\"%s\",perm=%uo,mode=%d)...",		thdr.fid, thdr.name, thdr.perm, thdr.mode);	errno = 0;	if(strcmp(thdr.name, ".") == 0 || strcmp(thdr.name, "..") == 0){		errno = Eperm;		goto error;	}	f = xfile(r->fid, Asis);	if( !f ){		errno = Eio;		goto error;	}	if( strlen(thdr.name) > EXT2_NAME_LEN ){		chat("name too long ...");		errno = Elongname;		goto error;	}	/* create */	errno = 0;	if( thdr.perm & DMDIR ){		perm = (thdr.perm & ~0777) | 				(getmode(f) & thdr.perm & 0777);		perm |= S_IFDIR;		inr = create_dir(f, thdr.name, perm);	}else{		perm = (thdr.perm & (~0777|0111)) |				(getmode(f) & thdr.perm & 0666);		perm |= S_IFREG;		inr = create_file(f, thdr.name, perm);			}	if( inr < 0 )		goto error;	/* fill with new inode */	f->pinbr = f->inbr;	if( get_inode(f, inr) < 0 ){		errno = Eio;		goto error;	}	r->fid->qid = (Qid){inr, 0, 0};	if( S_ISDIR(getmode(f)) )		r->fid->qid.type |= QTDIR;	chat("f->qid=0x%8.8lux...", r->fid->qid.path);	rhdr.qid = r->fid->qid;error:	response(r);}static voidrremove(Req *r){	Xfile *f=xfile(r->fid, Asis);	chat("remove(fid=%d) ...", thdr.fid);	errno = 0;	if(!f){		errno = Eio;		goto error;	}	/* check permission here !!!!*/	unlink(f);error:	response(r);}Srv ext2srv = {	.destroyfid =	destroyfid,	.attach =	rattach,	.stat =		rstat,	.wstat =	rwstat,	.clone =	rclone,	.walk1 =	rwalk1,	.open =		ropen,	.read =		rread,	.write =	rwrite,	.create =	rcreate,	.remove =	rremove,};

⌨️ 快捷键说明

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