Esempio n. 1
0
/*
 * read the arena header and trailer blocks from disk
 */
static int
loadarena(Arena *arena)
{
	ArenaHead head;
	ZBlock *b;

	b = alloczblock(arena->blocksize, 0, arena->part->blocksize);
	if(b == nil)
		return -1;
	if(readpart(arena->part, arena->base + arena->size, b->data, arena->blocksize) < 0){
		freezblock(b);
		return -1;
	}
	if(unpackarena(arena, b->data) < 0){
		freezblock(b);
		return -1;
	}
	if(arena->version != ArenaVersion4 && arena->version != ArenaVersion5){
		seterr(EAdmin, "unknown arena version %d", arena->version);
		freezblock(b);
		return -1;
	}
	scorecp(arena->score, &b->data[arena->blocksize - VtScoreSize]);

	if(readpart(arena->part, arena->base - arena->blocksize, b->data, arena->blocksize) < 0){
		logerr(EAdmin, "can't read arena header: %r");
		freezblock(b);
		return 0;
	}
	if(unpackarenahead(&head, b->data) < 0)
		logerr(ECorrupt, "corrupted arena header: %r");
	else if(namecmp(arena->name, head.name)!=0
	     || arena->clumpmagic != head.clumpmagic
	     || arena->version != head.version
	     || arena->blocksize != head.blocksize
	     || arena->size + 2 * arena->blocksize != head.size){
		if(namecmp(arena->name, head.name)!=0)
			logerr(ECorrupt, "arena tail name %s head %s", 
				arena->name, head.name);
		else if(arena->clumpmagic != head.clumpmagic)
			logerr(ECorrupt, "arena %d tail clumpmagic 0x%lux head 0x%lux",
				debugarena, (uint32_t)arena->clumpmagic,
				(uint32_t)head.clumpmagic);
		else if(arena->version != head.version)
			logerr(ECorrupt, "arena tail version %d head version %d",
				arena->version, head.version);
		else if(arena->blocksize != head.blocksize)
			logerr(ECorrupt, "arena tail block size %d head %d",
				arena->blocksize, head.blocksize);
		else if(arena->size+2*arena->blocksize != head.size)
			logerr(ECorrupt, "arena tail size %lud head %lud",
				(uint32_t)arena->size+2*arena->blocksize,
			       head.size);
		else
			logerr(ECorrupt, "arena header inconsistent with arena data");
	}
	freezblock(b);

	return 0;
}
Esempio n. 2
0
/*
 * Return the next IEntry (still packed) in the stream.
 */
static uint8_t*
peekientry(IEStream *ies)
{
	uint32_t n, nn;

	n = ies->epos - ies->pos;
	if(n < IEntrySize){
		memmove(ies->buf, ies->pos, n);
		ies->epos = &ies->buf[n];
		ies->pos = ies->buf;
		nn = ies->size;
		if(nn > ies->n * IEntrySize)
			nn = ies->n * IEntrySize;
		nn -= n;
		if(nn == 0)
			return nil;
//fprint(2, "peek %d from %llud into %p\n", nn, ies->off, ies->epos);
		if(readpart(ies->part, ies->off, ies->epos, nn) < 0){
			seterr(EOk, "can't read sorted index entries: %r");
			return nil;
		}
		ies->epos += nn;
		ies->off += nn;
	}
	return ies->pos;
}
Esempio n. 3
0
/*
 * read in the chained buffers for bucket b,
 * and return it's total number of IEntries
 */
