/*
 * Check and fix an arena partition.
 *
 * This is a lot grittier than the rest of Venti because
 * it can't just give up if a byte here or there is wrong.
 *
 * The rule here (hopefully followed!) is that block corruption
 * only ever has a local effect -- there are no blocks that you
 * can wipe out that will cause large portions of 
 * uncorrupted data blocks to be useless.
 */

#include "stdinc.h"
#include "dat.h"
#include "fns.h"
#include "whack.h"

#pragma varargck type "z" uvlong
#pragma varargck type "z" vlong
#pragma varargck type "t" uint

enum
{
	K = 1024,
	M = 1024*1024,
	G = 1024*1024*1024,
	
	Block = 4096,
};

int debugsha1;

int verbose;
Part *part;
char *file;
char *basename;
char *dumpbase;
int fix;
int badreads;
int unseal;
uchar zero[MaxDiskBlock];

Arena lastarena;
ArenaPart ap;
uvlong arenasize;
int nbadread;
int nbad;
uvlong partend;
void checkarena(vlong, int);

void
usage(void)
{
	fprint(2, "usage: fixarenas [-fv] [-a arenasize] [-b blocksize] file [ranges]\n");
	threadexitsall(0);
}

/*
 * Format number in simplest way that is okay with unittoull.
 */
static int
zfmt(Fmt *fmt)
{
	vlong x;
	
	x = va_arg(fmt->args, vlong);
	if(x == 0)
		return fmtstrcpy(fmt, "0");
	if(x%G == 0)
		return fmtprint(fmt, "%lldG", x/G);
	if(x%M == 0)
		return fmtprint(fmt, "%lldM", x/M);
	if(x%K == 0)
		return fmtprint(fmt, "%lldK", x/K);
	return fmtprint(fmt, "%lld", x);
}

/*
 * Format time like ctime without newline.
 */
static int
tfmt(Fmt *fmt)
{
	uint t;
	char buf[30];
	
	t = va_arg(fmt->args, uint);
	strcpy(buf, ctime(t));
	buf[28] = 0;
	return fmtstrcpy(fmt, buf);
}

/*
 * Coalesce messages about unreadable sectors into larger ranges.
 * bad(0, 0) flushes the buffer.
 */
static void
bad(char *msg, vlong o, int len)
{
	static vlong lb0, lb1;
	static char *lmsg;

	if(msg == nil)
		msg = lmsg;
	if(o == -1){
		lmsg = nil;
		lb0 = 0;
		lb1 = 0;
		return;
	}
	if(lb1 != o || (msg && lmsg && strcmp(msg, lmsg) != 0)){
		if(lb0 != lb1)
			print("%s %#llux+%#llux (%,lld+%,lld)\n",
				lmsg, lb0, lb1-lb0, lb0, lb1-lb0);
		lb0 = o;
	}
	lmsg = msg;
	lb1 = o+len;
}

/*
 * 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, sizeof buf);
		return buf;
	}
	
	if(offset+len > partend){
		memset(buf, 0xFB, sizeof buf);
		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;
}

/*
 * Buffer to support running SHA1 hash of the disk.
 */
typedef struct Shabuf Shabuf;
struct Shabuf
{
	int fd;
	vlong offset;
	DigestState state;
	int rollback;
	vlong r0;
	DigestState *hist;
	int nhist;
};

void
sbdebug(Shabuf *sb, char *file)
{
	int fd;
	
	if(sb->fd > 0){
		close(sb->fd);
		sb->fd = 0;
	}
	if((fd = create(file, OWRITE, 0666)) < 0)
		return;
	if(fd == 0){
		fd = dup(fd, -1);
		close(0);
	}
	sb->fd = fd;
}

void
sbupdate(Shabuf *sb, uchar *p, vlong offset, int len)
{
	int n, x;
	vlong o;

	if(sb->rollback && !sb->hist){
		sb->r0 = offset;
		sb->nhist = 1;
		sb->hist = vtmalloc(sb->nhist*sizeof *sb->hist);
		memset(sb->hist, 0, sizeof sb->hist[0]);
	}
	if(sb->r0 == 0)
		sb->r0 = offset;

	if(sb->offset < offset || sb->offset >= offset+len){
		if(0) print("sbupdate %p %#llux+%d but offset=%#llux\n",
			p, offset, len, sb->offset);
		return;
	}
	x = sb->offset - offset;
	if(0) print("sbupdate %p %#llux+%d skip %d\n",
		sb, offset, len, x);
	if(x){
		p += x;
		offset += x;
		len -= x;
	}
	assert(sb->offset == offset);
	
	if(sb->fd > 0)
		pwrite(sb->fd, p, len, offset - sb->r0);

	if(!sb->rollback){
		sha1(p, len, nil, &sb->state);
		sb->offset += len;
		return;
	}
	
	/* save state every 4M so we can roll back quickly */
	o = offset - sb->r0;
	while(len > 0){
		n = 4*M - o%(4*M);
		if(n > len)
			n = len;
		sha1(p, n, nil, &sb->state);
		sb->offset += n;
		o += n;
		p += n;
		len -= n;
		if(o%(4*M) == 0){
			x = o/(4*M);
			if(x >= sb->nhist){
				if(x != sb->nhist)
					print("oops! x=%d nhist=%d\n", x, sb->nhist);
				sb->nhist += 32;
				sb->hist = vtrealloc(sb->hist, sb->nhist*sizeof *sb->hist);
			}
			sb->hist[x] = sb->state;
		}
	}		
}

void
sbdiskhash(Shabuf *sb, vlong eoffset)
{
	static uchar dbuf[4*M];
	int n;
	
	while(sb->offset < eoffset){
		n = sizeof dbuf;
		if(sb->offset+n > eoffset)
			n = eoffset - sb->offset;
		readdisk(dbuf, sb->offset, n);
		sbupdate(sb, dbuf, sb->offset, n);
	}
}

void
sbrollback(Shabuf *sb, vlong offset)
{
	int x;
	vlong o;
	Dir d;
	
	if(!sb->rollback || !sb->r0){
		print("cannot rollback sha\n");
		return;
	}
	if(offset >= sb->offset)
		return;
	o = offset - sb->r0;
	x = o/(4*M);
	if(x >= sb->nhist){
		print("cannot rollback sha\n");
		return;
	}
	sb->state = sb->hist[x];
	sb->offset = sb->r0 + x*4*M;
	assert(sb->offset <= offset);
	
	if(sb->fd > 0){
		nulldir(&d);
		d.length = sb->offset - sb->r0;
		dirfwstat(sb->fd, &d);
	}
}

