Пример #1
0
/*
 * We've just walked the whole write buffer.  Notice blocks that
 * aren't marked available but that we didn't visit.  They are lost.
 */
static void
checkLeak(Fsck *chk)
{
	u32int a, nfree, nlost;
	Block *b;
	Label l;

	nfree = 0;
	nlost = 0;

	for(a = 0; a < chk->nblocks; a++){
		if(!readLabel(chk->cache, &l, a)){
			error(chk, "could not read label: addr 0x%ux %d %d: %R",
				a, l.type, l.state);
			continue;
		}
		if(getBit(chk->amap, a))
			continue;
		if(l.state == BsFree || l.epochClose <= chk->fs->elo ||
		    l.epochClose == l.epoch){
			nfree++;
			setBit(chk->amap, a);
			continue;
		}
		if(l.state&BsClosed)
			continue;
		nlost++;
//		warn(chk, "unreachable block: addr 0x%ux type %d tag 0x%ux "
//			"state %s epoch %ud close %ud", a, l.type, l.tag,
//			bsStr(l.state), l.epoch, l.epochClose);
		b = cacheLocal(chk->cache, PartData, a, OReadOnly);
		if(b == nil){
			error(chk, "could not read block 0x%#.8ux", a);
			continue;
		}
		chk->close(chk, b, 0);
		chk->nclose++;
		setBit(chk->amap, a);
		blockPut(b);
	}
	chk->print("fsys blocks: total=%ud used=%ud(%.1f%%) free=%ud(%.1f%%) lost=%ud(%.1f%%)\n",
		chk->nblocks,
		chk->nblocks - nfree-nlost,
		100.*(chk->nblocks - nfree - nlost)/chk->nblocks,
		nfree, 100.*nfree/chk->nblocks,
		nlost, 100.*nlost/chk->nblocks);
}
Пример #2
0
Файл: fs.c Проект: bhanug/harvey
Block*
superGet(Cache *c, Super* super)
{
	Block *b;

	if((b = cacheLocal(c, PartSuper, 0, OReadWrite)) == nil){
		fprint(2, "%s: superGet: cacheLocal failed: %R\n", argv0);
		return nil;
	}
	if(!superUnpack(super, b->data)){
		fprint(2, "%s: superGet: superUnpack failed: %R\n", argv0);
		blockPut(b);
		return nil;
	}

	return b;
}
Пример #3
0
/*
 * caller must lock f->source and f->msource
 * caller must NOT lock the source and msource
 * referenced by dir.
 */
