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

📄 9fsys.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
			goto error;		}		vtMemFree(de.elem);		de.elem = vtStrDup(argv[1]);	}	if(strcmp(argv[2], "-") != 0){		if(!validUserName(argv[2])){			vtSetError("console wstat - bad uid");			goto error;		}		vtMemFree(de.uid);		de.uid = vtStrDup(argv[2]);	}	if(strcmp(argv[3], "-") != 0){		if(!validUserName(argv[3])){			vtSetError("console wstat - bad gid");			goto error;		}		vtMemFree(de.gid);		de.gid = vtStrDup(argv[3]);	}	if(strcmp(argv[4], "-") != 0){		if(!fsysParseMode(argv[4], &de.mode)){			vtSetError("console wstat - bad mode");			goto error;		}	}	if(strcmp(argv[5], "-") != 0){		de.size = strtoull(argv[5], &p, 0);		if(argv[5][0] == '\0' || *p != '\0' || (vlong)de.size < 0){			vtSetError("console wstat - bad length");			goto error;		}	}	if(!fileSetDir(f, &de, uidadm)){		vtSetError("console wstat - %R");		goto error;	}	deCleanup(&de);	if(!fileGetDir(f, &de)){		vtSetError("console wstat - stat2 - %R");		goto error;	}	fsysPrintStat("\tnew: w", argv[0], &de);	deCleanup(&de);	fileDecRef(f);	vtRUnlock(fsys->fs->elk);	return 1;error:	deCleanup(&de);	/* okay to do this twice */	fileDecRef(f);	vtRUnlock(fsys->fs->elk);	return 0;}static voidfsckClri(Fsck *fsck, char *name, MetaBlock *mb, int i, Block *b){	USED(name);	if((fsck->flags&DoClri) == 0)		return;	mbDelete(mb, i);	mbPack(mb);	blockDirty(b);	}static voidfsckClose(Fsck *fsck, Block *b, u32int epoch){	Label l;	if((fsck->flags&DoClose) == 0)		return;	l = b->l;	if(l.state == BsFree || (l.state&BsClosed)){		consPrint("%#ux is already closed\n", b->addr);		return;	}	if(epoch){			l.state |= BsClosed;		l.epochClose = epoch;	}else		l.state = BsFree;			if(!blockSetLabel(b, &l, 0))		consPrint("%#ux setlabel: %R\n", b->addr);}static voidfsckClre(Fsck *fsck, Block *b, int offset){	Entry e;	if((fsck->flags&DoClre) == 0)		return;	if(offset<0 || offset*VtEntrySize >= fsck->bsize){		consPrint("bad clre\n");		return;	}	memset(&e, 0, sizeof e);	entryPack(&e, b->data, offset);	blockDirty(b);}static voidfsckClrp(Fsck *fsck, Block *b, int offset){	if((fsck->flags&DoClrp) == 0)		return;	if(offset<0 || offset*VtScoreSize >= fsck->bsize){		consPrint("bad clre\n");		return;	}	memmove(b->data+offset*VtScoreSize, vtZeroScore, VtScoreSize);	blockDirty(b);}static intfsysCheck(Fsys *fsys, int argc, char *argv[]){	int i, halting;	char *usage = "usage: [fsys name] check [-v] [options]";	Fsck fsck;	Block *b;	Super super;	memset(&fsck, 0, sizeof fsck);	fsck.fs = fsys->fs;	fsck.clri = fsckClri;	fsck.clre = fsckClre;	fsck.clrp = fsckClrp;	fsck.close = fsckClose;	fsck.print = consPrint;	ARGBEGIN{	default:		return cliError(usage);	}ARGEND	for(i=0; i<argc; i++){		if(strcmp(argv[i], "pblock") == 0)			fsck.printblocks = 1;		else if(strcmp(argv[i], "pdir") == 0)			fsck.printdirs = 1;		else if(strcmp(argv[i], "pfile") == 0)			fsck.printfiles = 1;		else if(strcmp(argv[i], "bclose") == 0)			fsck.flags |= DoClose;		else if(strcmp(argv[i], "clri") == 0)			fsck.flags |= DoClri;		else if(strcmp(argv[i], "clre") == 0)			fsck.flags |= DoClre;		else if(strcmp(argv[i], "clrp") == 0)			fsck.flags |= DoClrp;		else if(strcmp(argv[i], "fix") == 0)			fsck.flags |= DoClose|DoClri|DoClre|DoClrp;		else if(strcmp(argv[i], "venti") == 0)			fsck.useventi = 1;		else if(strcmp(argv[i], "snapshot") == 0)			fsck.walksnapshots = 1;		else{			consPrint("unknown option '%s'\n", argv[i]);			return cliError(usage);		}	}	halting = fsys->fs->halted==0;	if(halting)		fsHalt(fsys->fs);	if(fsys->fs->arch){		b = superGet(fsys->fs->cache, &super);		if(b == nil){			consPrint("could not load super block\n");			goto Out;		}		blockPut(b);		if(super.current != NilBlock){			consPrint("cannot check fs while archiver is running; wait for it to finish\n");			goto Out;		}	}	fsCheck(&fsck);	consPrint("fsck: %d clri, %d clre, %d clrp, %d bclose\n",		fsck.nclri, fsck.nclre, fsck.nclrp, fsck.nclose);Out:	if(halting)		fsUnhalt(fsys->fs);	return 1;}static intfsysVenti(char* name, int argc, char* argv[]){	int r;	char *host;	char *usage = "usage: [fsys name] venti [address]";	Fsys *fsys;	ARGBEGIN{	default:		return cliError(usage);	}ARGEND	if(argc == 0)		host = nil;	else if(argc == 1)		host = argv[0];	else		return cliError(usage);	if((fsys = _fsysGet(name)) == nil)		return 0;	vtLock(fsys->lock);	if(host == nil)		host = fsys->venti;	else{		vtMemFree(fsys->venti);		if(host[0])			fsys->venti = vtStrDup(host);		else{			host = nil;			fsys->venti = nil;		}	}	/* already open: do a redial */	if(fsys->fs != nil){		if(fsys->session == nil){			vtSetError("file system was opened with -V");			r = 0;			goto out;		}		r = 1;		if(!vtRedial(fsys->session, host)		|| !vtConnect(fsys->session, 0))			r = 0;		goto out;	}	/* not yet open: try to dial */	if(fsys->session)		vtClose(fsys->session);	r = 1;	if((fsys->session = vtDial(host, 0)) == nil	|| !vtConnect(fsys->session, 0))		r = 0;out:	vtUnlock(fsys->lock);	fsysPut(fsys);	return r;}static intfsysOpen(char* name, int argc, char* argv[]){	char *p, *host;	Fsys *fsys;	long ncache;	int noauth, noventi, noperm, rflag, wstatallow;	char *usage = "usage: fsys name open [-APVWr] [-c ncache]";	ncache = 1000;	noauth = noperm = wstatallow = noventi = 0;	rflag = OReadWrite;	ARGBEGIN{	default:		return cliError(usage);	case 'A':		noauth = 1;		break;	case 'P':		noperm = 1;		break;	case 'V':		noventi = 1;		break;	case 'W':		wstatallow = 1;		break;	case 'c':		p = ARGF();		if(p == nil)			return cliError(usage);		ncache = strtol(argv[0], &p, 0);		if(ncache <= 0 || p == argv[0] || *p != '\0')			return cliError(usage);		break;	case 'r':		rflag = OReadOnly;		break;	}ARGEND	if(argc)		return cliError(usage);	if((fsys = _fsysGet(name)) == nil)		return 0;	vtLock(fsys->lock);	if(fsys->fs != nil){		vtSetError(EFsysBusy, fsys->name);		vtUnlock(fsys->lock);		fsysPut(fsys);		return 0;	}	if(noventi){		if(fsys->session){			vtClose(fsys->session);			fsys->session = nil;		}	}	else if(fsys->session == nil){		if(fsys->venti && fsys->venti[0])			host = fsys->venti;		else			host = nil;		fsys->session = vtDial(host, 1);		if(!vtConnect(fsys->session, nil) && !noventi)			fprint(2, "warning: connecting to venti: %R\n");	}	if((fsys->fs = fsOpen(fsys->dev, fsys->session, ncache, rflag)) == nil){		vtSetError("fsOpen: %R");		vtUnlock(fsys->lock);		fsysPut(fsys);		return 0;	}	fsys->noauth = noauth;	fsys->noperm = noperm;	fsys->wstatallow = wstatallow;	vtUnlock(fsys->lock);	fsysPut(fsys);	if(strcmp(name, "main") == 0)		usersFileRead(nil);	return 1;}static intfsysUnconfig(char* name, int argc, char* argv[]){	Fsys *fsys, **fp;	char *usage = "usage: fsys name unconfig";	ARGBEGIN{	default:		return cliError(usage);	}ARGEND	if(argc)		return cliError(usage);	vtLock(sbox.lock);	fp = &sbox.head;	for(fsys = *fp; fsys != nil; fsys = fsys->next){		if(strcmp(fsys->name, name) == 0)			break;		fp = &fsys->next;	}	if(fsys == nil){		vtSetError(EFsysNotFound, name);		vtUnlock(sbox.lock);		return 0;	}	if(fsys->ref != 0 || fsys->fs != nil){		vtSetError(EFsysBusy, fsys->name);		vtUnlock(sbox.lock);		return 0;	}	*fp = fsys->next;	vtUnlock(sbox.lock);	if(fsys->session != nil){		vtClose(fsys->session);		vtFree(fsys->session);	}	if(fsys->venti != nil)		vtMemFree(fsys->venti);	if(fsys->dev != nil)		vtMemFree(fsys->dev);	if(fsys->name != nil)		vtMemFree(fsys->name);	vtMemFree(fsys);	return 1;}static intfsysConfig(char* name, int argc, char* argv[]){	Fsys *fsys;	char *usage = "usage: fsys name config dev";	ARGBEGIN{	default:		return cliError(usage);	}ARGEND	if(argc != 1)		return cliError(usage);	if((fsys = _fsysGet(argv[0])) != nil){		vtLock(fsys->lock);		if(fsys->fs != nil){			vtSetError(EFsysBusy, fsys->name);			vtUnlock(fsys->lock);			fsysPut(fsys);			return 0;		}		vtMemFree(fsys->dev);		fsys->dev = vtStrDup(argv[0]);		vtUnlock(fsys->lock);	}	else if((fsys = fsysAlloc(name, argv[0])) == nil)		return 0;	fsysPut(fsys);	return 1;}static struct {	char*	cmd;	int	(*f)(Fsys*, int, char**);	int	(*f1)(char*, int, char**);} fsyscmd[] = {	{ "close",	fsysClose, },	{ "config",	nil, fsysConfig, },	{ "open",	nil, fsysOpen, },	{ "unconfig",	nil, fsysUnconfig, },	{ "venti",	nil, fsysVenti, },	{ "bfree",	fsysBfree, },	{ "block",	fsysBlock, },	{ "check",	fsysCheck, },	{ "clre",	fsysClre, },	{ "clri",	fsysClri, },	{ "clrp",	fsysClrp, },	{ "create",	fsysCreate, },	{ "df",		fsysDf, },	{ "epoch",	fsysEpoch, },	{ "halt",	fsysHalt, },	{ "label",	fsysLabel, },	{ "remove",	fsysRemove, },	{ "snap",	fsysSnap, },	{ "snaptime",	fsysSnapTime, },	{ "snapclean",	fsysSnapClean, },	{ "stat",	fsysStat, },	{ "sync",	fsysSync, },	{ "unhalt",	fsysUnhalt, },	{ "wstat",	fsysWstat, },	{ "vac",	fsysVac, },	{ nil,		nil, },};static intfsysXXX1(Fsys *fsys, int i, int argc, char* argv[]){	int r;	vtLock(fsys->lock);	if(fsys->fs == nil){		vtUnlock(fsys->lock);		vtSetError(EFsysNotOpen, fsys->name);		return 0;	}	if(fsys->fs->halted	&& fsyscmd[i].f != fsysUnhalt && fsyscmd[i].f != fsysCheck){		vtSetError("file system %s is halted", fsys->name);		vtUnlock(fsys->lock);		return 0;	}	r = (*fsyscmd[i].f)(fsys, argc, argv);	vtUnlock(fsys->lock);	return r;}static intfsysXXX(char* name, int argc, char* argv[]){	int i, r;	Fsys *fsys;	for(i = 0; fsyscmd[i].cmd != nil; i++){		if(strcmp(fsyscmd[i].cmd, argv[0]) == 0)			break;	}	if(fsyscmd[i].cmd == nil){		vtSetError("unknown command - '%s'", argv[0]);		return 0;	}	/* some commands want the name... */	if(fsyscmd[i].f1 != nil){		if(strcmp(name, FsysAll) == 0){			vtSetError("cannot use fsys %#q with %#q command", FsysAll, argv[0]);			return 0;		}		return (*fsyscmd[i].f1)(name, argc, argv);	}	/* ... but most commands want the Fsys */	if(strcmp(name, FsysAll) == 0){		r = 1;		vtRLock(sbox.lock);		for(fsys = sbox.head; fsys != nil; fsys = fsys->next){			fsys->ref++;			r = fsysXXX1(fsys, i, argc, argv) && r;			fsys->ref--;		}		vtRUnlock(sbox.lock);	}else{		if((fsys = _fsysGet(name)) == nil)			return 0;		r = fsysXXX1(fsys, i, argc, argv);		fsysPut(fsys);	}	return r;}static intcmdFsysXXX(int argc, char* argv[]){	char *name;	if((name = sbox.curfsys) == nil){		vtSetError(EFsysNoCurrent, argv[0]);		return 0;	}	return fsysXXX(name, argc, argv);}static intcmdFsys(int argc, char* argv[]){	Fsys *fsys;	char *usage = "usage: fsys [name ...]";	ARGBEGIN{	default:		return cliError(usage);	}ARGEND	if(argc == 0){		vtRLock(sbox.lock);		for(fsys = sbox.head; fsys != nil; fsys = fsys->next)			consPrint("\t%s\n", fsys->name);		vtRUnlock(sbox.lock);		return 1;	}	if(argc == 1){		fsys = nil;		if(strcmp(argv[0], FsysAll) != 0 && (fsys = fsysGet(argv[0])) == nil)			return 0;		sbox.curfsys = vtStrDup(argv[0]);		consPrompt(sbox.curfsys);		if(fsys)			fsysPut(fsys);		return 1;	}	return fsysXXX(argv[0], argc-1, argv+1);}intfsysInit(void){	int i;	fmtinstall('H', encodefmt);	fmtinstall('V', scoreFmt);	fmtinstall('R', vtErrFmt);	fmtinstall('L', labelFmt);	sbox.lock = vtLockAlloc();	cliAddCmd("fsys", cmdFsys);	for(i = 0; fsyscmd[i].cmd != nil; i++){		if(fsyscmd[i].f != nil)			cliAddCmd(fsyscmd[i].cmd, cmdFsysXXX);	}	/* the venti cmd is special: the fs can be either open or closed */	cliAddCmd("venti", cmdFsysXXX);	cliAddCmd("printconfig", cmdPrintConfig);	return 1;}

⌨️ 快捷键说明

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