Example #1
0
static void
fileSetTmp(File *f, int istmp)
{
	int i;
	Entry e;
	Source *r;

	for(i=0; i<2; i++){
		if(i==0)
			r = f->source;
		else
			r = f->msource;
		if(r == nil)
			continue;
		if(!sourceGetEntry(r, &e)){
			fprint(2, "sourceGetEntry failed (cannot happen): %r\n");
			continue;
		}
		if(istmp)
			e.flags |= VtEntryNoArchive;
		else
			e.flags &= ~VtEntryNoArchive;
		if(!sourceSetEntry(r, &e)){
			fprint(2, "sourceSetEntry failed (cannot happen): %r\n");
			continue;
		}
	}
}
Example #2
0
static void
scanSource(Fsck *chk, char *name, Source *r)
{
	u32int a, nb, o;
	Block *b;
	Entry e;

	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);
	}
}
Example #3
0
/*
 * Changes the file block bn to be the given block score.
 * Very sneaky.  Only used by flfmt.
 */
int
fileMapBlock(File *f, ulong bn, uchar score[VtScoreSize], ulong tag)
{
	Block *b;
	Entry e;
	Source *s;

	if(!fileLock(f))
		return 0;

	s = nil;
	if(f->dir.mode & ModeDir){
		vtSetError(ENotFile);
		goto Err;
	}

	if(f->source->mode != OReadWrite){
		vtSetError(EReadOnly);
		goto Err;
	}

	if(!sourceLock(f->source, -1))
		goto Err;

	s = f->source;
	b = _sourceBlock(s, bn, OReadWrite, 1, tag);
	if(b == nil)
		goto Err;

	if(!sourceGetEntry(s, &e))
		goto Err;
	if(b->l.type == BtDir){
		memmove(e.score, score, VtScoreSize);
		assert(e.tag == tag || e.tag == 0);
		e.tag = tag;
		e.flags |= VtEntryLocal;
		entryPack(&e, b->data, f->source->offset % f->source->epb);
	}else
		memmove(b->data + (bn%(e.psize/VtScoreSize))*VtScoreSize, score, VtScoreSize);
	blockDirty(b);
	blockPut(b);
	sourceUnlock(s);
	fileUnlock(f);
	return 1;

Err:
	if(s)
		sourceUnlock(s);
	fileUnlock(f);
	return 0;
}
Example #4
0
/*
 * Walk the source tree making sure that the BtData
 * sources containing directory entries are okay.
 */
static void
chkDir(Fsck *chk, char *name, Source *source, Source *meta)
{
	int i;
	u32int a1, a2, nb, o;
	char *s, *nn;
	uchar *bm;
	Block *b, *bb;
	DirEntry de;
	Entry e1, e2;
	MetaBlock mb;
	MetaEntry me;
	Source *r, *mr;

	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,
				  "could 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, 0);
		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);
}