static u32int
fileMetaAlloc(File *f, DirEntry *dir, u32int start)
{
	u32int nb, bo;
	Block *b, *bb;
	MetaBlock mb;
	int nn;
	uchar *p;
	int i, n, epb;
	MetaEntry me;
	Source *s, *ms;

	s = f->source;
	ms = f->msource;

	n = deSize(dir);
	nb = (sourceGetSize(ms)+ms->dsize-1)/ms->dsize;
	b = nil;
	if(start > nb)
		start = nb;
	for(bo=start; bo<nb; bo++){
		b = sourceBlock(ms, bo, OReadWrite);
		if(b == nil)
			goto Err;
		if(!mbUnpack(&mb, b->data, ms->dsize))
			goto Err;
		nn = (mb.maxsize*FullPercentage/100) - mb.size + mb.free;
		if(n <= nn && mb.nindex < mb.maxindex)
			break;
		blockPut(b);
		b = nil;
	}

	/* add block to meta file */
	if(b == nil){
		b = sourceBlock(ms, bo, OReadWrite);
		if(b == nil)
			goto Err;
		sourceSetSize(ms, (nb+1)*ms->dsize);
		mbInit(&mb, b->data, ms->dsize, ms->dsize/BytesPerEntry);
	}

	p = mbAlloc(&mb, n);
	if(p == nil){
		/* mbAlloc might have changed block */
		mbPack(&mb);
		blockDirty(b);
		vtSetError(EBadMeta);
		goto Err;
	}

	mbSearch(&mb, dir->elem, &i, &me);
	assert(me.p == nil);
	me.p = p;
	me.size = n;
	dePack(dir, &me);
	mbInsert(&mb, i, &me);
	mbPack(&mb);

	/* meta block depends on super block for qid ... */
	bb = cacheLocal(b->c, PartSuper, 0, OReadOnly);
	blockDependency(b, bb, -1, nil, nil);
	blockPut(bb);

	/* ... and one or two dir entries */
	epb = s->dsize/VtEntrySize;
	bb = sourceBlock(s, dir->entry/epb, OReadOnly);
	blockDependency(b, bb, -1, nil, nil);
	blockPut(bb);
	if(dir->mode & ModeDir){
		bb = sourceBlock(s, dir->mentry/epb, OReadOnly);
		blockDependency(b, bb, -1, nil, nil);
		blockPut(bb);
	}

	blockDirty(b);
	blockPut(b);
	return bo;
Err:
	blockPut(b);
	return NilBlock;
}
Пример #4
0
Файл: fs.c Проект: bhanug/harvey
Fs *
fsOpen(char *file, VtSession *z, int32_t ncache, int mode)
{
	int fd, m;
	uint8_t oscore[VtScoreSize];
	Block *b, *bs;
	Disk *disk;
	Fs *fs;
	Super super;

	switch(mode){
	default:
		vtSetError(EBadMode);
		return nil;
	case OReadOnly:
		m = OREAD;
		break;
	case OReadWrite:
		m = ORDWR;
		break;
	}
	fd = open(file, m);
	if(fd < 0){
		vtSetError("open %s: %r", file);
		return nil;
	}

	bwatchInit();
	disk = diskAlloc(fd);
	if(disk == nil){
		vtSetError("diskAlloc: %R");
		close(fd);
		return nil;
	}

	fs = vtMemAllocZ(sizeof(Fs));
	fs->mode = mode;
	fs->name = vtStrDup(file);
	fs->blockSize = diskBlockSize(disk);
	fs->elk = vtLockAlloc();
	fs->cache = cacheAlloc(disk, z, ncache, mode);
	if(mode == OReadWrite && z)
		fs->arch = archInit(fs->cache, disk, fs, z);
	fs->z = z;

	b = cacheLocal(fs->cache, PartSuper, 0, mode);
	if(b == nil)
		goto Err;
	if(!superUnpack(&super, b->data)){
		blockPut(b);
		vtSetError("bad super block");
		goto Err;
	}
	blockPut(b);

	fs->ehi = super.epochHigh;
	fs->elo = super.epochLow;

//fprint(2, "%s: fs->ehi %d fs->elo %d active=%d\n", argv0, fs->ehi, fs->elo, super.active);

	fs->source = sourceRoot(fs, super.active, mode);
	if(fs->source == nil){
		/*
		 * Perhaps it failed because the block is copy-on-write.
		 * Do the copy and try again.
		 */
		if(mode == OReadOnly || strcmp(vtGetError(), EBadRoot) != 0)
			goto Err;
		b = cacheLocalData(fs->cache, super.active, BtDir, RootTag,
			OReadWrite, 0);
		if(b == nil){
			vtSetError("cacheLocalData: %R");
			goto Err;
		}
		if(b->l.epoch == fs->ehi){
			blockPut(b);
			vtSetError("bad root source block");
			goto Err;
		}
		b = blockCopy(b, RootTag, fs->ehi, fs->elo);
		if(b == nil)
			goto Err;
		localToGlobal(super.active, oscore);
		super.active = b->addr;
		bs = cacheLocal(fs->cache, PartSuper, 0, OReadWrite);
		if(bs == nil){
			blockPut(b);
			vtSetError("cacheLocal: %R");
			goto Err;
		}
		superPack(&super, bs->data);
		blockDependency(bs, b, 0, oscore, nil);
		blockPut(b);
		blockDirty(bs);
		blockRemoveLink(bs, globalToLocal(oscore), BtDir, RootTag, 0);
		blockPut(bs);
		fs->source = sourceRoot(fs, super.active, mode);
		if(fs->source == nil){
			vtSetError("sourceRoot: %R");
			goto Err;
		}
	}

//fprint(2, "%s: got fs source\n", argv0);

	vtRLock(fs->elk);
	fs->file = fileRoot(fs->source);
	fs->source->file = fs->file;		/* point back */
	vtRUnlock(fs->elk);
	if(fs->file == nil){
		vtSetError("fileRoot: %R");
		goto Err;
	}

//fprint(2, "%s: got file root\n", argv0);

	if(mode == OReadWrite){
		fs->metaFlush = periodicAlloc(fsMetaFlush, fs, 1000);
		fs->snap = snapInit(fs);
	}
	return fs;

Err:
fprint(2, "%s: fsOpen error\n", argv0);
	fsClose(fs);
	return nil;
}