void
sbscore(Shabuf *sb, uchar *score)
{
	if(sb->hist){
		free(sb->hist);
		sb->hist = nil;
	}
	sha1(nil, 0, score, &sb->state);
}

/*
 * If we're fixing arenas, then editing this memory edits the disk!
 * It will be written back out as new data is paged in. 
 */
uchar buf[4*M];
uchar sbuf[4*M];
vlong bufoffset;
int buflen;

static void pageout(void);
static uchar*
pagein(vlong offset, int len)
{
	pageout();
	if(offset >= partend){
		memset(buf, 0xFB, sizeof buf);
		return buf;
	}
	
	if(offset+len > partend){
		memset(buf, 0xFB, sizeof buf);
		len = partend - offset;
	}
	bufoffset = offset;
	buflen = len;
	readdisk(buf, offset, len);
	memmove(sbuf, buf, len);
	return buf;
}

static void
pageout(void)
{
	if(buflen==0 || !fix || memcmp(buf, sbuf, buflen) == 0){
		buflen = 0;
		return;
	}
	if(writepart(part, bufoffset, buf, buflen) < 0)
		print("disk write failed at %#llux+%#ux (%,lld+%,d)\n",
			bufoffset, buflen, bufoffset, buflen);
	buflen = 0;
}

static void
zerorange(vlong offset, int len)
{
	int i;
	vlong ooff;
	int olen;
	enum { MinBlock = 4*K, MaxBlock = 8*K };
	
	if(0)
	if(bufoffset <= offset && offset+len <= bufoffset+buflen){
		memset(buf+(offset-bufoffset), 0, len);
		return;
	}
	
	ooff = bufoffset;
	olen = buflen;
	
	i = offset%MinBlock;
	if(i+len < MaxBlock){
		pagein(offset-i, (len+MinBlock-1)&~(MinBlock-1));
		memset(buf+i, 0, len);
	}else{
		pagein(offset-i, MaxBlock);
		memset(buf+i, 0, MaxBlock-i);
		offset += MaxBlock-i;
		len -= MaxBlock-i;
		while(len >= MaxBlock){
			pagein(offset, MaxBlock);
			memset(buf, 0, MaxBlock);
			offset += MaxBlock;
			len -= MaxBlock;
		}
		pagein(offset, (len+MinBlock-1)&~(MinBlock-1));
		memset(buf, 0, len);
	}
	pagein(ooff, olen);
}

/*
 * read/write integers
 *
static void
p16(uchar *p, u16int u)
{
	p[0] = (u>>8) & 0xFF;
	p[1] = u & 0xFF;
}
*/

static u16int
u16(uchar *p)
{
	return (p[0]<<8)|p[1];
}

static void
p32(uchar *p, u32int u)
{
	p[0] = (u>>24) & 0xFF;
	p[1] = (u>>16) & 0xFF;
	p[2] = (u>>8) & 0xFF;
	p[3] = u & 0xFF;
}

static u32int
u32(uchar *p)
{
	return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
}

/*
static void
p64(uchar *p, u64int u)
{
	p32(p, u>>32);
	p32(p, u);
}
*/

static u64int
u64(uchar *p)
{
	return ((u64int)u32(p)<<32) | u32(p+4);
}

static int
vlongcmp(const void *va, const void *vb)
{
	vlong a, b;
	
	a = *(vlong*)va;
	b = *(vlong*)vb;
	if(a < b)
		return -1;
	if(b > a)
		return 1;
	return 0;
}

/* D and S are in draw.h */
#define D VD
#define S VS

enum
{
	D = 0x10000,
	Z = 0x20000,
	S = 0x30000,
	T = 0x40000,
	N = 0xFFFF
};
typedef struct Info Info;
struct Info
{
	int len;
	char *name;
};

Info partinfo[] = {
	4,	"magic",
	D|4,	"version",
	Z|4,	"blocksize",
	4,	"arenabase",
	0
};

Info headinfo4[] = {
	4,	"magic",
	D|4,	"version",
	S|ANameSize,	"name",
	Z|4,	"blocksize",
	Z|8,	"size",
	0
};

Info headinfo5[] = {
	4,	"magic",
	D|4,	"version",
	S|ANameSize,	"name",
	Z|4,	"blocksize",
	Z|8,	"size",
	4,	"clumpmagic",
	0
};

Info tailinfo4[] = {
	4,	"magic",
	D|4,	"version",
	S|ANameSize,	"name",
	D|4,	"clumps",
	D|4,	"cclumps",
	T|4,	"ctime",
	T|4,	"wtime",
	D|8,	"used",
	D|8,	"uncsize",
	1,	"sealed",
	0
};
	
Info tailinfo4a[] = {
	/* tailinfo 4 */
	4,	"magic",
	D|4,	"version",
	S|ANameSize,	"name",
	D|4,	"clumps",
	D|4,	"cclumps",
	T|4,	"ctime",
	T|4,	"wtime",
	D|8,	"used",
	D|8,	"uncsize",
	1,	"sealed",

	/* mem stats */
	1,	"extension",
	D|4,	"mem.clumps",
	D|4,	"mem.cclumps",
	D|8,	"mem.used",
	D|8,	"mem.uncsize",
	1,	"mem.sealed",
	0
};
	
Info tailinfo5[] = {
	4,	"magic",
	D|4,	"version",
	S|ANameSize,	"name",
	D|4,	"clumps",
	D|4,	"cclumps",
	T|4,	"ctime",
	T|4,	"wtime",
	4,	"clumpmagic",
	D|8,	"used",
	D|8,	"uncsize",
	1,	"sealed",
	0
};

Info tailinfo5a[] = {
	/* tailinfo 5 */
	4,	"magic",
	D|4,	"version",
	S|ANameSize,	"name",
	D|4,	"clumps",
	D|4,	"cclumps",
	T|4,	"ctime",
	T|4,	"wtime",
	4,	"clumpmagic",
	D|8,	"used",
	D|8,	"uncsize",
	1,	"sealed",

	/* mem stats */
	1,	"extension",
	D|4,	"mem.clumps",
	D|4,	"mem.cclumps",
	D|8,	"mem.used",
	D|8,	"mem.uncsize",
	1,	"mem.sealed",
	0
};
	
