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

📄 check.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
	r = nil;	if(getBit(bm, offset)){		warn(chk, "multiple references to source: %s -> %d", name, offset);		goto Err;	}	setBit(bm, offset);	r = sourceOpen(s, offset, OReadOnly);	if(r == nil){		warn(chk, "could not open source: %s -> %d: %R", name, offset);		goto Err;	}	if(r->gen != gen){		warn(chk, "source has been removed: %s -> %d", name, offset);		goto Err;	}	if(r->dir != dir){		warn(chk, "dir mismatch: %s -> %d", name, offset);		goto Err;	}	return r;Err:	chk->clri(chk, name, mb, i, b);	chk->nclri++;	if(r)		sourceClose(r);	return nil;}typedef struct MetaChunk MetaChunk;struct MetaChunk {	ushort offset;	ushort size;	ushort index;};static intoffsetCmp(void *s0, void *s1){	MetaChunk *mc0, *mc1;	mc0 = s0;	mc1 = s1;	if(mc0->offset < mc1->offset)		return -1;	if(mc0->offset > mc1->offset)		return 1;	return 0;}/* * Fsck that MetaBlock has reasonable header, sorted entries, */static intchkMetaBlock(MetaBlock *mb){	MetaChunk *mc;	int oo, o, n, i;	uchar *p;	mc = vtMemAlloc(mb->nindex*sizeof(MetaChunk));	p = mb->buf + MetaHeaderSize;	for(i = 0; i<mb->nindex; i++){		mc[i].offset = (p[0]<<8) | p[1];		mc[i].size = (p[2]<<8) | p[3];		mc[i].index = i;		p += MetaIndexSize;	}	qsort(mc, mb->nindex, sizeof(MetaChunk), offsetCmp);	/* check block looks ok */	oo = MetaHeaderSize + mb->maxindex*MetaIndexSize;	o = oo;	n = 0;	for(i=0; i<mb->nindex; i++){		o = mc[i].offset;		n = mc[i].size;		if(o < oo)			goto Err;		oo += n;	}	if(o+n > mb->size)		goto Err;	if(mb->size - oo != mb->free)		goto Err;	vtMemFree(mc);	return 1;Err:if(0){	fprint(2, "metaChunks failed!\n");	oo = MetaHeaderSize + mb->maxindex*MetaIndexSize;	for(i=0; i<mb->nindex; i++){		fprint(2, "\t%d: %d %d\n", i, mc[i].offset, mc[i].offset + mc[i].size);		oo += mc[i].size;	}	fprint(2, "\tused=%d size=%d free=%d free2=%d\n", 		oo, mb->size, mb->free, mb->size - oo);}	vtMemFree(mc);	return 0;}static voidscanSource(Fsck *chk, char *name, Source *r){	u32int nb, o;	Block *b;	Entry e;	u32int a;	if(!chk->useventi && globalToLocal(r->score)==NilBlock)		return;	if(!sourceGetEntry(r, &e)){		error(chk, "could not get entry for %s", name);		return;	}	a = globalToLocal(e.score);	if(!chk->useventi && a==NilBlock)		return;	if(getBit(chk->smap, a))		return;	setBit(chk->smap, a);	nb = (sourceGetSize(r) + r->dsize-1) / r->dsize;	for(o=0; o<nb; o++){		b = sourceBlock(r, o, OReadOnly);		if(b == nil){			error(chk, "could not read block in data file %s", name);			continue;		}		if(b->addr != NilBlock && getBit(chk->errmap, b->addr)){			warn(chk, "previously reported error in block %ux is in file %s",				b->addr, name);		}		blockPut(b);	}}/* * Walk the source tree making sure that the BtData * sources containing directory entries are okay. */static voidchkDir(Fsck *chk, char *name, Source *source, Source *meta){	uchar *bm;	Block *b, *bb;	u32int nb, o;	MetaBlock mb;	DirEntry de;	Entry e1, e2;	MetaEntry me;	int i;	char *s, *nn;	Source *r, *mr;	u32int a1, a2;	if(!chk->useventi && globalToLocal(source->score)==NilBlock && globalToLocal(meta->score)==NilBlock)		return;	if(!sourceLock2(source, meta, OReadOnly)){		warn(chk, "could not lock sources for %s: %R", name);		return;	}	if(!sourceGetEntry(source, &e1) || !sourceGetEntry(meta, &e2)){		warn(chk, "could not load entries for %s: %R", name);		return;	}	a1 = globalToLocal(e1.score);	a2 = globalToLocal(e2.score);	if((!chk->useventi && a1==NilBlock && a2==NilBlock)	|| (getBit(chk->smap, a1) && getBit(chk->smap, a2))){		sourceUnlock(source);		sourceUnlock(meta);		return;	}	setBit(chk->smap, a1);	setBit(chk->smap, a2);	bm = vtMemAllocZ(sourceGetDirSize(source)/8 + 1);	nb = (sourceGetSize(meta) + meta->dsize - 1)/meta->dsize;	for(o=0; o<nb; o++){		b = sourceBlock(meta, o, OReadOnly);		if(b == nil){			error(chk, "could not read block in meta file: %s[%ud]: %R", name, o);			continue;		}if(0)fprint(2, "source %V:%d block %d addr %d\n", source->score, source->offset, o, b->addr);		if(b->addr != NilBlock && getBit(chk->errmap, b->addr))			warn(chk, "previously reported error in block %ux is in %s",				b->addr, name);		if(!mbUnpack(&mb, b->data, meta->dsize)){			error(chk, "could not unpack meta block: %s[%ud]: %R", name, o);			blockPut(b);			continue;		}		if(!chkMetaBlock(&mb)){			error(chk, "bad meta block: %s[%ud]: %R", name, o);			blockPut(b);			continue;		}		s = nil;		for(i=mb.nindex-1; i>=0; i--){			meUnpack(&me, &mb, i);			if(!deUnpack(&de, &me)){				error(chk, "cound not unpack dir entry: %s[%ud][%d]: %R", name, o, i);				continue;			}			if(s && strcmp(s, de.elem) <= 0)				error(chk, "dir entry out of order: %s[%ud][%d] = %s last = %s", name, o, i,					de.elem, s);			vtMemFree(s);			s = vtStrDup(de.elem);			nn = smprint("%s/%s", name, de.elem);			if(nn == nil){				error(chk, "out of memory");				continue;			}			if(chk->printdirs){				if(de.mode&ModeDir)					chk->print("%s/\n", nn);			}			if(chk->printfiles){				if(!(de.mode&ModeDir))					chk->print("%s\n", nn);			}			if(!(de.mode & ModeDir)){				r = openSource(chk, source, nn, bm, de.entry, de.gen, 0, &mb, i, b);				if(r != nil){					if(sourceLock(r, OReadOnly)){						scanSource(chk, nn, r);						sourceUnlock(r);					}					sourceClose(r);				}				deCleanup(&de);				free(nn);				continue;			}			r = openSource(chk, source, nn, bm, de.entry, de.gen, 1, &mb, i, b);			if(r == nil){				deCleanup(&de);				free(nn);				continue;			}			mr = openSource(chk, source, nn, bm, de.mentry, de.mgen, 0, &mb, i, b);			if(mr == nil){				sourceClose(r);				deCleanup(&de);				free(nn);				continue;			}			if(!(de.mode&ModeSnapshot) || chk->walksnapshots)				chkDir(chk, nn, r, mr);			sourceClose(mr);			sourceClose(r);			deCleanup(&de);			free(nn);			deCleanup(&de);		}		vtMemFree(s);		blockPut(b);	}	nb = sourceGetDirSize(source);	for(o=0; o<nb; o++){		if(getBit(bm, o))			continue;		r = sourceOpen(source, o, OReadOnly);		if(r == nil)			continue;		warn(chk, "non referenced entry in source %s[%d]", name, o);		if((bb = sourceBlock(source, o/(source->dsize/VtEntrySize), OReadOnly)) != nil){			if(bb->addr != NilBlock){				setBit(chk->errmap, bb->addr);				chk->clre(chk, bb, o%(source->dsize/VtEntrySize));				chk->nclre++;			}			blockPut(bb);		}		sourceClose(r);	}	sourceUnlock(source);	sourceUnlock(meta);	vtMemFree(bm);}static voidcheckDirs(Fsck *chk){	Source *r, *mr;	sourceLock(chk->fs->source, OReadOnly);	r = sourceOpen(chk->fs->source, 0, OReadOnly);	mr = sourceOpen(chk->fs->source, 1, OReadOnly);	sourceUnlock(chk->fs->source);	chkDir(chk, "", r, mr);	sourceClose(r);	sourceClose(mr);}static voidsetBit(uchar *bmap, u32int addr){	if(addr == NilBlock)		return;	bmap[addr>>3] |= 1 << (addr & 7);}static intgetBit(uchar *bmap, u32int addr){	if(addr == NilBlock)		return 0;	return (bmap[addr>>3] >> (addr & 7)) & 1;}static voiderror(Fsck *chk, char *fmt, ...){	static nerr;	va_list arg;	char buf[128];	va_start(arg, fmt);	vseprint(buf, buf+sizeof(buf), fmt, arg);	va_end(arg);	chk->print("error: %s\n", buf);//	if(nerr++ > 20)//		vtFatal("too many errors");}static voidwarn(Fsck *chk, char *fmt, ...){	static nerr;	va_list arg;	char buf[128];	va_start(arg, fmt);	vseprint(buf, buf+sizeof(buf), fmt, arg);	va_end(arg);	chk->print("error: %s\n", buf);}static voidclrenop(Fsck*, Block*, int){}static voidclosenop(Fsck*, Block*, u32int){}static voidclrinop(Fsck*, char*, MetaBlock*, int, Block*){}static intprintnop(char*, ...){	return 0;}

⌨️ 快捷键说明

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