示例#1
0
文件: archive.c 项目: 99years/plan9
static int
ventiSend(Arch *a, Block *b, uchar *data)
{
	uint n;
	uchar score[VtScoreSize];

	if(DEBUG > 1)
		fprint(2, "ventiSend: sending %#ux %L to venti\n", b->addr, &b->l);
	n = vtZeroTruncate(vtType[b->l.type], data, a->blockSize);
	if(DEBUG > 1)
		fprint(2, "ventiSend: truncate %d to %d\n", a->blockSize, n);
	if(!vtWrite(a->z, score, vtType[b->l.type], data, n)){
		fprint(2, "ventiSend: vtWrite block %#ux failed: %R\n", b->addr);
		return 0;
	}
	if(!vtSha1Check(score, data, n)){
		uchar score2[VtScoreSize];
		vtSha1(score2, data, n);
		fprint(2, "ventiSend: vtWrite block %#ux failed vtSha1Check %V %V\n",
			b->addr, score, score2);
		return 0;
	}
	if(!vtSync(a->z))
		return 0;
	return 1;
}
示例#2
0
文件: fs.c 项目: bhanug/harvey
static int
vtWriteBlock(VtSession *z, uint8_t *buf, uint n, uint type,
	     uint8_t score[VtScoreSize])
{
	if(!vtWrite(z, score, type, buf, n))
		return 0;
	if(!vtSha1Check(score, buf, n))
		return 0;
	return 1;
}
示例#3
0
文件: archive.c 项目: 99years/plan9
static void
archThread(void *v)
{
	Arch *a = v;
	Block *b;
	Param p;
	Super super;
	int ret;
	u32int addr;
	uchar rbuf[VtRootSize];
	VtRoot root;

	vtThreadSetName("arch");

	for(;;){
		/* look for work */
		vtLock(a->fs->elk);
		b = superGet(a->c, &super);
		if(b == nil){
			vtUnlock(a->fs->elk);
			fprint(2, "archThread: superGet: %R\n");
			sleep(60*1000);
			continue;
		}
		addr = super.next;
		if(addr != NilBlock && super.current == NilBlock){
			super.current = addr;
			super.next = NilBlock;
			superPack(&super, b->data);
			blockDirty(b);
		}else
			addr = super.current;
		blockPut(b);
		vtUnlock(a->fs->elk);

		if(addr == NilBlock){
			/* wait for work */
			vtLock(a->lk);
			vtSleep(a->starve);
			if(a->die != nil)
				goto Done;
			vtUnlock(a->lk);
			continue;
		}

sleep(10*1000);	/* window of opportunity to provoke races */

		/* do work */
		memset(&p, 0, sizeof p);
		p.blockSize = a->blockSize;
		p.dsize = 3*VtEntrySize;	/* root has three Entries */
		p.c = a->c;
		p.a = a;

		ret = archWalk(&p, addr, BtDir, RootTag);
		switch(ret){
		default:
			abort();
		case ArchFailure:
			fprint(2, "archiveBlock %#ux: %R\n", addr);
			sleep(60*1000);
			continue;
		case ArchSuccess:
		case ArchFaked:
			break;
		}

		if(0) fprint(2, "archiveSnapshot 0x%#ux: maxdepth %ud nfixed %ud"
			" send %ud nfailsend %ud nvisit %ud"
			" nreclaim %ud nfake %ud nreal %ud\n",
			addr, p.maxdepth, p.nfixed,
			p.nsend, p.nfailsend, p.nvisit,
			p.nreclaim, p.nfake, p.nreal);
		if(0) fprint(2, "archiveBlock %V (%ud)\n", p.score, p.blockSize);

		/* tie up vac root */
		memset(&root, 0, sizeof root);
		root.version = VtRootVersion;
		strecpy(root.type, root.type+sizeof root.type, "vac");
		strecpy(root.name, root.name+sizeof root.name, "fossil");
		memmove(root.score, p.score, VtScoreSize);
		memmove(root.prev, super.last, VtScoreSize);
		root.blockSize = a->blockSize;
		vtRootPack(&root, rbuf);
		if(!vtWrite(a->z, p.score, VtRootType, rbuf, VtRootSize)
		|| !vtSha1Check(p.score, rbuf, VtRootSize)){
			fprint(2, "vtWriteBlock %#ux: %R\n", addr);
			sleep(60*1000);
			continue;
		}

		/* record success */
		vtLock(a->fs->elk);
		b = superGet(a->c, &super);
		if(b == nil){
			vtUnlock(a->fs->elk);
			fprint(2, "archThread: superGet: %R\n");
			sleep(60*1000);
			continue;
		}
		super.current = NilBlock;
		memmove(super.last, p.score, VtScoreSize);
		superPack(&super, b->data);
		blockDirty(b);
		blockPut(b);
		vtUnlock(a->fs->elk);

		consPrint("archive vac:%V\n", p.score);
	}

Done:
	a->ref--;
	vtWakeup(a->die);
	vtUnlock(a->lk);
}