void
showdiffs(uchar *want, uchar *have, int len, Info *info)
{
	int n;
	
	while(len > 0 && (n=info->len&N) > 0){
		if(memcmp(have, want, n) != 0){
			switch(info->len){
			case 1:
				print("\t%s: correct=%d disk=%d\n",
					info->name, *want, *have);
				break;
			case 4:
				print("\t%s: correct=%#ux disk=%#ux\n",
					info->name, u32(want), u32(have));
				break;
			case D|4:
				print("\t%s: correct=%,ud disk=%,ud\n",
					info->name, u32(want), u32(have));
				break;
			case T|4:
				print("\t%s: correct=%t\n\t\tdisk=%t\n",
					info->name, u32(want), u32(have));
				break;
			case Z|4:
				print("\t%s: correct=%z disk=%z\n",
					info->name, (uvlong)u32(want), (uvlong)u32(have));
				break;
			case D|8:
				print("\t%s: correct=%,lld disk=%,lld\n",
					info->name, u64(want), u64(have));
				break;
			case Z|8:
				print("\t%s: correct=%z disk=%z\n",
					info->name, u64(want), u64(have));
				break;
			case S|ANameSize:
				print("\t%s: correct=%s disk=%.*s\n",
					info->name, (char*)want, 
					utfnlen((char*)have, ANameSize-1),
					(char*)have);
				break;
			default:
				print("\t%s: correct=%.*H disk=%.*H\n",
					info->name, n, want, n, have);
				break;
			}
		}
		have += n;
		want += n;
		len -= n;
		info++;
	}
	if(len > 0 && memcmp(have, want, len) != 0){
		if(memcmp(want, zero, len) != 0)
			print("!!\textra want data in showdiffs (bug in fixarenas)\n");
		else
			print("\tnon-zero data on disk after structure\n");
		if(verbose > 1){
			print("want: %.*H\n", len, want);
			print("have: %.*H\n", len, have);
		}
	}
}

static int tabsizes[] = { 64*1024, 512*1024, };
/*
 * Poke around on the disk to guess what the ArenaPart numbers are.
 */
void
guessgeometry(void)
{
	int i, j, n, bestn, ndiff, nhead, ntail;
	uchar *p, *ep, *sp;
	u64int diff[100], head[20], tail[20];
	u64int offset, bestdiff;
	
	ap.version = ArenaPartVersion;

	if(arenasize == 0 || ap.blocksize == 0){
		/*
		 * The ArenaPart block at offset PartBlank may be corrupt or just wrong.
		 * Instead, look for the individual arena headers and tails, which there
		 * are many of, and once we've seen enough, infer the spacing.
		 *
		 * Of course, nothing in the file format requires that arenas be evenly
		 * spaced, but fmtarenas always does that for us.
		 */
		nhead = 0;
		ntail = 0;
		for(offset=PartBlank; offset<partend; offset+=4*M){
			p = pagein(offset, 4*M);
			for(sp=p, ep=p+4*M; p<ep; p+=K){
				if(u32(p) == ArenaHeadMagic && nhead < nelem(head)){
					if(verbose)
						print("arena head at %#llx\n", offset+(p-sp));
					head[nhead++] = offset+(p-sp);
				}
				if(u32(p) == ArenaMagic && ntail < nelem(tail)){
					tail[ntail++] = offset+(p-sp);
					if(verbose)
						print("arena tail at %#llx\n", offset+(p-sp));
				}
			}
			if(nhead == nelem(head) && ntail == nelem(tail))
				break;
		}
		if(nhead < 3 && ntail < 3)
			sysfatal("too few intact arenas: %d heads, %d tails", nhead, ntail);
	
		/* 
		 * Arena size is likely the most common
		 * inter-head or inter-tail spacing.
		 */
		ndiff = 0;
		for(i=1; i<nhead; i++)
			diff[ndiff++] = head[i] - head[i-1];
		for(i=1; i<ntail; i++)
			diff[ndiff++] = tail[i] - tail[i-1];
		qsort(diff, ndiff, sizeof diff[0], vlongcmp);
		bestn = 0;
		bestdiff = 0;
		for(i=1, n=1; i<=ndiff; i++, n++){
			if(i==ndiff || diff[i] != diff[i-1]){
				if(n > bestn){
					bestn = n;
					bestdiff = diff[i-1];
				}
				n = 0;
			}
		}
		print("arena size likely %z (%d of %d)\n", bestdiff, bestn, ndiff);
		if(arenasize != 0 && arenasize != bestdiff)
			print("using user-specified size %z instead\n", arenasize);
		else
			arenasize = bestdiff;

		/*
		 * The arena tail for an arena is arenasize-blocksize from the head.
		 */
		ndiff = 0;
		for(i=j=0; i<nhead && j<ntail; ){
			if(tail[j] < head[i]){
				j++;
				continue;
			}
			if(tail[j] < head[i]+arenasize){
				diff[ndiff++] = head[i]+arenasize - tail[j];
				j++;
				continue;
			}
			i++;
		}
		if(ndiff < 3)
			sysfatal("too few intact arenas: %d head, tail pairs", ndiff);
		qsort(diff, ndiff, sizeof diff[0], vlongcmp);
		bestn = 0;
		bestdiff = 0;
		for(i=1, n=1; i<=ndiff; i++, n++){
			if(i==ndiff || diff[i] != diff[i-1]){
				if(n > bestn){
					bestn = n;
					bestdiff = diff[i-1];
				}
				n = 0;
			}
		}
		print("block size likely %z (%d of %d)\n", bestdiff, bestn, ndiff);
		if(ap.blocksize != 0 && ap.blocksize != bestdiff)
			print("using user-specified size %z instead\n", (vlong)ap.blocksize);
		else
			ap.blocksize = bestdiff;
		if(ap.blocksize == 0 || ap.blocksize&(ap.blocksize-1))
			sysfatal("block size not a power of two");
		if(ap.blocksize > MaxDiskBlock)
			sysfatal("block size too big (max=%d)", MaxDiskBlock);

		/*
		 * Use head/tail information to deduce arena base.
		 */
		ndiff = 0;
		for(i=0; i<nhead; i++)
			diff[ndiff++] = head[i]%arenasize;
		for(i=0; i<ntail; i++)
			diff[ndiff++] = (tail[i]+ap.blocksize)%arenasize;
		qsort(diff, ndiff, sizeof diff[0], vlongcmp);
		bestn = 0;
		bestdiff = 0;
		for(i=1, n=1; i<=ndiff; i++, n++){
			if(i==ndiff || diff[i] != diff[i-1]){
				if(n > bestn){
					bestn = n;
					bestdiff = diff[i-1];
				}
				n = 0;
			}
		}
		ap.arenabase = bestdiff;
	}
	
	ap.tabbase = (PartBlank+HeadSize+ap.blocksize-1)&~(ap.blocksize-1);
	/*
	 * XXX pick up table, check arenabase.
	 * XXX pick up table, record base name.
	 */

	/*
	 * Somewhat standard computation.
	 * Fmtarenas used to use 64k tab, now uses 512k tab.
	 */
	if(ap.arenabase == 0){
		for(i=0; i<nelem(tabsizes); i++){
			ap.arenabase = (PartBlank+HeadSize+tabsizes[i]+ap.blocksize-1)&~(ap.blocksize-1);
			p = pagein(ap.arenabase, Block);
			if(u32(p) == ArenaHeadMagic)
				break;
		}
	}
	p = pagein(ap.arenabase, Block);
	print("arena base likely %z%s\n", (vlong)ap.arenabase, 
		u32(p)!=ArenaHeadMagic ? " (but no arena head there)" : "");

	ap.tabsize = ap.arenabase - ap.tabbase;
	
}