static uint32_t
readiebuck(IEBucks *ib, int b)
{
	uint32_t head, m, n;

	head = ib->bucks[b].head;
	n = 0;
	m = ib->bucks[b].used;
	if(m == 0)
		m = ib->usable;
	if(0) if(ib->bucks[b].total)
		fprint(2, "\tbucket %d: %lld entries\n", b, ib->bucks[b].total/IEntrySize);
	while(head != TWID32){
		if(readpart(ib->part, (uint64_t)head * ib->size, &ib->buf[n], m+U32Size) < 0){
			seterr(EOk, "can't read index sort bucket: %r");
			return TWID32;
		}
		n += m;
		head = U32GET(&ib->buf[n]);
		m = ib->usable;
	}
	if(n != ib->bucks[b].total)
		fprint(2, "\tbucket %d: expected %d entries, got %d\n",
			b, (int)ib->bucks[b].total/IEntrySize, n/IEntrySize);
	return n / IEntrySize;
}
Esempio n. 4
0
static vlong
findintoc(HConnect *c, Arena *arena, uchar *score)
{
	uchar *blk;
	int i;
	vlong off;
	vlong coff;
	ClumpInfo ci;

	blk = vtmalloc(arena->blocksize);
	off = arena->base + arena->size;
	coff = 0;
	for(i=0; i<arena->memstats.clumps; i++){
		if(i%arena->clumpmax == 0){
			off -= arena->blocksize;
			if(readpart(arena->part, off, blk, arena->blocksize) != arena->blocksize){
				if(c)
					hprint(&c->hout, "<i>clump info directory at %#llx: %r</i>\n<br>\n",
						off);
				break;
			}
		}
		unpackclumpinfo(&ci, blk+(i%arena->clumpmax)*ClumpInfoSize);
		if(scorecmp(ci.score, score) == 0){
			vtfree(blk);
			return coff;
		}
		coff += ClumpSize + ci.size;
	}
	vtfree(blk);
	return -1;
}
Esempio n. 5
0
Bloom*
readbloom(Part *p)
{
	uchar buf[512];
	Bloom *b;
	
	b = vtmallocz(sizeof *b);
	if(readpart(p, 0, buf, sizeof buf) < 0)
		return nil;
	/*
	 * pass buf as b->data so that bloominit
	 * can parse header.  won't be used for
	 * accessing bits (cleared below).
	 */
	if(bloominit(b, 0, buf) < 0){
		vtfree(b);
		return nil;
	}else{
		/*
		 * default block size is system page size.
		 * the bloom filter is usually very big.
		 * bump the block size up to speed i/o.
		 */
		if(p->blocksize < (1<<20)){
			p->blocksize = 1<<20;
			if(p->blocksize > p->size)
				p->blocksize = p->size;
		}
	}
	b->part = p;
	b->data = nil;
	return b;
}
Esempio n. 6
0
static void
rdarena(Arena *arena)
{
	ZBlock *b;
	uint64_t a, e;
	uint32_t bs;

	if (!quiet) {
		fprint(2, "copying %s to standard output\n", arena->name);
		printarena(2, arena);
	}

	bs = MaxIoSize;
	if(bs < arena->blocksize)
		bs = arena->blocksize;

	b = alloczblock(bs, 0, arena->blocksize);
	e = arena->base + arena->size + arena->blocksize;
	for(a = arena->base - arena->blocksize; a + arena->blocksize <= e; a += bs){
		if(a + bs > e)
			bs = arena->blocksize;
		if(readpart(arena->part, a, b->data, bs) < 0)
			fprint(2, "can't copy %s, read at %lld failed: %r\n", arena->name, a);	
		if(write(1, b->data, bs) != bs)
			sysfatal("can't copy %s, write at %lld failed: %r", arena->name, a);
	}

	freezblock(b);
}
Esempio n. 7
0
int
loadbloom(Bloom *b)
{
	int i, n;
	uint ones;
	uchar *data;
	u32int *a;
	
	data = vtmallocz(b->size);
	if(readpart(b->part, 0, data, b->size) < 0){
		vtfree(b);
		vtfree(data);
		return -1;
	}
	b->data = data;

	a = (u32int*)b->data;
	n = b->size/4;
	ones = 0;
	for(i=0; i<n; i++)
		ones += countbits(a[i]); 
	addstat(StatBloomOnes, ones);

	if(b->size == MaxBloomSize)	/* 2^32 overflows ulong */
		addstat(StatBloomBits, b->size*8-1);
	else
		addstat(StatBloomBits, b->size*8);
		
	return 0;
}
Esempio n. 8
0
ISect*
initisect(Part *part)
{
	ISect *is;
	ZBlock *b;
	int ok;

	b = alloczblock(HeadSize, 0, 0);
	if(b == nil || readpart(part, PartBlank, b->data, HeadSize) < 0){
		seterr(EAdmin, "can't read index section header: %r");
		return nil;
	}

	is = MKZ(ISect);
	if(is == nil){
		freezblock(b);
		return nil;
	}
	is->part = part;
	ok = unpackisect(is, b->data);
	freezblock(b);
	if(ok < 0){
		seterr(ECorrupt, "corrupted index section header: %r");
		freeisect(is);
		return nil;
	}

	if(is->version != ISectVersion1 && is->version != ISectVersion2){
		seterr(EAdmin, "unknown index section version %d", is->version);
		freeisect(is);
		return nil;
	}

	return initisect1(is);
}
Esempio n. 9
0
/*
 * Read in the len bytes of data at the offset.  If can't for whatever reason,
 * fill it with garbage but print an error.
 */
