aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/venti/srv/conv.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2005-07-12 15:23:36 +0000
committerrsc <devnull@localhost>2005-07-12 15:23:36 +0000
commita0d146edd7a7de6236a0d60baafeeb59f8452aae (patch)
treeb55baa526d9f5adfc73246e6ee2fadf455e0b7a2 /src/cmd/venti/srv/conv.c
parent88bb285e3d87ec2508840af33f7e0af53ec3c13c (diff)
downloadplan9port-a0d146edd7a7de6236a0d60baafeeb59f8452aae.tar.gz
plan9port-a0d146edd7a7de6236a0d60baafeeb59f8452aae.tar.bz2
plan9port-a0d146edd7a7de6236a0d60baafeeb59f8452aae.zip
return of venti
Diffstat (limited to 'src/cmd/venti/srv/conv.c')
-rw-r--r--src/cmd/venti/srv/conv.c632
1 files changed, 632 insertions, 0 deletions
diff --git a/src/cmd/venti/srv/conv.c b/src/cmd/venti/srv/conv.c
new file mode 100644
index 00000000..13afc7d2
--- /dev/null
+++ b/src/cmd/venti/srv/conv.c
@@ -0,0 +1,632 @@
+#include "stdinc.h"
+#include "dat.h"
+#include "fns.h"
+
+/*
+ * disk structure conversion routines
+ */
+#define U8GET(p) ((p)[0])
+#define U16GET(p) (((p)[0]<<8)|(p)[1])
+#define U32GET(p) ((u32int)(((p)[0]<<24)|((p)[1]<<16)|((p)[2]<<8)|(p)[3]))
+#define U64GET(p) (((u64int)U32GET(p)<<32)|(u64int)U32GET((p)+4))
+
+#define U8PUT(p,v) (p)[0]=(v)&0xFF
+#define U16PUT(p,v) (p)[0]=((v)>>8)&0xFF;(p)[1]=(v)&0xFF
+#define U32PUT(p,v) (p)[0]=((v)>>24)&0xFF;(p)[1]=((v)>>16)&0xFF;(p)[2]=((v)>>8)&0xFF;(p)[3]=(v)&0xFF
+#define U64PUT(p,v,t32) t32=(v)>>32;U32PUT(p,t32);t32=(v);U32PUT((p)+4,t32)
+
+static struct {
+ u32int m;
+ char *s;
+} magics[] = {
+ ArenaPartMagic, "ArenaPartMagic",
+ ArenaHeadMagic, "ArenaHeadMagic",
+ ArenaMagic, "ArenaMagic",
+ ISectMagic, "ISectMagic",
+ BloomMagic, "BloomMagic",
+};
+
+static char*
+fmtmagic(char *s, u32int m)
+{
+ int i;
+
+ for(i=0; i<nelem(magics); i++)
+ if(magics[i].m == m)
+ return magics[i].s;
+ sprint(s, "0x%08ux", m);
+ return s;
+}
+
+u32int
+unpackmagic(u8int *buf)
+{
+ return U32GET(buf);
+}
+
+void
+packmagic(u32int magic, u8int *buf)
+{
+ U32PUT(buf, magic);
+}
+
+int
+unpackarenapart(ArenaPart *ap, u8int *buf)
+{
+ u8int *p;
+ u32int m;
+ char fbuf[20];
+
+ p = buf;
+
+ m = U32GET(p);
+ if(m != ArenaPartMagic){
+ seterr(ECorrupt, "arena set has wrong magic number: %s expected ArenaPartMagic (%lux)", fmtmagic(fbuf, m), ArenaPartMagic);
+ return -1;
+ }
+ p += U32Size;
+ ap->version = U32GET(p);
+ p += U32Size;
+ ap->blocksize = U32GET(p);
+ p += U32Size;
+ ap->arenabase = U32GET(p);
+ p += U32Size;
+
+ if(buf + ArenaPartSize != p)
+ sysfatal("unpackarenapart unpacked wrong amount");
+
+ return 0;
+}
+
+int
+packarenapart(ArenaPart *ap, u8int *buf)
+{
+ u8int *p;
+
+ p = buf;
+
+ U32PUT(p, ArenaPartMagic);
+ p += U32Size;
+ U32PUT(p, ap->version);
+ p += U32Size;
+ U32PUT(p, ap->blocksize);
+ p += U32Size;
+ U32PUT(p, ap->arenabase);
+ p += U32Size;
+
+ if(buf + ArenaPartSize != p)
+ sysfatal("packarenapart packed wrong amount");
+
+ return 0;
+}
+
+int
+unpackarena(Arena *arena, u8int *buf)
+{
+ int sz;
+ u8int *p;
+ u32int m;
+ char fbuf[20];
+
+ p = buf;
+
+ m = U32GET(p);
+ if(m != ArenaMagic){
+ seterr(ECorrupt, "arena has wrong magic number: %s expected ArenaMagic (%lux)", fmtmagic(fbuf, m), ArenaMagic);
+ return -1;
+ }
+ p += U32Size;
+ arena->version = U32GET(p);
+ p += U32Size;
+ namecp(arena->name, (char*)p);
+ p += ANameSize;
+ arena->diskstats.clumps = U32GET(p);
+ p += U32Size;
+ arena->diskstats.cclumps = U32GET(p);
+ p += U32Size;
+ arena->ctime = U32GET(p);
+ p += U32Size;
+ arena->wtime = U32GET(p);
+ p += U32Size;
+ if(arena->version == ArenaVersion5){
+ arena->clumpmagic = U32GET(p);
+ p += U32Size;
+ }
+ arena->diskstats.used = U64GET(p);
+ p += U64Size;
+ arena->diskstats.uncsize = U64GET(p);
+ p += U64Size;
+ arena->diskstats.sealed = U8GET(p);
+ p += U8Size;
+
+ arena->memstats = arena->diskstats;
+
+ switch(arena->version){
+ case ArenaVersion4:
+ sz = ArenaSize4;
+ arena->clumpmagic = _ClumpMagic;
+ break;
+ case ArenaVersion5:
+ sz = ArenaSize5;
+ break;
+ default:
+ seterr(ECorrupt, "arena has bad version number %d", arena->version);
+ return -1;
+ }
+ if(buf + sz != p)
+ sysfatal("unpackarena unpacked wrong amount");
+
+ return 0;
+}
+
+int
+packarena(Arena *arena, u8int *buf)
+{
+ int sz;
+ u8int *p;
+ u32int t32;
+
+ switch(arena->version){
+ case ArenaVersion4:
+ sz = ArenaSize4;
+ if(arena->clumpmagic != _ClumpMagic)
+ fprint(2, "warning: writing old arena tail loses clump magic 0x%lux != 0x%lux\n",
+ (ulong)arena->clumpmagic, (ulong)_ClumpMagic);
+ break;
+ case ArenaVersion5:
+ sz = ArenaSize5;
+ break;
+ default:
+ sysfatal("packarena unknown version %d", arena->version);
+ return -1;
+ }
+
+ p = buf;
+
+ U32PUT(p, ArenaMagic);
+ p += U32Size;
+ U32PUT(p, arena->version);
+ p += U32Size;
+ namecp((char*)p, arena->name);
+ p += ANameSize;
+ U32PUT(p, arena->diskstats.clumps);
+ p += U32Size;
+ U32PUT(p, arena->diskstats.cclumps);
+ p += U32Size;
+ U32PUT(p, arena->ctime);
+ p += U32Size;
+ U32PUT(p, arena->wtime);
+ p += U32Size;
+ if(arena->version == ArenaVersion5){
+ U32PUT(p, arena->clumpmagic);
+ p += U32Size;
+ }
+ U64PUT(p, arena->diskstats.used, t32);
+ p += U64Size;
+ U64PUT(p, arena->diskstats.uncsize, t32);
+ p += U64Size;
+ U8PUT(p, arena->diskstats.sealed);
+ p += U8Size;
+
+ if(buf + sz != p)
+ sysfatal("packarena packed wrong amount");
+
+ return 0;
+}
+
+int
+unpackarenahead(ArenaHead *head, u8int *buf)
+{
+ u8int *p;
+ u32int m;
+ int sz;
+
+ p = buf;
+
+ m = U32GET(p);
+ /* XXX check magic! */
+
+ p += U32Size;
+ head->version = U32GET(p);
+ p += U32Size;
+ namecp(head->name, (char*)p);
+ p += ANameSize;
+ head->blocksize = U32GET(p);
+ p += U32Size;
+ head->size = U64GET(p);
+ p += U64Size;
+ if(head->version == ArenaVersion5){
+ head->clumpmagic = U32GET(p);
+ p += U32Size;
+ }
+
+ switch(head->version){
+ case ArenaVersion4:
+ sz = ArenaHeadSize4;
+ head->clumpmagic = _ClumpMagic;
+ break;
+ case ArenaVersion5:
+ sz = ArenaHeadSize5;
+ break;
+ default:
+ seterr(ECorrupt, "arena head has unexpected version %d", head->version);
+ return -1;
+ }
+
+ if(buf + sz != p)
+ sysfatal("unpackarenahead unpacked wrong amount");
+
+ return 0;
+}
+
+int
+packarenahead(ArenaHead *head, u8int *buf)
+{
+ u8int *p;
+ int sz;
+ u32int t32;
+
+ switch(head->version){
+ case ArenaVersion4:
+ sz = ArenaHeadSize4;
+ if(head->clumpmagic != _ClumpMagic)
+ fprint(2, "warning: writing old arena header loses clump magic 0x%lux != 0x%lux\n",
+ (ulong)head->clumpmagic, (ulong)_ClumpMagic);
+ break;
+ case ArenaVersion5:
+ sz = ArenaHeadSize5;
+ break;
+ default:
+ sysfatal("packarenahead unknown version %d", head->version);
+ return -1;
+ }
+
+ p = buf;
+
+ U32PUT(p, ArenaHeadMagic);
+ p += U32Size;
+ U32PUT(p, head->version);
+ p += U32Size;
+ namecp((char*)p, head->name);
+ p += ANameSize;
+ U32PUT(p, head->blocksize);
+ p += U32Size;
+ U64PUT(p, head->size, t32);
+ p += U64Size;
+ if(head->version == ArenaVersion5){
+ U32PUT(p, head->clumpmagic);
+ p += U32Size;
+ }
+ if(buf + sz != p)
+ sysfatal("packarenahead packed wrong amount");
+
+ return 0;
+}
+
+static int
+checkclump(Clump *w)
+{
+ if(w->encoding == ClumpENone){
+ if(w->info.size != w->info.uncsize){
+ seterr(ECorrupt, "uncompressed wad size mismatch");
+ return -1;
+ }
+ }else if(w->encoding == ClumpECompress){
+ if(w->info.size >= w->info.uncsize){
+ seterr(ECorrupt, "compressed lump has inconsistent block sizes %d %d", w->info.size, w->info.uncsize);
+ return -1;
+ }
+ }else{
+ seterr(ECorrupt, "clump has illegal encoding");
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+unpackclump(Clump *c, u8int *buf, u32int cmagic)
+{
+ u8int *p;
+ u32int magic;
+
+ p = buf;
+ magic = U32GET(p);
+ if(magic != cmagic){
+ seterr(ECorrupt, "clump has bad magic number=%#8.8ux != %#8.8ux", magic, cmagic);
+ return -1;
+ }
+ p += U32Size;
+
+ c->info.type = vtfromdisktype(U8GET(p));
+ p += U8Size;
+ c->info.size = U16GET(p);
+ p += U16Size;
+ c->info.uncsize = U16GET(p);
+ p += U16Size;
+ scorecp(c->info.score, p);
+ p += VtScoreSize;
+
+ c->encoding = U8GET(p);
+ p += U8Size;
+ c->creator = U32GET(p);
+ p += U32Size;
+ c->time = U32GET(p);
+ p += U32Size;
+
+ if(buf + ClumpSize != p)
+ sysfatal("unpackclump unpacked wrong amount");
+
+ return checkclump(c);
+}
+
+int
+packclump(Clump *c, u8int *buf, u32int magic)
+{
+ u8int *p;
+
+ p = buf;
+ U32PUT(p, magic);
+ p += U32Size;
+
+ U8PUT(p, vttodisktype(c->info.type));
+ p += U8Size;
+ U16PUT(p, c->info.size);
+ p += U16Size;
+ U16PUT(p, c->info.uncsize);
+ p += U16Size;
+ scorecp(p, c->info.score);
+ p += VtScoreSize;
+
+ U8PUT(p, c->encoding);
+ p += U8Size;
+ U32PUT(p, c->creator);
+ p += U32Size;
+ U32PUT(p, c->time);
+ p += U32Size;
+
+ if(buf + ClumpSize != p)
+ sysfatal("packclump packed wrong amount");
+
+ return checkclump(c);
+}
+
+void
+unpackclumpinfo(ClumpInfo *ci, u8int *buf)
+{
+ u8int *p;
+
+ p = buf;
+ ci->type = vtfromdisktype(U8GET(p));
+ p += U8Size;
+ ci->size = U16GET(p);
+ p += U16Size;
+ ci->uncsize = U16GET(p);
+ p += U16Size;
+ scorecp(ci->score, p);
+ p += VtScoreSize;
+
+ if(buf + ClumpInfoSize != p)
+ sysfatal("unpackclumpinfo unpacked wrong amount");
+}
+
+void
+packclumpinfo(ClumpInfo *ci, u8int *buf)
+{
+ u8int *p;
+
+ p = buf;
+ U8PUT(p, vttodisktype(ci->type));
+ p += U8Size;
+ U16PUT(p, ci->size);
+ p += U16Size;
+ U16PUT(p, ci->uncsize);
+ p += U16Size;
+ scorecp(p, ci->score);
+ p += VtScoreSize;
+
+ if(buf + ClumpInfoSize != p)
+ sysfatal("packclumpinfo packed wrong amount");
+}
+
+int
+unpackisect(ISect *is, u8int *buf)
+{
+ u8int *p;
+ u32int m;
+ char fbuf[20];
+
+ p = buf;
+
+
+ m = U32GET(p);
+ if(m != ISectMagic){
+ seterr(ECorrupt, "index section has wrong magic number: %s expected ISectMagic (%lux)",
+ fmtmagic(fbuf, m), ISectMagic);
+ return -1;
+ }
+ p += U32Size;
+ is->version = U32GET(p);
+ p += U32Size;
+ namecp(is->name, (char*)p);
+ p += ANameSize;
+ namecp(is->index, (char*)p);
+ p += ANameSize;
+ is->blocksize = U32GET(p);
+ p += U32Size;
+ is->blockbase = U32GET(p);
+ p += U32Size;
+ is->blocks = U32GET(p);
+ p += U32Size;
+ is->start = U32GET(p);
+ p += U32Size;
+ is->stop = U32GET(p);
+ p += U32Size;
+ if(buf + ISectSize1 != p)
+ sysfatal("unpackisect unpacked wrong amount");
+ is->bucketmagic = 0;
+ if(is->version == ISectVersion2){
+ is->bucketmagic = U32GET(p);
+ p += U32Size;
+ if(buf + ISectSize2 != p)
+ sysfatal("unpackisect unpacked wrong amount");
+ }
+
+ return 0;
+}
+
+int
+packisect(ISect *is, u8int *buf)
+{
+ u8int *p;
+
+ p = buf;
+
+ U32PUT(p, ISectMagic);
+ p += U32Size;
+ U32PUT(p, is->version);
+ p += U32Size;
+ namecp((char*)p, is->name);
+ p += ANameSize;
+ namecp((char*)p, is->index);
+ p += ANameSize;
+ U32PUT(p, is->blocksize);
+ p += U32Size;
+ U32PUT(p, is->blockbase);
+ p += U32Size;
+ U32PUT(p, is->blocks);
+ p += U32Size;
+ U32PUT(p, is->start);
+ p += U32Size;
+ U32PUT(p, is->stop);
+ p += U32Size;
+ if(buf + ISectSize1 != p)
+ sysfatal("packisect packed wrong amount");
+ if(is->version == ISectVersion2){
+ U32PUT(p, is->bucketmagic);
+ p += U32Size;
+ if(buf + ISectSize2 != p)
+ sysfatal("packisect packed wrong amount");
+ }
+
+ return 0;
+}
+
+void
+unpackientry(IEntry *ie, u8int *buf)
+{
+ u8int *p;
+
+ p = buf;
+
+ scorecp(ie->score, p);
+ p += VtScoreSize;
+ ie->wtime = U32GET(p);
+ p += U32Size;
+ ie->train = U16GET(p);
+ p += U16Size;
+ ie->ia.addr = U64GET(p);
+if(ie->ia.addr>>56) print("%.8H => %llux\n", p, ie->ia.addr);
+ p += U64Size;
+ ie->ia.size = U16GET(p);
+ p += U16Size;
+ if(p - buf != IEntryTypeOff)
+ sysfatal("unpackientry bad IEntryTypeOff amount");
+ ie->ia.type = vtfromdisktype(U8GET(p));
+ p += U8Size;
+ ie->ia.blocks = U8GET(p);
+ p += U8Size;
+
+ if(p - buf != IEntrySize)
+ sysfatal("unpackientry unpacked wrong amount");
+}
+
+void
+packientry(IEntry *ie, u8int *buf)
+{
+ u32int t32;
+ u8int *p;
+
+ p = buf;
+
+ scorecp(p, ie->score);
+ p += VtScoreSize;
+ U32PUT(p, ie->wtime);
+ p += U32Size;
+ U16PUT(p, ie->train);
+ p += U16Size;
+ U64PUT(p, ie->ia.addr, t32);
+ p += U64Size;
+ U16PUT(p, ie->ia.size);
+ p += U16Size;
+ U8PUT(p, vttodisktype(ie->ia.type));
+ p += U8Size;
+ U8PUT(p, ie->ia.blocks);
+ p += U8Size;
+
+ if(p - buf != IEntrySize)
+ sysfatal("packientry packed wrong amount");
+}
+
+void
+unpackibucket(IBucket *b, u8int *buf, u32int magic)
+{
+ b->n = U16GET(buf);
+ b->data = buf + IBucketSize;
+ if(magic && magic != U32GET(buf+U16Size))
+ b->n = 0;
+}
+
+void
+packibucket(IBucket *b, u8int *buf, u32int magic)
+{
+ U16PUT(buf, b->n);
+ U32PUT(buf+U16Size, magic);
+}
+
+void
+packbloomhead(Bloom *b, u8int *buf)
+{
+ u8int *p;
+
+ p = buf;
+ U32PUT(p, BloomMagic);
+ U32PUT(p+4, BloomVersion);
+ U32PUT(p+8, b->nhash);
+ U32PUT(p+12, b->size);
+}
+
+int
+unpackbloomhead(Bloom *b, u8int *buf)
+{
+ u8int *p;
+ u32int m;
+ char fbuf[20];
+
+ p = buf;
+
+ m = U32GET(p);
+ if(m != BloomMagic){
+ seterr(ECorrupt, "bloom filter has wrong magic number: %s expected BloomMagic (%lux)", fmtmagic(fbuf, m), (ulong)BloomMagic);
+ return -1;
+ }
+ p += U32Size;
+
+ m = U32GET(p);
+ if(m != BloomVersion){
+ seterr(ECorrupt, "bloom filter has wrong version %ud expected %ud", (uint)m, (uint)BloomVersion);
+ return -1;
+ }
+ p += U32Size;
+
+ b->nhash = U32GET(p);
+ p += U32Size;
+
+ b->size = U32GET(p);
+ p += U32Size;
+
+ if(buf + BloomHeadSize != p)
+ sysfatal("unpackarena unpacked wrong amount");
+
+ return 0;
+}