/*
 * Check the arena partition blocks and then the arenas listed in range.
 */
void
checkarenas(char *range)
{
	char *s, *t;
	int i, lo, hi, narena;
	uchar dbuf[HeadSize];
	uchar *p;

	guessgeometry();

	partend -= partend%ap.blocksize;

	memset(dbuf, 0, sizeof dbuf);
	packarenapart(&ap, dbuf);
	p = pagein(PartBlank, Block);
	if(memcmp(p, dbuf, HeadSize) != 0){
		print("on-disk arena part superblock incorrect\n");
		showdiffs(dbuf, p, HeadSize, partinfo);
	}
	memmove(p, dbuf, HeadSize);

	narena = (partend-ap.arenabase + arenasize-1)/arenasize;
	if(range == nil){
		for(i=0; i<narena; i++)
			checkarena(ap.arenabase+(vlong)i*arenasize, i);
	}else if(strcmp(range, "none") == 0){
		/* nothing */
	}else{
		/* parse, e.g., -4,8-9,10- */
		for(s=range; *s; s=t){
			t = strchr(s, ',');
			if(t)
				*t++ = 0;
			else
				t = s+strlen(s);
			if(*s == '-')
				lo = 0;
			else
				lo = strtol(s, &s, 0);
			hi = lo;
			if(*s == '-'){
				s++;
				if(*s == 0)
					hi = narena-1;
				else
					hi = strtol(s, &s, 0);
			}
			if(*s != 0){
				print("bad arena range: %s\n", s);
				continue;
			}
			for(i=lo; i<=hi; i++)
				checkarena(ap.arenabase+(vlong)i*arenasize, i);
		}
	}
}

/*
 * Is there a clump here at p?
 */
static int
isclump(uchar *p, Clump *cl, u32int *pmagic)
{
	int n;
	u32int magic;
	uchar score[VtScoreSize], *bp;
	Unwhack uw;
	uchar ubuf[70*1024];
	
	bp = p;
	magic = u32(p);
	if(magic == 0)
		return 0;
	p += U32Size;

	cl->info.type = vtfromdisktype(*p);
	if(cl->info.type == 0xFF)
		return 0;
	p++;
	cl->info.size = u16(p);
	p += U16Size;
	cl->info.uncsize = u16(p);
	if(cl->info.size > cl->info.uncsize)
		return 0;
	p += U16Size;
	scorecp(cl->info.score, p);
	p += VtScoreSize;
	cl->encoding = *p;
	p++;
	cl->creator = u32(p);
	p += U32Size;
	cl->time = u32(p);
	p += U32Size;

	switch(cl->encoding){
	case ClumpENone:
		if(cl->info.size != cl->info.uncsize)
			return 0;
		scoremem(score, p, cl->info.size);
		if(scorecmp(score, cl->info.score) != 0)
			return 0;
		break;
	case ClumpECompress:
		if(cl->info.size >= cl->info.uncsize)
			return 0;
		unwhackinit(&uw);
		n = unwhack(&uw, ubuf, cl->info.uncsize, p, cl->info.size);
		if(n != cl->info.uncsize)
			return 0;
		scoremem(score, ubuf, cl->info.uncsize);
		if(scorecmp(score, cl->info.score) != 0)
			return 0;
		break;
	default:
		return 0;
	}
	p += cl->info.size;
	
	/* it all worked out in the end */
	*pmagic = magic;
	return p - bp;
}

/*
 * All ClumpInfos seen in this arena.
 * Kept in binary tree so we can look up by score.
 */
typedef struct Cit Cit;
struct Cit
{
	int left;
	int right;
	vlong corrupt;
	ClumpInfo ci;
};
Cit *cibuf;
int ciroot;
int ncibuf, mcibuf;

void
resetcibuf(void)
{
	ncibuf = 0;
	ciroot = -1;
}

int*
ltreewalk(int *p, uchar *score)
{
	int i;
	
	for(;;){
		if(*p == -1)
			return p;
		i = scorecmp(cibuf[*p].ci.score, score);
		if(i == 0)
			return p;
		if(i < 0)
			p = &cibuf[*p].right;
		else
			p = &cibuf[*p].left;
	}
}

void
addcibuf(ClumpInfo *ci, vlong corrupt)
{
	Cit *cit;
	
	if(ncibuf == mcibuf){
		mcibuf += 131072;
		cibuf = vtrealloc(cibuf, mcibuf*sizeof cibuf[0]);
	}
	cit = &cibuf[ncibuf];
	cit->ci = *ci;
	cit->left = -1;
	cit->right = -1;
	cit->corrupt = corrupt;
	if(!corrupt)
		*ltreewalk(&ciroot, ci->score) = ncibuf;
	ncibuf++;
}

void
addcicorrupt(vlong len)
{
	static ClumpInfo zci;
	
	addcibuf(&zci, len);
}

int
haveclump(uchar *score)
{
	int i;
	int p;
	
	p = ciroot;
	for(;;){
		if(p == -1)
			return 0;
		i = scorecmp(cibuf[p].ci.score, score);
		if(i == 0)
			return 1;
		if(i < 0)
			p = cibuf[p].right;
		else
			p = cibuf[p].left;
	}
}

int
matchci(ClumpInfo *ci, uchar *p)
{
	if(ci->type != vtfromdisktype(p[0]))
		return 0;
	if(ci->size != u16(p+1))
		return 0;
	if(ci->uncsize != u16(p+3))
		return 0;
	if(scorecmp(ci->score, p+5) != 0)
		return 0;
	return 1;
}

int
sealedarena(uchar *p, int blocksize)
{
	int v, n;
	
	v = u32(p+4);
	switch(v){
	default:
		return 0;
	case ArenaVersion4:
		n = ArenaSize4;
		break;
	case ArenaVersion5:
		n = ArenaSize5;
		break;
	}
	if(p[n-1] != 1){
		print("arena tail says not sealed\n");
		return 0;
	}
	if(memcmp(p+n, zero, blocksize-VtScoreSize-n) != 0){
		print("arena tail followed by non-zero data\n");
		return 0;
	}
	if(memcmp(p+blocksize-VtScoreSize, zero, VtScoreSize) == 0){
		print("arena score zero\n");
		return 0;
	}
	return 1;
}