static uchar*
readdisk(uchar *buf, vlong offset, int len)
{
	int i, j, k, n;

	if(offset >= partend){
		memset(buf, 0xFB, len);
		return buf;
	}
	
	if(offset+len > partend){
		memset(buf, 0xFB, len);
		len = partend - offset;
	}

	if(readpart(part, offset, buf, len) >= 0)
		return buf;
	
	/*
	 * The read failed.  Clear the buffer to nonsense, and
	 * then try reading in smaller pieces.  If that fails,
	 * read in even smaller pieces.  And so on down to sectors.
	 */
	memset(buf, 0xFD, len);
	for(i=0; i<len; i+=64*K){
		n = 64*K;
		if(i+n > len)
			n = len-i;
		if(readpart(part, offset+i, buf+i, n) >= 0)
			continue;
		for(j=i; j<len && j<i+64*K; j+=4*K){
			n = 4*K;
			if(j+n > len)
				n = len-j;
			if(readpart(part, offset+j, buf+j, n) >= 0)
				continue;
			for(k=j; k<len && k<j+4*K; k+=512){
				if(readpart(part, offset+k, buf+k, 512) >= 0)
					continue;
				bad("disk read failed at", k, 512);
				badreads++;
			}
		}
	}
	bad(nil, 0, 0);
	return buf;
}
Esempio n. 10
0
static int
diskarenatoc(HConnect *c, Arena *arena)
{
	uchar *blk;
	int i;
	vlong off;
	vlong coff;
	ClumpInfo ci;
	char base[512];
	int cib;

	snprint(base, sizeof base, "/disk?disk=%s&type=a&arena=%s",
		arena->part->name, arena->name);

	blk = vtmalloc(arena->blocksize);
	off = arena->base + arena->size;
	hprint(&c->hout, "<h2>table of contents</h2>\n");
	hprint(&c->hout, "<pre>\n");
	hprint(&c->hout, "%5s %6s %7s %s\n", "type", "size", "uncsize", "score");
	coff = 0;
	cib = hargint(c, "cib", 0);

	for(i=0; i<arena->memstats.clumps; i++){
		if(i%arena->clumpmax == 0){
			off -= arena->blocksize;
			if(readpart(arena->part, off, blk, arena->blocksize) != arena->blocksize){
				hprint(&c->hout, "<i>clump info directory at %#llx: %r</i>\n<br>\n",
					off);
				i += arena->clumpmax-1;
				coff = -1;
				continue;
			}
		}
		unpackclumpinfo(&ci, blk+(i%arena->clumpmax)*ClumpInfoSize);
		if(i/arena->clumpmax == cib || i%arena->clumpmax == 0){
			hprint(&c->hout, "%5d %6d %7d %V", 
				ci.type, ci.size, ci.uncsize, ci.score);
			if(coff >= 0)
				hprint(&c->hout, " at <a href=\"%s&clump=%#llx&score=%V\">%#llx</a>", 
					base, coff, ci.score, coff);
			if(i/arena->clumpmax != cib)
				hprint(&c->hout, "  <font size=-1><a href=\"%s&cib=%d\">more</a></font>", base, i/arena->clumpmax);
			hprint(&c->hout, "\n");
		}
		if(coff >= 0)
			coff += ClumpSize + ci.size;
	}
	hprint(&c->hout, "</pre>\n");
	return 0;
}
Esempio n. 11
0
static char*
readap(Part *p, ArenaPart *ap)
{
	uchar *blk;
	char *table;
	
	blk = vtmalloc(8192);
	if(readpart(p, PartBlank, blk, 8192) != 8192)
		return nil;
	if(unpackarenapart(ap, blk) < 0){
		werrstr("corrupt arena part header: %r");
		return nil;
	}
	vtfree(blk);
	ap->tabbase = (PartBlank+HeadSize+ap->blocksize-1)&~(ap->blocksize-1);
	ap->tabsize = ap->arenabase - ap->tabbase;
	table = vtmalloc(ap->tabsize+1);
	if(readpart(p, ap->tabbase, (uchar*)table, ap->tabsize) != ap->tabsize){
		werrstr("reading arena part directory: %r");
		return nil;
	}
	table[ap->tabsize] = 0;
	return table;
}
Esempio n. 12
0
int
partifile(IFile *f, Part *part, u64int start, u32int size)
{
	ZBlock *b;

	b = alloczblock(size, 0, part->blocksize);
	if(b == nil)
		return -1;
	if(readpart(part, start, b->data, size) < 0){
		seterr(EAdmin, "can't read %s: %r", part->name);
		freezblock(b);
		return -1;
	}
	f->name = part->name;
	f->b = b;
	f->pos = 0;
	return 0;
}
Esempio n. 13
0
void
dumpisect(ISect *is)
{
	int j;
	uchar *buf;
	u32int i;
	u64int off;
	IBucket ib;
	IEntry ie;

	buf = emalloc(is->blocksize);
	for(i=0; i<is->blocks; i++){
		off = is->blockbase+(u64int)is->blocksize*i;
		if(readpart(is->part, off, buf, is->blocksize) < 0)
			fprint(2, "read %s at 0x%llux: %r\n", is->part->name, off);
		else{
			unpackibucket(&ib, buf, is->bucketmagic);
			for(j=0; j<ib.n; j++){
				unpackientry(&ie, &ib.data[j*IEntrySize]);
				pie(&ie);
			}
		}
	}
}
Esempio n. 14
0
  void load_Files(void){
    int i;
    int errorcode;

//    show_glui_alert();
    for(i=0;i<nplot3dinfo;i++){
      plot3ddata *plot3di;

      plot3di = plot3dinfo + i;
      if(plot3di->autoload==0&&plot3di->loaded==1){
        readplot3d(plot3di->file,i,UNLOAD,&errorcode);
      }
      if(plot3di->autoload==1){
        ReadPlot3dFile=1;
        readplot3d(plot3di->file,i,LOAD,&errorcode);
      }
    }
    npartframes_max=get_min_partframes();
    for(i=0;i<npartinfo;i++){
      partdata *parti;

      parti = partinfo + i;
      if(parti->autoload==0&&parti->loaded==1)readpart(parti->file,i,UNLOAD,&errorcode);
      if(parti->autoload==1)readpart(parti->file,i,UNLOAD,&errorcode);
    }
    for(i=0;i<npartinfo;i++){
      partdata *parti;

      parti = partinfo + i;
      if(parti->autoload==0&&parti->loaded==1)readpart(parti->file,i,UNLOAD,&errorcode);
      if(parti->autoload==1)readpart(parti->file,i,LOAD,&errorcode);
    }
    update_readiso_geom_wrapup == UPDATE_ISO_START_ALL;
    for(i = 0; i<nisoinfo; i++){
      isodata *isoi;

      isoi = isoinfo + i;
      if(isoi->autoload==0&&isoi->autoload==1)readiso(isoi->file,i,UNLOAD,&errorcode);
      if(isoi->autoload == 1){
        readiso(isoi->file, i, LOAD, &errorcode);
      }
    }
    if(update_readiso_geom_wrapup == UPDATE_ISO_ALL_NOW)readiso_geom_wrapup();
    update_readiso_geom_wrapup = UPDATE_ISO_OFF;
    for(i = 0; i<nvsliceinfo; i++){
      vslicedata *vslicei;

      vslicei = vsliceinfo + i;
      if(vslicei->autoload==0&&vslicei->loaded==1)readvslice(i,UNLOAD,&errorcode);
      if(vslicei->autoload==1){
        readvslice(i,LOAD,&errorcode);
      }
    }
    // note:  only slices that are NOT a part of a vector slice will be loaded here
    for(i=0;i<nsliceinfo;i++){
      slicedata *slicei;

      slicei = sliceinfo + i;
      if(slicei->autoload==0&&slicei->loaded==1)readslice(slicei->file,i,UNLOAD,&errorcode);
      if(slicei->autoload==1&&slicei->loaded==0){
        readslice(slicei->file,i,LOAD,&errorcode);
      }
    }
    for(i=0;i<nterraininfo;i++){
      terraindata *terri;

      terri = terraininfo + i;
      if(terri->autoload==0&&terri->loaded==1)readterrain(terri->file,i,UNLOAD,&errorcode);
      if(terri->autoload==1&&terri->loaded==0)readslice(terri->file,i,LOAD,&errorcode);
    }
    for(i=0;i<nsmoke3dinfo;i++){
      smoke3ddata *smoke3di;

      smoke3di = smoke3dinfo + i;
      if(smoke3di->autoload==0&&smoke3di->loaded==1)readsmoke3d(i,UNLOAD,&errorcode);
      if(smoke3di->autoload==1)readsmoke3d(i,LOAD,&errorcode);
    }
    for(i=0;i<npatchinfo;i++){
      patchdata *patchi;

      patchi = patchinfo + i;
      if(patchi->autoload==0&&patchi->loaded==1)readpatch(i,UNLOAD,&errorcode);
      if(patchi->autoload==1)readpatch(i,LOAD,&errorcode);
    }
    force_redisplay=1;
    Update_Framenumber(0);
    updatemenu=1;
    update_load_Files=0;
    hide_glui_alert();
    TrainerViewMenu(trainerview);
  }
