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); }
static int printheader(char *name, ArenaHead *head, int fd) { Arena arena; vlong baseoff, lo, hi, off; int clumpmax; off = seek(fd, 0, 1); seek(fd, off + head->size - head->blocksize, 0); if(readblock(fd, data, head->blocksize) < 0){ fprint(2, "%s: reading arena tail: %r\n", name); return -1; } seek(fd, off, 0); memset(&arena, 0, sizeof arena); if(unpackarena(&arena, data) < 0){ fprint(2, "%s: unpack arena tail: %r\n", name); return -1; } arena.blocksize = head->blocksize; arena.base = off + head->blocksize; arena.clumpmax = arena.blocksize / ClumpInfoSize; arena.size = head->size - 2*head->blocksize; fprint(2, "%s: base=%llx size=%llx blocksize=%x\n", name, off, head->size, head->blocksize); baseoff = head->blocksize; fprint(2, "\t%llx-%llx: head\n", (vlong)0, baseoff); lo = baseoff; hi = baseoff + arena.diskstats.used; fprint(2, "\t%llx-%llx: data (%llx)\n", lo, hi, hi - lo); hi = head->size - head->blocksize; clumpmax = head->blocksize / ClumpInfoSize; if(clumpmax > 0) lo = hi - (u64int)arena.diskstats.clumps/clumpmax * head->blocksize; else lo = hi; fprint(2, "\t%llx-%llx: clumps (%llx)\n", lo, hi, hi - lo); fprint(2, "\t%llx-%llx: tail\n", hi, hi + head->blocksize); fprint(2, "arena:\n"); printarena(2, &arena); return 0; }
static void rdarena(Arena *arena, u64int offset) { int i; u64int a, aa, e; uchar score[VtScoreSize]; Clump cl; ClumpInfo ci; ZBlock *lump; ZClump zcl; fprint(2, "wrarena: copying %s to venti\n", arena->name); printarena(2, arena); a = arena->base; e = arena->base + arena->size; if(offset != ~(u64int)0) { if(offset >= e - a) sysfatal("bad offset %#llx >= %#llx", offset, e - a); aa = offset; } else aa = 0; i = 0; for(a = 0; maxwrites != 0 && i < arena->memstats.clumps; a += ClumpSize + ci.size){ if(readclumpinfo(arena, i++, &ci) < 0) break; if(a < aa || ci.type == VtCorruptType){ if(ci.type == VtCorruptType) fprint(2, "%s: corrupt clump read at %#llx: +%d\n", argv0, a, ClumpSize+ci.size); continue; } lump = loadclump(arena, a, 0, &cl, score, 0); if(lump == nil) { fprint(2, "clump %#llx failed to read: %r\n", a); continue; } if(!fast && cl.info.type != VtCorruptType) { scoremem(score, lump->data, cl.info.uncsize); if(scorecmp(cl.info.score, score) != 0) { fprint(2, "clump %#llx has mismatched score\n", a); break; } if(vttypevalid(cl.info.type) < 0) { fprint(2, "clump %#llx has bad type %d\n", a, cl.info.type); break; } } if(z && cl.info.type != VtCorruptType){ zcl.cl = cl; zcl.lump = lump; zcl.aa = a; send(c, &zcl); }else freezblock(lump); if(maxwrites > 0) --maxwrites; } if(a > aa) aa = a; if(haveaoffset) print("end offset %#llx\n", aa); }