int
okayname(char *name, int n)
{
	char buf[20];
	
	if(nameok(name) < 0)
		return 0;
	sprint(buf, "%d", n);
	if(strlen(name) < strlen(buf) 
	|| strcmp(name+strlen(name)-strlen(buf), buf) != 0)
		return 0;
	return 1;
}

int
clumpinfocmp(ClumpInfo *a, ClumpInfo *b)
{
	if(a->type != b->type)
		return a->type - b->type;
	if(a->size != b->size)
		return a->size - b->size;
	if(a->uncsize != b->uncsize)
		return a->uncsize - b->uncsize;
	return scorecmp(a->score, b->score);
}

ClumpInfo*
loadci(vlong offset, Arena *arena, int nci)
{
	int i, j, per;
	uchar *p, *sp;
	ClumpInfo *bci, *ci;
	
	per = arena->blocksize/ClumpInfoSize;
	bci = vtmalloc(nci*sizeof bci[0]);
	ci = bci;
	offset += arena->size - arena->blocksize;
	p = sp = nil;
	for(i=0; i<nci; i+=per){
		if(p == sp){
			sp = pagein(offset-4*M, 4*M);
			p = sp+4*M;
		}
		p -= arena->blocksize;
		offset -= arena->blocksize;
		for(j=0; j<per && i+j<nci; j++)
			unpackclumpinfo(ci++, p+j*ClumpInfoSize);
	}
	return bci;
}

vlong
writeci(vlong offset, Arena *arena, ClumpInfo *ci, int nci)
{
	int i, j, per;
	uchar *p, *sp;
	
	per = arena->blocksize/ClumpInfoSize;
	offset += arena->size - arena->blocksize;
	p = sp = nil;
	for(i=0; i<nci; i+=per){
		if(p == sp){
			sp = pagein(offset-4*M, 4*M);
			p = sp+4*M;
		}
		p -= arena->blocksize;
		offset -= arena->blocksize;
		memset(p, 0, arena->blocksize);
		for(j=0; j<per && i+j<nci; j++)
			packclumpinfo(ci++, p+j*ClumpInfoSize);
	}
	pageout();
	return offset;
}

void
loadarenabasics(vlong offset0, int anum, ArenaHead *head, Arena *arena)
{
	char dname[ANameSize];
	static char lastbase[ANameSize];
	uchar *p;
	Arena oarena;
	ArenaHead ohead;

	/*
	 * Fmtarenas makes all arenas the same size
	 * except the last, which may be smaller.
	 * It uses the same block size for arenas as for
	 * the arena partition blocks.
	 */
	arena->size = arenasize;
	if(offset0+arena->size > partend)
		arena->size = partend - offset0;
	head->size = arena->size;
	
	arena->blocksize = ap.blocksize;
	head->blocksize = arena->blocksize;
	
	/* 
	 * Look for clump magic and name in head/tail blocks.
	 * All the other info we will reconstruct just in case.
	 */
	p = pagein(offset0, arena->blocksize);
	memset(&ohead, 0, sizeof ohead);
	if(unpackarenahead(&ohead, p) >= 0){
		head->version = ohead.version;
		head->clumpmagic = ohead.clumpmagic;
		if(okayname(ohead.name, anum))
			strcpy(head->name, ohead.name);
	}

	p = pagein(offset0+arena->size-arena->blocksize, 
		arena->blocksize);
	memset(&oarena, 0, sizeof oarena);
	if(unpackarena(&oarena, p) >= 0){
		arena->version = oarena.version;
		arena->clumpmagic = oarena.clumpmagic;
		if(okayname(oarena.name, anum))
			strcpy(arena->name, oarena.name);
		arena->diskstats.clumps = oarena.diskstats.clumps;
print("old arena: sealed=%d\n", oarena.diskstats.sealed);
		arena->diskstats.sealed = oarena.diskstats.sealed;
	}

	/* Head trumps arena. */
	if(head->version){
		arena->version = head->version;
		arena->clumpmagic = head->clumpmagic;
	}
	if(arena->version == 0)
		arena->version = ArenaVersion5;
	if(basename)
		snprint(arena->name, ANameSize, "%s%d", basename, anum);
	else if(lastbase[0])
		snprint(arena->name, ANameSize, "%s%d", lastbase, anum);
	else if(head->name[0])
		strcpy(arena->name, head->name);
	else if(arena->name[0] == 0)
		sysfatal("cannot determine base name for arena; use -n");
	strcpy(lastbase, arena->name);
	sprint(dname, "%d", anum);
	lastbase[strlen(lastbase)-strlen(dname)] = 0;
	
	/* Was working in arena, now copy to head. */
	head->version = arena->version;
	memmove(head->name, arena->name, sizeof head->name);
	head->blocksize = arena->blocksize;
	head->size = arena->size;
}

void
shahead(Shabuf *sb, vlong offset0, ArenaHead *head)
{
	uchar headbuf[MaxDiskBlock];
	
	sb->offset = offset0;
	memset(headbuf, 0, sizeof headbuf);
	packarenahead(head, headbuf);
	sbupdate(sb, headbuf, offset0, head->blocksize);
}

u32int
newclumpmagic(int version)
{
	u32int m;
	
	if(version == ArenaVersion4)
		return _ClumpMagic;
	do{
		m = fastrand();
	}while(m==0 || m == _ClumpMagic);
	return m;
}

/*
 * Poke around in the arena to find the clump data
 * and compute the relevant statistics.
 */