Esempio n. 15
0
void
sumarena(Arena *arena)
{
	ZBlock *b;
	DigestState s;
	uint64_t a, e;
	uint32_t bs;
	int t;
	uint8_t score[VtScoreSize];

	bs = MaxIoSize;
	if(bs < arena->blocksize)
		bs = arena->blocksize;

	/*
	 * read & sum all blocks except the last one
	 */
	flushdcache();
	memset(&s, 0, sizeof s);
	b = alloczblock(bs, 0, arena->part->blocksize);
	e = arena->base + arena->size;
	for(a = arena->base - arena->blocksize; a + arena->blocksize <= e; a += bs){
		disksched();
		while((t=arenasumsleeptime) == SleepForever){
			sleep(1000);
			disksched();
		}
		sleep(t);
		if(a + bs > e)
			bs = arena->blocksize;
		if(readpart(arena->part, a, b->data, bs) < 0)
			goto ReadErr;
		addstat(StatSumRead, 1);
		addstat(StatSumReadBytes, bs);
		sha1(b->data, bs, nil, &s);
	}

	/*
	 * the last one is special, since it may already have the checksum included
	 */
	bs = arena->blocksize;
	if(readpart(arena->part, e, b->data, bs) < 0){
ReadErr:
		logerr(EOk, "sumarena can't sum %s, read at %lld failed: %r", arena->name, a);
		freezblock(b);
		return;
	}
	addstat(StatSumRead, 1);
	addstat(StatSumReadBytes, bs);

	sha1(b->data, bs-VtScoreSize, nil, &s);
	sha1(zeroscore, VtScoreSize, nil, &s);
	sha1(nil, 0, score, &s);
	
	/*
	 * check for no checksum or the same
	 */
	if(scorecmp(score, &b->data[bs - VtScoreSize]) != 0
	&& scorecmp(zeroscore, &b->data[bs - VtScoreSize]) != 0)
		logerr(EOk, "overwriting mismatched checksums for arena=%s, found=%V calculated=%V",
			arena->name, &b->data[bs - VtScoreSize], score);
	freezblock(b);

	qlock(&arena->lock);
	scorecp(arena->score, score);
	wbarena(arena);
	qunlock(&arena->lock);
}
Esempio n. 16
0
int
readifile(IFile *f, char *name)
{
	Part *p;
	ZBlock *b;
	u8int *z;

	p = initpart(name, OREAD);
	if(p == nil)
		return -1;
	b = alloczblock(Maxconfig+1, 1, 0);
	if(b == nil){
		seterr(EOk, "can't alloc for %s: %R", name);
		return -1;
	}
	if(p->size > PartBlank){
		/*
		 * this is likely a real venti partition, in which case we're
		 * looking for the config file stored as 8k at end of PartBlank.
		 */
		if(readpart(p, PartBlank-Maxconfig, b->data, Maxconfig) < 0){
			seterr(EOk, "can't read %s: %r", name);
			freezblock(b);
			freepart(p);
			return -1;
		}
		b->data[Maxconfig] = '\0';
		if(memcmp(b->data, vcmagic, Maglen) != 0){
			seterr(EOk, "bad venti config magic in %s", name);
			freezblock(b);
			freepart(p);
			return -1;
		}
		/*
		 * if we change b->data+b->_size, freezblock
		 * will blow an assertion, so don't.
		 */
		b->data  += Maglen;
		b->_size -= Maglen;
		b->len   -= Maglen;
		z = memchr(b->data, '\0', b->len);
		if(z)
			b->len = z - b->data;
	}else if(p->size > Maxconfig){
		seterr(EOk, "config file is too large");
		freepart(p);
		freezblock(b);
		return -1;
	}else{
		freezblock(b);
		b = readfile(name);
		if(b == nil){
			freepart(p);
			return -1;
		}
	}
	freepart(p);
	f->name = name;
	f->b = b;
	f->pos = 0;
	return 0;
}
Esempio n. 17
0
static int
icachewritesect(Index *ix, ISect *is, u8int *buf)
{
	int err, i, werr, h, bsize, t;
	u32int lo, hi;
	u64int addr, naddr;
	uint nbuf, off;
	DBlock *b;
	IBucket ib;
	IEntry *ie, *iedirty, **l, *chunk;

	lo = is->start * ix->div;
	if(TWID32/ix->div < is->stop)
		hi = TWID32;
	else
		hi = is->stop * ix->div - 1;

	trace(TraceProc, "icachewritesect enter %ud %ud %llud",
		lo, hi, iwrite.as.aa);

	iedirty = icachedirty(lo, hi, iwrite.as.aa);
	iedirty = iesort(iedirty);
	bsize = 1 << is->blocklog;
	err = 0;

	while(iedirty){
		disksched();
		while((t = icachesleeptime) == SleepForever){
			sleep(1000);
			disksched();
		}
		if(t < minicachesleeptime)
			t = minicachesleeptime;
		if(t > 0)
			sleep(t);
		trace(TraceProc, "icachewritesect nextchunk");
		chunk = nextchunk(ix, is, &iedirty, &addr, &nbuf);

		trace(TraceProc, "icachewritesect readpart 0x%llux+0x%ux",
			addr, nbuf);
		if(readpart(is->part, addr, buf, nbuf) < 0){
			fprint(2, "%s: part %s addr 0x%llux: icachewritesect "
				"readpart: %r\n", argv0, is->part->name, addr);
			err  = -1;
			continue;
		}
		trace(TraceProc, "icachewritesect updatebuf");
		addstat(StatIsectReadBytes, nbuf);
		addstat(StatIsectRead, 1);

		for(l=&chunk; (ie=*l)!=nil; l=&ie->nextdirty){
again:
			naddr = ie2diskaddr(ix, is, ie);
			off = naddr - addr;
			if(off+bsize > nbuf){
				fprint(2, "%s: whoops! addr=0x%llux nbuf=%ud "
					"addr+nbuf=0x%llux naddr=0x%llux\n",
					argv0, addr, nbuf, addr+nbuf, naddr);
				assert(off+bsize <= nbuf);
			}
			unpackibucket(&ib, buf+off, is->bucketmagic);
			if(okibucket(&ib, is) < 0){
				fprint(2, "%s: bad bucket XXX\n", argv0);
				goto skipit;
			}
			trace(TraceProc, "icachewritesect add %V at 0x%llux",
				ie->score, naddr);
			h = bucklook(ie->score, ie->ia.type, ib.data, ib.n);
			if(h & 1){
				h ^= 1;
				packientry(ie, &ib.data[h]);
			}else if(ib.n < is->buckmax){
				memmove(&ib.data[h + IEntrySize], &ib.data[h],
					ib.n*IEntrySize - h);
				ib.n++;
				packientry(ie, &ib.data[h]);
			}else{
				fprint(2, "%s: bucket overflow XXX\n", argv0);
skipit:
				err = -1;
				*l = ie->nextdirty;
				ie = *l;
				if(ie)
					goto again;
				else
					break;
			}
			packibucket(&ib, buf+off, is->bucketmagic);
		}

		diskaccess(1);

		trace(TraceProc, "icachewritesect writepart", addr, nbuf);
		werr = 0;
		if(writepart(is->part, addr, buf, nbuf) < 0 || flushpart(is->part) < 0)
			werr = -1;

		for(i=0; i<nbuf; i+=bsize){
			if((b = _getdblock(is->part, addr+i, ORDWR, 0)) != nil){
				memmove(b->data, buf+i, bsize);
				putdblock(b);
			}
		}

		if(werr < 0){
			fprint(2, "%s: part %s addr 0x%llux: icachewritesect "
				"writepart: %r\n", argv0, is->part->name, addr);
			err = -1;
			continue;
		}
		
		addstat(StatIsectWriteBytes, nbuf);
		addstat(StatIsectWrite, 1);
		icacheclean(chunk);
	}

	trace(TraceProc, "icachewritesect done");
	return err;
}
Esempio n. 18
0
vol_err_t vol_getfilenames(vol_t handle)
{
    struct volume* vhnd = handle;
    struct vfile *curfile;
    log_info("Fetching filenames from array.");
    guint64 os;
    os = vhnd->footer.filenames.offset;
    gint i, j = 0, l = 0;
    vol_err_t err;
    gchar* datadir;
    guint8 bite;
    log_debug("Scraping array header.");
    for (i=0; i <=4; i++)
    {
        err = vol_getheader(handle, &vhnd->footer.filenames.header,
                                     vhnd->footer.filenames.offset + i);
        if (err)
            return err;

        /* Header verification
         * There might be a memory leak here
         */
        if (memcmp("vols", vhnd->footer.filenames.header.ident, 4))
        {
            log_debug("Retrieved IDstring does not matched needed IDstring.");
            err = VOL_ERR_BADHEADER;
        } else {
            vhnd->footer.filenames.offset += i;
            err = VOL_ERR_OK;
            break;
        }
    }
    if (err == VOL_ERR_BADHEADER)
    {
        log_critical("Array identity string not recognized.");
        return VOL_ERR_BROKEN;
    }
    if (vhnd->footer.filenames.header.val != 0)
    {
        os+=sizeof(struct header);
        vhnd->footer.filenames.data = g_ptr_array_new_with_free_func(g_free);
        vhnd->files = g_ptr_array_new_with_free_func(vol_filesarray_free);
        log_debug("Fetching array data.");
        for (i = 0; i < vhnd->footer.filenames.header.val; i++)
        {
            if (j == 0)
                log_debug("Seeking to end of string.");
            j++;
            readbyte(&vhnd->volio, (guint64)(os+j), &bite);
            if (bite == 0x00)
            {
                j++;
                log_debug("String at offset 0x%lx indexed. Size is %d. Pulling now.", os, j);
                gchar *data, *sanitary, *pathcopy1, *pathcopy2;
                curfile = (struct vfile*)g_malloc(sizeof(struct vfile));
                curfile->vol = vhnd;
                curfile->data.data = NULL;
                data = readpart(&vhnd->volio, (guint64)os, sizeof(gchar)*j);
                sanitary = sanitizepath(data);
                log_debug("Pulled string: %s.", data);
                i++;
                os+=j;
                j=0;
                log_debug("Adding string to arrays.");
                pathcopy1 = g_strdup(sanitary);
                pathcopy2 = g_strdup(sanitary);
                g_ptr_array_add(vhnd->footer.filenames.data, (gpointer)data);
                curfile->path = g_strdup(data);
                curfile->path_canonical = sanitary;
                curfile->name = g_strdup(basename(pathcopy1));
                curfile->dir = g_strdup(dirname(pathcopy2));
                g_free(pathcopy1);
                g_free(pathcopy2);
                g_ptr_array_add(vhnd->files, (gpointer)curfile);
                l++;
            } else if (bite == 0x5C) {
                log_todo("Warn windows users about invalid characters and forward slashes");
                log_warning("An internal path string may contain backslashes.");
            }
        }
        struct counter* k;
        k = g_malloc0(sizeof(struct counter));
        k->count = 0;
        log_info("File arrays created.");
        g_ptr_array_foreach(vhnd->files, printfiles, (gpointer)k);
        g_free(k);
    } else {
        log_message("Array is empty. (No files in volume?)");
        vhnd->footer.filenames.data = NULL;
    }
    vhnd->footer.fileprops.offset = vhnd->footer.filenames.header.val
                                    +vhnd->footer.filenames.offset+sizeof(struct header);
    return err;
}
Esempio n. 19
0
static int
diskarenaclump(HConnect *c, Arena *arena, vlong off, char *scorestr)
{
	uchar *blk, *blk2;
	Clump cl;
	char err[ERRMAX];
	uchar xscore[VtScoreSize], score[VtScoreSize];
	Unwhack uw;
	int n;
	
	if(scorestr){
		if(vtparsescore(scorestr, nil, score) < 0){
			hprint(&c->hout, "bad score %s: %r\n", scorestr);
			return -1;
		}
		if(off < 0){
			off = findintoc(c, arena, score);
			if(off < 0){
				hprint(&c->hout, "score %V not found in arena %s\n", score, arena->name);
				return -1;
			}
			hprint(&c->hout, "score %V at %#llx\n", score, off);
		}
	}else
		memset(score, 0, sizeof score);

	if(off < 0){
		hprint(&c->hout, "bad offset %#llx\n", off);
		return -1;
	}
	
	off += arena->base;

	blk = vtmalloc(ClumpSize + VtMaxLumpSize);
	if(readpart(arena->part, off, blk, ClumpSize + VtMaxLumpSize) != ClumpSize + VtMaxLumpSize){
		hprint(&c->hout, "reading at %#llx: %r\n", off);
		vtfree(blk);
		return -1;
	}

	if(unpackclump(&cl, blk, arena->clumpmagic) < 0){
		hprint(&c->hout, "unpackclump: %r\n<br>");
		rerrstr(err, sizeof err);
		if(strstr(err, "magic")){
			hprint(&c->hout, "trying again with magic=%#ux<br>\n", U32GET(blk));
			if(unpackclump(&cl, blk, U32GET(blk)) < 0){
				hprint(&c->hout, "unpackclump: %r\n<br>\n");
				goto error;
			}
		}else
			goto error;
	}

	hprint(&c->hout, "<pre>type=%d size=%d uncsize=%d score=%V\n", cl.info.type, cl.info.size, cl.info.uncsize, cl.info.score);
	hprint(&c->hout, "encoding=%d creator=%d time=%d %s</pre>\n", cl.encoding, cl.creator, cl.time, fmttime(err, cl.time));
	
	if(cl.info.type == VtCorruptType)
		hprint(&c->hout, "clump is marked corrupt<br>\n");
	
	if(cl.info.size >= VtMaxLumpSize){
		hprint(&c->hout, "clump too big\n");
		goto error;
	}
	
	switch(cl.encoding){
	case ClumpECompress:
		blk2 = vtmalloc(VtMaxLumpSize);
		unwhackinit(&uw);
		n = unwhack(&uw, blk2, cl.info.uncsize, blk+ClumpSize, cl.info.size);
		if(n < 0){
			hprint(&c->hout, "decompression failed\n");
			vtfree(blk2);
			goto error;
		}
		if(n != cl.info.uncsize){
			hprint(&c->hout, "got wrong amount: %d wanted %d\n", n, cl.info.uncsize);
			// hhex(blk2, n);
			vtfree(blk2);
			goto error;
		}
		scoremem(xscore, blk2, cl.info.uncsize);
		vtfree(blk2);
		break;
	case ClumpENone:
		scoremem(xscore, blk+ClumpSize, cl.info.size);
		break;
	}
	
	hprint(&c->hout, "score=%V<br>\n", xscore);
	if(scorestr && scorecmp(score, xscore) != 0)
		hprint(&c->hout, "score does NOT match expected %V\n", score);

	vtfree(blk);
	return 0;

error:
	// hhex(blk, ClumpSize + VtMaxLumpSize);
	vtfree(blk);
	return -1;
}
Esempio n. 20
0
void
threadmain(int argc, char *argv[])
{
	int i;
	char *file;
	Arena *arena;
	u64int offset, aoffset;
	Part *part;
	uchar buf[8192];
	ArenaHead head;
	ZClump zerocl;

	ventifmtinstall();
	qlock(&godot);
	aoffset = 0;
	ARGBEGIN{
	case 'f':
		fast = 1;
		ventidoublechecksha1 = 0;
		break;
	case 'h':
		host = EARGF(usage());
		break;
	case 'o':
		haveaoffset = 1;
		aoffset = strtoull(EARGF(usage()), 0, 0);
		break;
	case 'M':
		maxwrites = atoi(EARGF(usage()));
		break;
	case 'v':
		verbose = 1;
		break;
	default:
		usage();
		break;
	}ARGEND

	offset = ~(u64int)0;
	switch(argc) {
	default:
		usage();
	case 2:
		offset = strtoull(argv[1], 0, 0);
		/* fall through */
	case 1:
		file = argv[0];
	}

	fmtinstall('V', vtscorefmt);

	statsinit();

	part = initpart(file, OREAD);
	if(part == nil)
		sysfatal("can't open file %s: %r", file);
	if(readpart(part, aoffset, buf, sizeof buf) < 0)
		sysfatal("can't read file %s: %r", file);

	if(unpackarenahead(&head, buf) < 0)
		sysfatal("corrupted arena header: %r");

	if(aoffset+head.size > part->size)
		sysfatal("arena is truncated: want %llud bytes have %llud",
			head.size, part->size);

	partblocksize(part, head.blocksize);
	initdcache(8 * MaxDiskBlock);

	arena = initarena(part, aoffset, head.size, head.blocksize);
	if(arena == nil)
		sysfatal("initarena: %r");

	z = nil;
	if(host==nil || strcmp(host, "/dev/null") != 0){
		z = vtdial(host);
		if(z == nil)
			sysfatal("could not connect to server: %r");
		if(vtconnect(z) < 0)
			sysfatal("vtconnect: %r");
	}
	
	c = chancreate(sizeof(ZClump), 0);
	for(i=0; i<12; i++)
		vtproc(vtsendthread, nil);

	rdarena(arena, offset);
	if(vtsync(z) < 0)
		sysfatal("executing sync: %r");

	memset(&zerocl, 0, sizeof zerocl);
	for(i=0; i<12; i++)
		send(c, &zerocl);
	if(z){
		vthangup(z);
	}
	threadexitsall(0);
}
Esempio n. 21
0
static int
diskarenapart(HConnect *c, char *disk, Part *p)
{
	char *arenaname;
	ArenaPart ap;
	ArenaHead head;
	Arena arena;
	char *table;
	char *score;
	char *clump;
	uchar *blk;
	vlong start, end, off;
	char tbuf[60];

	hprint(&c->hout, "<h1>arena partition %s</h1>\n", disk);

	if((table = readap(p, &ap)) == nil){
		hprint(&c->hout, "%r\n");
		goto out;
	}
	
	hprint(&c->hout, "<pre>\n");
	hprint(&c->hout, "version=%d blocksize=%d base=%d\n",
		ap.version, ap.blocksize, ap.arenabase);
	hprint(&c->hout, "</pre>\n");

	arenaname = hargstr(c, "arena", "");
	if(arenaname[0] == 0){
		diskarenatable(c, disk, table);
		goto out;
	}
	
	if(xfindarena(table, arenaname, &start, &end) < 0){
		hprint(&c->hout, "no such arena %s\n", arenaname);
		goto out;
	}
	
	hprint(&c->hout, "<h2>arena %s</h2>\n", arenaname);
	hprint(&c->hout, "<pre>start=%#llx end=%#llx<pre>\n", start, end);
	if(end < start || end - start < HeadSize){
		hprint(&c->hout, "bad size %#llx\n", end - start);
		goto out;
	}

	// read arena header, tail
	blk = vtmalloc(HeadSize);
	if(readpart(p, start, blk, HeadSize) != HeadSize){
		hprint(&c->hout, "reading header: %r\n");
		vtfree(blk);
		goto out;
	}
	if(unpackarenahead(&head, blk) < 0){
		hprint(&c->hout, "corrupt arena header: %r\n");
		// hhex(blk, HeadSize);
		vtfree(blk);
		goto out;
	}
	vtfree(blk);

	hprint(&c->hout, "head:\n<pre>\n");
	hprint(&c->hout, "version=%d name=%s blocksize=%d size=%#llx clumpmagic=%#ux\n",
		head.version, head.name, head.blocksize, head.size, 
		head.clumpmagic);
	hprint(&c->hout, "</pre><br><br>\n");

	if(head.blocksize > MaxIoSize || head.blocksize >= end - start){
		hprint(&c->hout, "corrupt block size %d\n", head.blocksize);
		goto out;
	}

	blk = vtmalloc(head.blocksize);
	if(readpart(p, end - head.blocksize, blk, head.blocksize) < 0){
		hprint(&c->hout, "reading tail: %r\n");
		vtfree(blk);
		goto out;
	}
	memset(&arena, 0, sizeof arena);
	arena.part = p;
	arena.blocksize = head.blocksize;
	arena.clumpmax = head.blocksize / ClumpInfoSize;
	arena.base = start + head.blocksize;
	arena.size = end - start - 2 * head.blocksize;
	if(unpackarena(&arena, blk) < 0){
		vtfree(blk);
		goto out;
	}
	scorecp(arena.score, blk+head.blocksize - VtScoreSize);

	vtfree(blk);
	
	hprint(&c->hout, "tail:\n<pre>\n");
	hprint(&c->hout, "version=%d name=%s\n", arena.version, arena.name);
	hprint(&c->hout, "ctime=%d %s\n", arena.ctime, fmttime(tbuf, arena.ctime));
	hprint(&c->hout, "wtime=%d %s\n", arena.wtime, fmttime(tbuf, arena.wtime));
	hprint(&c->hout, "clumpmagic=%#ux\n", arena.clumpmagic);
	hprint(&c->hout, "score %V\n", arena.score);
	hprint(&c->hout, "diskstats:\n");
	hprint(&c->hout, "\tclumps=%,d cclumps=%,d used=%,lld uncsize=%,lld sealed=%d\n",
		arena.diskstats.clumps, arena.diskstats.cclumps,
		arena.diskstats.used, arena.diskstats.uncsize,
		arena.diskstats.sealed);
	hprint(&c->hout, "memstats:\n");
	hprint(&c->hout, "\tclumps=%,d cclumps=%,d used=%,lld uncsize=%,lld sealed=%d\n",
		arena.memstats.clumps, arena.memstats.cclumps,
		arena.memstats.used, arena.memstats.uncsize,
		arena.memstats.sealed);
	if(arena.clumpmax == 0){
		hprint(&c->hout, "bad clumpmax\n");
		goto out;
	}

	score = hargstr(c, "score", "");
	clump = hargstr(c, "clump", "");

	if(clump[0]){
		off = strtoull(clump, 0, 0);
		diskarenaclump(c, &arena, off, score[0] ? score : nil);
	}else if(score[0]){
		diskarenaclump(c, &arena, -1, score);
	}else{
		diskarenatoc(c, &arena);
	}

out:
	free(table);
	return 0;
}