Пример #1
0
/*
 * Some of this logic is duplicated in hdisk.c
 */
Packet*
readlump(u8int *score, int type, u32int size, int *cached)
{
	Lump *u;
	Packet *p;
	IAddr ia;
	u32int n;

	trace(TraceLump, "readlump enter");
/*
	qlock(&stats.lock);
	stats.lumpreads++;
	qunlock(&stats.lock);
*/
	if(scorecmp(score, zeroscore) == 0)
		return packetalloc();
	u = lookuplump(score, type);
	if(u->data != nil){
		trace(TraceLump, "readlump lookuplump hit");
		if(cached)
			*cached = 1;
		n = packetsize(u->data);
		if(n > size){
			seterr(EOk, "read too small: asked for %d need at least %d", size, n);
			putlump(u);

			return nil;
		}
		p = packetdup(u->data, 0, n);
		putlump(u);
		return p;
	}

	if(cached)
		*cached = 0;

	if(lookupscore(score, type, &ia) < 0){
		/* ZZZ place to check for someone trying to guess scores */
		seterr(EOk, "no block with score %V/%d exists", score, type);

		putlump(u);
		return nil;
	}
	if(ia.size > size){
		seterr(EOk, "read too small 1: asked for %d need at least %d", size, ia.size);

		putlump(u);
		return nil;
	}

	trace(TraceLump, "readlump readilump");
	p = readilump(u, &ia, score);
	putlump(u);

	trace(TraceLump, "readlump exit");
	return p;
}
Пример #2
0
/*
 * save away a lump, and return it's score.
 * doesn't store duplicates, but checks that the data is really the same.
 */
int
writelump(Packet *p, u8int *score, int type, u32int creator, uint ms)
{
	Lump *u;
	int ok;

/*
	qlock(&stats.lock);
	stats.lumpwrites++;
	qunlock(&stats.lock);
*/

	packetsha1(p, score);
	if(packetsize(p) == 0 || writestodevnull==1){
		packetfree(p);
		return 0;
	}

	u = lookuplump(score, type);
	if(u->data != nil){
		ok = 0;
		if(packetcmp(p, u->data) != 0){
			uchar nscore[VtScoreSize];

			packetsha1(u->data, nscore);
			if(scorecmp(u->score, score) != 0)
				seterr(EStrange, "lookuplump returned bad score %V not %V", u->score, score);
			else if(scorecmp(u->score, nscore) != 0)
				seterr(EStrange, "lookuplump returned bad data %V not %V", nscore, u->score);
			else
				seterr(EStrange, "score collision %V", score);
			ok = -1;
		}
		packetfree(p);
		putlump(u);
		return ok;
	}

	if(writestodevnull==2){
		packetfree(p);
		return 0;
	}

	if(queuewrites)
		return queuewrite(u, p, creator, ms);

	ok = writeqlump(u, p, creator, ms);

	putlump(u);
	return ok;
}
Пример #3
0
static void
queueproc(void *vq)
{
	LumpQueue *q;
	Lump *u;
	Packet *p;
	int creator;
	uint ms;

	threadsetname("queueproc");

	q = vq;
	for(;;){
		qlock(&q->lock);
		while(q->w == q->r){
			trace(TraceProc, "queueproc sleep empty");
			rsleep(&q->empty);
		}

		u = q->q[q->r].u;
		p = q->q[q->r].p;
		creator = q->q[q->r].creator;
		ms = q->q[q->r].ms;

		q->r = (q->r + 1) & (MaxLumpQ - 1);
		trace(TraceProc, "queueproc wakeup flush");
		rwakeupall(&q->flush);

		trace(TraceProc, "queueproc wakeup full");
		rwakeup(&q->full);

		qunlock(&q->lock);

		trace(TraceProc, "queueproc writelump %V", u->score);
		if(writeqlump(u, p, creator, ms) < 0)
			fprint(2, "failed to write lump for %V: %r", u->score);
		trace(TraceProc, "queueproc wrotelump %V", u->score);

		putlump(u);
	}
}
Пример #4
0
static void
debugread(HConnect *c, u8int *score)
{
	int type;
	Lump *u;
	IAddr ia;
	IEntry ie;
	int i;
	Arena *arena;
	u64int aa;
	ZBlock *zb;
	Clump cl;
	vlong off;
	u8int sc[VtScoreSize];

	if(scorecmp(score, zeroscore) == 0){
		hprint(&c->hout, "zero score\n");
		return;
	}
	
	hprint(&c->hout, "<h2>index search %V</h2><pre>\n", score);
	if(icachelookup(score, -1, &ia) < 0)
		hprint(&c->hout, "  icache: not found\n");
	else
		hprint(&c->hout, "  icache: addr=%#llx size=%d type=%d blocks=%d\n",
			ia.addr, ia.size, ia.type, ia.blocks);
	
	if(loadientry(mainindex, score, -1, &ie) < 0)
		hprint(&c->hout, "  idisk: not found\n");
	else
		hprint(&c->hout, "  idisk: addr=%#llx size=%d type=%d blocks=%d\n",
			ie.ia.addr, ie.ia.size, ie.ia.type, ie.ia.blocks);
	
	hprint(&c->hout, "</pre><h2>lookup %V</h2>\n", score);
	hprint(&c->hout, "<pre>\n");
	
	for(type=0; type < VtMaxType; type++){
		hprint(&c->hout, "%V type %d:", score, type);
		u = lookuplump(score, type);
		if(u->data != nil)
			hprint(&c->hout, " +cache");
		else
			hprint(&c->hout, " -cache");
		putlump(u);
		
		if(lookupscore(score, type, &ia) < 0){
			hprint(&c->hout, " -lookup\n");
			continue;
		}
		hprint(&c->hout, "\n  lookupscore: addr=%#llx size=%d blocks=%d\n",
			ia.addr, ia.size, ia.blocks);
		
		arena = amapitoa(mainindex, ia.addr, &aa);
		if(arena == nil){
			hprint(&c->hout, "  amapitoa failed: %r\n");
			continue;
		}

		hprint(&c->hout, "  amapitoa: aa=%#llx arena="
			"<a href=\"/disk?disk=%s&type=a&arena=%s&score=%V\">%s</a>\n",
			aa, arena->part->name, arena->name, score, arena->name);
		zb = loadclump(arena, aa, ia.blocks, &cl, sc, 1);
		if(zb == nil){
			hprint(&c->hout, "  loadclump failed: %r\n");
			continue;
		}
		
		hprint(&c->hout, "  loadclump: uncsize=%d type=%d score=%V\n",
			cl.info.uncsize, cl.info.type, sc);
		if(ia.size != cl.info.uncsize || ia.type != cl.info.type || scorecmp(score, sc) != 0){
			hprint(&c->hout, "    clump info mismatch\n");
			continue;
		}
	}
	
	if(hargstr(c, "brute", "")[0] == 'y'){
		hprint(&c->hout, "</pre>\n");
		hprint(&c->hout, "<h2>brute force arena search %V</h2>\n", score);
		hprint(&c->hout, "<pre>\n");
		
		for(i=0; i<mainindex->narenas; i++){
			arena = mainindex->arenas[i];
			hprint(&c->hout, "%s...\n", arena->name);
			hflush(&c->hout);
			off = findintoc(nil, arena, score);
			if(off >= 0)
				hprint(&c->hout, "%s %#llx (%#llx)\n", arena->name, off, mainindex->amap[i].start + off);
		}
	}

	hprint(&c->hout, "</pre>\n");
}