void
guessarena(vlong offset0, int anum, ArenaHead *head, Arena *arena,
	uchar *oldscore, uchar *score)
{
	uchar dbuf[MaxDiskBlock];
	int needtozero, clumps, nb1, nb2, minclumps;
	int inbad, n, ncib, printed, sealing, smart;
	u32int magic;
	uchar *sp, *ep, *p;
	vlong boffset, eoffset, lastclumpend, leaked;
	vlong offset, toffset, totalcorrupt, v;
	Clump cl;
	ClumpInfo *bci, *ci, *eci, *xci;
	Cit *bcit, *cit, *ecit;
	Shabuf oldsha, newsha;
	
	/*
	 * We expect to find an arena, with data, between offset
	 * and offset+arenasize.  With any luck, the data starts at
	 * offset+ap.blocksize.  The blocks have variable size and
	 * aren't padded at all, which doesn't give us any alignment
	 * constraints.  The blocks are compressed or high entropy,
	 * but the headers are pretty low entropy (except the score):
	 *
	 *	type[1] (range 0 thru 9, 13)
	 *	size[2]
	 *	uncsize[2] (<= size)
	 *
	 * so we can look for these.  We check the scores as we go,
	 * so we can't make any wrong turns.  If we find ourselves
	 * in a dead end, scan forward looking for a new start.
	 */

	resetcibuf();
	memset(head, 0, sizeof *head);
	memset(arena, 0, sizeof *arena);
	memset(oldscore, 0, VtScoreSize);
	memset(score, 0, VtScoreSize);
	memset(&oldsha, 0, sizeof oldsha);
	memset(&newsha, 0, sizeof newsha);
	newsha.rollback = 1;

	if(0){
		sbdebug(&oldsha, "old.sha");
		sbdebug(&newsha, "new.sha");
	}

	loadarenabasics(offset0, anum, head, arena);

	/* start the clump hunt */
	
	clumps = 0;
	totalcorrupt = 0;
	sealing = 1;
	boffset = offset0 + arena->blocksize;
	offset = boffset;
	eoffset = offset0+arena->size - arena->blocksize;
	toffset = eoffset;
	sp = pagein(offset0, 4*M);

	if(arena->diskstats.sealed){
		oldsha.offset = offset0;
		sbupdate(&oldsha, sp, offset0, 4*M);
	}
	ep = sp+4*M;
	p = sp + (boffset - offset0);
	ncib = arena->blocksize / ClumpInfoSize;	/* ci per block in index */
	lastclumpend = offset;
	nbad = 0;
	inbad = 0;
	needtozero = 0;
	minclumps = 0;
	while(offset < eoffset){
		/*
		 * Shift buffer if we're running out of room.
		 */
		if(p+70*K >= ep){
			/*
			 * Start the post SHA1 buffer.   By now we should know the
			 * clumpmagic and arena version, so we can create a
			 * correct head block to get things going.
			 */
			if(sealing && fix && newsha.offset == 0){
				newsha.offset = offset0;
				if(arena->clumpmagic == 0){
					if(arena->version == 0)
						arena->version = ArenaVersion5;
					arena->clumpmagic = newclumpmagic(arena->version);
				}
				head->clumpmagic = arena->clumpmagic;
				shahead(&newsha, offset0, head);
			}
			n = 4*M-256*K;
			if(sealing && fix){
				sbdiskhash(&newsha, bufoffset);
				sbupdate(&newsha, buf, bufoffset, 4*M-256*K);
			}
			pagein(bufoffset+n, 4*M);
			p -= n;
			if(arena->diskstats.sealed)
				sbupdate(&oldsha, buf, bufoffset, 4*M);
		}

		/*
		 * Check for a clump at p, which is at offset in the disk.
		 * Duplicate clumps happen in corrupted disks
		 * (the same pattern gets written many times in a row)
		 * and should never happen during regular use.
		 */
		if((n = isclump(p, &cl, &magic)) > 0){
			/*
			 * If we were in the middle of some corrupted data,
			 * flush a warning about it and then add any clump
			 * info blocks as necessary.
			 */
			if(inbad){
				inbad = 0;
				v = offset-lastclumpend;
				if(needtozero){
					zerorange(lastclumpend, v);
					sbrollback(&newsha, lastclumpend);
					print("corrupt clump data - %#llux+%#llux (%,llud bytes)\n",
						lastclumpend, v, v);
				}
				addcicorrupt(v);
				totalcorrupt += v;
				nb1 = (minclumps+ncib-1)/ncib;
				minclumps += (v+ClumpSize+VtMaxLumpSize-1)/(ClumpSize+VtMaxLumpSize);
				nb2 = (minclumps+ncib-1)/ncib;
				eoffset -= (nb2-nb1)*arena->blocksize;
			}

			if(haveclump(cl.info.score))
				print("warning: duplicate clump %d %V\n", cl.info.type, cl.info.score);

			/*
			 * If clumps use different magic numbers, we don't care.
			 * We'll just use the first one we find and make the others
			 * follow suit.
			 */
			if(arena->clumpmagic == 0){
				print("clump type %d size %d score %V magic %x\n",
					cl.info.type, cl.info.size, cl.info.score, magic);
				arena->clumpmagic = magic;
				if(magic == _ClumpMagic)
					arena->version = ArenaVersion4;
				else
					arena->version = ArenaVersion5;
			}
			if(magic != arena->clumpmagic)
				p32(p, arena->clumpmagic);
			if(clumps == 0)
				arena->ctime = cl.time;

			/*
			 * Record the clump, update arena stats,
			 * grow clump info blocks if needed.
			 */
			if(verbose > 1)
				print("\tclump %d: %d %V at %#llux+%#ux (%d)\n", 
					clumps, cl.info.type, cl.info.score, offset, n, n);
			addcibuf(&cl.info, 0);
			if(minclumps%ncib == 0)
				eoffset -= arena->blocksize;
			minclumps++;
			clumps++;
			if(cl.encoding != ClumpENone)
				arena->diskstats.cclumps++;
			arena->diskstats.uncsize += cl.info.uncsize;
			arena->wtime = cl.time;
			
			/*
			 * Move to next clump.
			 */
			offset += n;
			p += n;
			lastclumpend = offset;
		}else{
			/*
			 * Overwrite malformed clump data with zeros later.
			 * For now, just record whether it needs to be overwritten.
			 * Bad regions must be of size at least ClumpSize.
			 * Postponing the overwriting keeps us from writing past
			 * the end of the arena data (which might be directory data)
			 * with zeros.
			 */
			if(!inbad){
				inbad = 1;
				needtozero = 0;
				if(memcmp(p, zero, ClumpSize) != 0)
					needtozero = 1;
				p += ClumpSize;
				offset += ClumpSize;
				nbad++;
			}else{
				if(*p != 0)
					needtozero = 1;
				p++;
				offset++;
			}
		}
	}
	pageout();

	if(verbose)
		print("readable clumps: %d; min. directory entries: %d\n", 
			clumps, minclumps);
	arena->diskstats.used = lastclumpend - boffset;
	leaked = eoffset - lastclumpend;
	if(verbose)
		print("used from %#llux to %#llux = %,lld (%,lld unused)\n",
			boffset, lastclumpend, arena->diskstats.used, leaked);

	/*
	 * Finish the SHA1 of the old data.
	 */
	if(arena->diskstats.sealed){
		sbdiskhash(&oldsha, toffset);
		readdisk(dbuf, toffset, arena->blocksize);
		scorecp(dbuf+arena->blocksize-VtScoreSize, zero);
		sbupdate(&oldsha, dbuf, toffset, arena->blocksize);
		sbscore(&oldsha, oldscore);
	}
	
	/*
	 * If we still don't know the clump magic, the arena
	 * must be empty.  It still needs a value, so make 
	 * something up.
	 */
	if(arena->version == 0)
		arena->version = ArenaVersion5;
	if(arena->clumpmagic == 0){
		if(arena->version == ArenaVersion4)
			arena->clumpmagic = _ClumpMagic;
		else{
			do
				arena->clumpmagic = fastrand();
			while(arena->clumpmagic==_ClumpMagic
				||arena->clumpmagic==0);
		}
		head->clumpmagic = arena->clumpmagic;
	}

	/*
	 * Guess at number of clumpinfo blocks to load.
	 * If we guess high, it's no big deal.  If we guess low,
	 * we'll be forced into rewriting the whole directory.
	 * Still not such a big deal.
	 */
	if(clumps == 0 || arena->diskstats.used == totalcorrupt)
		goto Nocib;
	if(clumps < arena->diskstats.clumps)
		clumps = arena->diskstats.clumps;
	if(clumps < ncibuf)
		clumps = ncibuf;
	clumps += totalcorrupt/
		((arena->diskstats.used - totalcorrupt)/clumps);
	clumps += totalcorrupt/2000;
	if(clumps < minclumps)
		clumps = minclumps;
	clumps += ncib-1;
	clumps -= clumps%ncib;

	/*
	 * Can't write into the actual data.
	 */
	v = offset0 + arena->size - arena->blocksize;
	v -= (clumps+ncib-1)/ncib * arena->blocksize;
	if(v < lastclumpend){
		v = offset0 + arena->size - arena->blocksize;
		clumps = (v-lastclumpend)/arena->blocksize * ncib;
	}
	
	if(clumps < minclumps)
		print("cannot happen?\n");

	/*
	 * Check clumpinfo blocks against directory we created.
	 * The tricky part is handling the corrupt sections of arena.
	 * If possible, we remark just the affected directory entries
	 * rather than slide everything down.
	 * 
	 * Allocate clumps+1 blocks and check that we don't need
	 * the last one at the end.
	 */
	bci = loadci(offset0, arena, clumps+1);
	eci = bci+clumps+1;
	bcit = cibuf;
	ecit = cibuf+ncibuf;
	smart = 1;
Again:
	nbad = 0;
	ci = bci;
	for(cit=bcit; cit<ecit && ci<eci; cit++){
		if(cit->corrupt){
			vlong n, m;
			if(smart){
				/*
				 * If we can, just mark existing entries as corrupt.
				 */
				n = cit->corrupt;
				for(xci=ci; n>0 && xci<eci; xci++)
					n -= ClumpSize+xci->size;
				if(n > 0 || xci >= eci)
					goto Dumb;
				printed = 0;
				for(; ci<xci; ci++){
					if(verbose && ci->type != VtCorruptType){
						if(!printed){
							print("marking directory %d-%d as corrupt\n",
								(int)(ci-bci), (int)(xci-bci));
							printed = 1;
						}
						print("\ttype=%d size=%d uncsize=%d score=%V\n",
							ci->type, ci->size, ci->uncsize, ci->score);
					}
					ci->type = VtCorruptType;
				}
			}else{
			Dumb:
				print("\trewriting clump directory\n");
				/*
				 * Otherwise, blaze a new trail.
				 */
				n = cit->corrupt;
				while(n > 0 && ci < eci){
					if(n < ClumpSize)
						sysfatal("bad math in clump corrupt");
					if(n <= VtMaxLumpSize+ClumpSize)
						m = n;
					else{
						m = VtMaxLumpSize+ClumpSize;
						if(n-m < ClumpSize)
							m -= ClumpSize;
					}
					ci->type = VtCorruptType;
					ci->size = m-ClumpSize;
					ci->uncsize = m-ClumpSize;
					memset(ci->score, 0, VtScoreSize);
					ci++;
					n -= m;
				}
			}
			continue;
		}
		if(clumpinfocmp(&cit->ci, ci) != 0){
			if(verbose && (smart || verbose>1)){
				print("clumpinfo %d\n", (int)(ci-bci));
				print("\twant: %d %d %d %V\n", 
					cit->ci.type, cit->ci.size,
					cit->ci.uncsize, cit->ci.score);
				print("\thave: %d %d %d %V\n", 
					ci->type, ci->size, 
					ci->uncsize, ci->score);
			}
			*ci = cit->ci;
			nbad++;
		}
		ci++;
	}
	if(ci >= eci || cit < ecit){
		print("ran out of space editing existing directory; rewriting\n");
		print("# eci %ld ci %ld ecit %ld cit %ld\n", eci-bci, ci-bci, ecit-bcit, cit-bcit);
		assert(smart);	/* can't happen second time thru */
		smart = 0;
		goto Again;
	}
	
	assert(ci <= eci);
	arena->diskstats.clumps = ci-bci;
	eoffset = writeci(offset0, arena, bci, ci-bci);
	if(sealing && fix)
		sbrollback(&newsha, v);
print("eoffset=%lld lastclumpend=%lld diff=%lld unseal=%d\n", eoffset, lastclumpend, eoffset-lastclumpend, unseal);
	if(lastclumpend > eoffset)
		print("arena directory overwrote blocks!  cannot happen!\n");
	free(bci);
	if(smart && nbad)
		print("arena directory has %d bad or missing entries\n", nbad);
Nocib:
	if(eoffset - lastclumpend > 64*1024 && (!arena->diskstats.sealed || unseal)){
		if(arena->diskstats.sealed)
			print("unsealing arena\n");
		sealing = 0;
		memset(oldscore, 0, VtScoreSize);
	}

	/*
	 * Finish the SHA1 of the new data - only meaningful
	 * if we've been writing to disk (`fix').
	 */
	arena->diskstats.sealed = sealing;
	arena->memstats = arena->diskstats;
	if(sealing && fix){
		uchar tbuf[MaxDiskBlock];
		
		sbdiskhash(&newsha, toffset);
		memset(tbuf, 0, sizeof tbuf);
		packarena(arena, tbuf);
		sbupdate(&newsha, tbuf, toffset, arena->blocksize);
		sbscore(&newsha, score);
	}
}

void
dumparena(vlong offset, int anum, Arena *arena)
{
	char buf[1000];
	vlong o, e;
	int fd, n;
	
	snprint(buf, sizeof buf, "%s.%d", dumpbase, anum);
	if((fd = create(buf, OWRITE, 0666)) < 0){
		fprint(2, "create %s: %r\n", buf);
		return;
	}
	e = offset+arena->size;
	for(o=offset; o<e; o+=n){
		n = 4*M;
		if(o+n > e)
			n = e-o;
		if(pwrite(fd, pagein(o, n), n, o-offset) != n){
			fprint(2, "write %s at %#llux: %r\n", buf, o-offset);
			return;
		}
	}
}

void
checkarena(vlong offset, int anum)
{
	uchar dbuf[MaxDiskBlock];
	uchar *p, oldscore[VtScoreSize], score[VtScoreSize];
	Arena arena, oarena;
	ArenaHead head;
	Info *fmt, *fmta;
	int sz;
	
	print("# arena %d: offset %#llux\n", anum, offset);

	if(offset >= partend){
		print("arena offset out of bounds\n");
		return;
	}

	guessarena(offset, anum, &head, &arena, oldscore, score);

	if(verbose){
		print("#\tversion=%d name=%s blocksize=%d size=%z",
			head.version, head.name, head.blocksize, head.size);
		if(head.clumpmagic)
			print(" clumpmagic=%#.8ux", head.clumpmagic);
		print("\n#\tclumps=%d cclumps=%d used=%,lld uncsize=%,lld\n",
			arena.diskstats.clumps, arena.diskstats.cclumps,
			arena.diskstats.used, arena.diskstats.uncsize);
		print("#\tctime=%t\n", arena.ctime);
		print("#\twtime=%t\n", arena.wtime);
		if(arena.diskstats.sealed)
			print("#\tsealed score=%V\n", score);
	}

	if(dumpbase){
		dumparena(offset, anum, &arena);
		return;
	}

	memset(dbuf, 0, sizeof dbuf);
	packarenahead(&head, dbuf);
	p = pagein(offset, arena.blocksize);
	if(memcmp(dbuf, p, arena.blocksize) != 0){
		print("on-disk arena header incorrect\n");
		showdiffs(dbuf, p, arena.blocksize, 
			arena.version==ArenaVersion4 ? headinfo4 : headinfo5);
	}
	memmove(p, dbuf, arena.blocksize);
	
	memset(dbuf, 0, sizeof dbuf);
	packarena(&arena, dbuf);
	if(arena.diskstats.sealed)
		scorecp(dbuf+arena.blocksize-VtScoreSize, score);
	p = pagein(offset+arena.size-arena.blocksize, arena.blocksize);
	memset(&oarena, 0, sizeof oarena);
	unpackarena(&oarena, p);
	if(arena.version == ArenaVersion4){
		sz = ArenaSize4;
		fmt = tailinfo4;
		fmta = tailinfo4a;
	}else{
		sz = ArenaSize5;
		fmt = tailinfo5;
		fmta = tailinfo5a;
	}
	if(p[sz] == 1){
		fmt = fmta;
		if(oarena.diskstats.sealed){
			/*
			 * some arenas were sealed with the extension
			 * before we adopted the convention that if it didn't
			 * add new information it gets dropped.
			 */
			_packarena(&arena, dbuf, 1);
		}
	}
	if(memcmp(dbuf, p, arena.blocksize-VtScoreSize) != 0){
		print("on-disk arena tail incorrect\n");
		showdiffs(dbuf, p, arena.blocksize-VtScoreSize, fmt);
	}
	if(arena.diskstats.sealed){
		if(oarena.diskstats.sealed)
		if(scorecmp(p+arena.blocksize-VtScoreSize, oldscore) != 0){
			print("on-disk arena seal score incorrect\n");
			print("\tcorrect=%V\n", oldscore);
			print("\t   disk=%V\n", p+arena.blocksize-VtScoreSize);
		}
		if(fix && scorecmp(p+arena.blocksize-VtScoreSize, score) != 0){
			print("%ssealing arena%s: %V\n", 
				oarena.diskstats.sealed ? "re" : "",
				scorecmp(oldscore, score) == 0 ? 
					"" : " after changes", score);
		}
	}
	memmove(p, dbuf, arena.blocksize);
	
	pageout();
}

AMapN*
buildamap(void)
{
	uchar *p;
	vlong o;
	ArenaHead h;
	AMapN *an;
	AMap *m;
	
	an = vtmallocz(sizeof *an);
	for(o=ap.arenabase; o<partend; o+=arenasize){
		p = pagein(o, Block);
		if(unpackarenahead(&h, p) >= 0){
			an->map = vtrealloc(an->map, (an->n+1)*sizeof an->map[0]);
			m = &an->map[an->n++];
			m->start = o;
			m->stop = o+h.size;
			strcpy(m->name, h.name);
		}
	}
	return an;	
}

void
checkmap(void)
{
	char *s;
	uchar *p;
	int i, len;
	AMapN *an;
	Fmt fmt;
	
	an = buildamap();
	fmtstrinit(&fmt);
	fmtprint(&fmt, "%ud\n", an->n);
	for(i=0; i<an->n; i++)
		fmtprint(&fmt, "%s\t%lld\t%lld\n",
			an->map[i].name, an->map[i].start, an->map[i].stop);
	s = fmtstrflush(&fmt);
	len = strlen(s);
	if(len > ap.tabsize){
		print("arena partition map too long: need %z bytes have %z\n",
			(vlong)len, (vlong)ap.tabsize);
		len = ap.tabsize;
	}
	
	if(ap.tabsize >= 4*M){	/* can't happen - max arenas is 2000 */
		print("arena partition map *way* too long\n");
		return;
	}

	p = pagein(ap.tabbase, ap.tabsize);
	if(memcmp(p, s, len) != 0){
		print("arena partition map incorrect; rewriting.\n");
		memmove(p, s, len);
	}
	pageout();
}

int mainstacksize = 512*1024;

void
threadmain(int argc, char **argv)
{
	int mode;
	
	mode = OREAD;
	readonly = 1;	
	ARGBEGIN{
	case 'U':
		unseal = 1;
		break;
	case 'a':
		arenasize = unittoull(EARGF(usage()));
		break;
	case 'b':
		ap.blocksize = unittoull(EARGF(usage()));
		break;
	case 'f':
		fix = 1;
		mode = ORDWR;
		readonly = 0;
		break;
	case 'n':
		basename = EARGF(usage());
		break;
	case 'v':
		verbose++;
		break;
	case 'x':
		dumpbase = EARGF(usage());
		break;
	default:
		usage();
	}ARGEND
	
	if(argc != 1 && argc != 2)
		usage();

	file = argv[0];
	
	ventifmtinstall();
	fmtinstall('z', zfmt);
	fmtinstall('t', tfmt);
	quotefmtinstall();
	
	part = initpart(file, mode|ODIRECT);
	if(part == nil)
		sysfatal("can't open %s: %r", file);
	partend = part->size;
	
	checkarenas(argc > 1 ? argv[1] : nil);
	checkmap();
	threadexitsall(nil);
}

