6 * disk structure conversion routines
8 #define U8GET(p) ((p)[0])
9 #define U16GET(p) (((p)[0]<<8)|(p)[1])
10 #define U32GET(p) ((u32int)(((p)[0]<<24)|((p)[1]<<16)|((p)[2]<<8)|(p)[3]))
11 #define U64GET(p) (((u64int)U32GET(p)<<32)|(u64int)U32GET((p)+4))
13 #define U8PUT(p,v) (p)[0]=(v)&0xFF
14 #define U16PUT(p,v) (p)[0]=((v)>>8)&0xFF;(p)[1]=(v)&0xFF
15 #define U32PUT(p,v) (p)[0]=((v)>>24)&0xFF;(p)[1]=((v)>>16)&0xFF;(p)[2]=((v)>>8)&0xFF;(p)[3]=(v)&0xFF
16 #define U64PUT(p,v,t32) t32=(v)>>32;U32PUT(p,t32);t32=(v);U32PUT((p)+4,t32)
22 ArenaPartMagic, "ArenaPartMagic",
23 ArenaHeadMagic, "ArenaHeadMagic",
24 ArenaMagic, "ArenaMagic",
25 ISectMagic, "ISectMagic",
26 BloomMagic, "BloomMagic",
30 fmtmagic(char *s, u32int m)
34 for(i=0; i<nelem(magics); i++)
37 sprint(s, "0x%08ux", m);
42 unpackmagic(u8int *buf)
48 packmagic(u32int magic, u8int *buf)
54 unpackarenapart(ArenaPart *ap, u8int *buf)
63 if(m != ArenaPartMagic){
64 seterr(ECorrupt, "arena set has wrong magic number: %s expected ArenaPartMagic (%lux)", fmtmagic(fbuf, m), ArenaPartMagic);
68 ap->version = U32GET(p);
70 ap->blocksize = U32GET(p);
72 ap->arenabase = U32GET(p);
75 if(buf + ArenaPartSize != p)
76 sysfatal("unpackarenapart unpacked wrong amount");
82 packarenapart(ArenaPart *ap, u8int *buf)
88 U32PUT(p, ArenaPartMagic);
90 U32PUT(p, ap->version);
92 U32PUT(p, ap->blocksize);
94 U32PUT(p, ap->arenabase);
97 if(buf + ArenaPartSize != p)
98 sysfatal("packarenapart packed wrong amount");
104 unpackarena(Arena *arena, u8int *buf)
115 seterr(ECorrupt, "arena has wrong magic number: %s expected ArenaMagic (%lux)", fmtmagic(fbuf, m), ArenaMagic);
119 arena->version = U32GET(p);
121 namecp(arena->name, (char*)p);
123 arena->diskstats.clumps = U32GET(p);
125 arena->diskstats.cclumps = U32GET(p);
127 arena->ctime = U32GET(p);
129 arena->wtime = U32GET(p);
131 if(arena->version == ArenaVersion5){
132 arena->clumpmagic = U32GET(p);
135 arena->diskstats.used = U64GET(p);
137 arena->diskstats.uncsize = U64GET(p);
139 arena->diskstats.sealed = U8GET(p);
142 arena->memstats = arena->diskstats;
144 switch(arena->version){
147 arena->clumpmagic = _ClumpMagic;
153 seterr(ECorrupt, "arena has bad version number %d", arena->version);
157 sysfatal("unpackarena unpacked wrong amount");
163 packarena(Arena *arena, u8int *buf)
169 switch(arena->version){
172 if(arena->clumpmagic != _ClumpMagic)
173 fprint(2, "warning: writing old arena tail loses clump magic 0x%lux != 0x%lux\n",
174 (ulong)arena->clumpmagic, (ulong)_ClumpMagic);
180 sysfatal("packarena unknown version %d", arena->version);
186 U32PUT(p, ArenaMagic);
188 U32PUT(p, arena->version);
190 namecp((char*)p, arena->name);
192 U32PUT(p, arena->diskstats.clumps);
194 U32PUT(p, arena->diskstats.cclumps);
196 U32PUT(p, arena->ctime);
198 U32PUT(p, arena->wtime);
200 if(arena->version == ArenaVersion5){
201 U32PUT(p, arena->clumpmagic);
204 U64PUT(p, arena->diskstats.used, t32);
206 U64PUT(p, arena->diskstats.uncsize, t32);
208 U8PUT(p, arena->diskstats.sealed);
212 sysfatal("packarena packed wrong amount");
218 unpackarenahead(ArenaHead *head, u8int *buf)
227 /* XXX check magic! */
230 head->version = U32GET(p);
232 namecp(head->name, (char*)p);
234 head->blocksize = U32GET(p);
236 head->size = U64GET(p);
238 if(head->version == ArenaVersion5){
239 head->clumpmagic = U32GET(p);
243 switch(head->version){
246 head->clumpmagic = _ClumpMagic;
252 seterr(ECorrupt, "arena head has unexpected version %d", head->version);
257 sysfatal("unpackarenahead unpacked wrong amount");
263 packarenahead(ArenaHead *head, u8int *buf)
269 switch(head->version){
272 if(head->clumpmagic != _ClumpMagic)
273 fprint(2, "warning: writing old arena header loses clump magic 0x%lux != 0x%lux\n",
274 (ulong)head->clumpmagic, (ulong)_ClumpMagic);
280 sysfatal("packarenahead unknown version %d", head->version);
286 U32PUT(p, ArenaHeadMagic);
288 U32PUT(p, head->version);
290 namecp((char*)p, head->name);
292 U32PUT(p, head->blocksize);
294 U64PUT(p, head->size, t32);
296 if(head->version == ArenaVersion5){
297 U32PUT(p, head->clumpmagic);
301 sysfatal("packarenahead packed wrong amount");
309 if(w->encoding == ClumpENone){
310 if(w->info.size != w->info.uncsize){
311 seterr(ECorrupt, "uncompressed wad size mismatch");
314 }else if(w->encoding == ClumpECompress){
315 if(w->info.size >= w->info.uncsize){
316 seterr(ECorrupt, "compressed lump has inconsistent block sizes %d %d", w->info.size, w->info.uncsize);
320 seterr(ECorrupt, "clump has illegal encoding");
328 unpackclump(Clump *c, u8int *buf, u32int cmagic)
336 seterr(ECorrupt, "clump has bad magic number=%#8.8ux != %#8.8ux", magic, cmagic);
341 c->info.type = vtfromdisktype(U8GET(p));
343 c->info.size = U16GET(p);
345 c->info.uncsize = U16GET(p);
347 scorecp(c->info.score, p);
350 c->encoding = U8GET(p);
352 c->creator = U32GET(p);
357 if(buf + ClumpSize != p)
358 sysfatal("unpackclump unpacked wrong amount");
360 return checkclump(c);
364 packclump(Clump *c, u8int *buf, u32int magic)
372 U8PUT(p, vttodisktype(c->info.type));
374 U16PUT(p, c->info.size);
376 U16PUT(p, c->info.uncsize);
378 scorecp(p, c->info.score);
381 U8PUT(p, c->encoding);
383 U32PUT(p, c->creator);
388 if(buf + ClumpSize != p)
389 sysfatal("packclump packed wrong amount");
391 return checkclump(c);
395 unpackclumpinfo(ClumpInfo *ci, u8int *buf)
400 ci->type = vtfromdisktype(U8GET(p));
402 ci->size = U16GET(p);
404 ci->uncsize = U16GET(p);
406 scorecp(ci->score, p);
409 if(buf + ClumpInfoSize != p)
410 sysfatal("unpackclumpinfo unpacked wrong amount");
414 packclumpinfo(ClumpInfo *ci, u8int *buf)
419 U8PUT(p, vttodisktype(ci->type));
423 U16PUT(p, ci->uncsize);
425 scorecp(p, ci->score);
428 if(buf + ClumpInfoSize != p)
429 sysfatal("packclumpinfo packed wrong amount");
433 unpackisect(ISect *is, u8int *buf)
444 seterr(ECorrupt, "index section has wrong magic number: %s expected ISectMagic (%lux)",
445 fmtmagic(fbuf, m), ISectMagic);
449 is->version = U32GET(p);
451 namecp(is->name, (char*)p);
453 namecp(is->index, (char*)p);
455 is->blocksize = U32GET(p);
457 is->blockbase = U32GET(p);
459 is->blocks = U32GET(p);
461 is->start = U32GET(p);
463 is->stop = U32GET(p);
465 if(buf + ISectSize1 != p)
466 sysfatal("unpackisect unpacked wrong amount");
468 if(is->version == ISectVersion2){
469 is->bucketmagic = U32GET(p);
471 if(buf + ISectSize2 != p)
472 sysfatal("unpackisect unpacked wrong amount");
479 packisect(ISect *is, u8int *buf)
485 U32PUT(p, ISectMagic);
487 U32PUT(p, is->version);
489 namecp((char*)p, is->name);
491 namecp((char*)p, is->index);
493 U32PUT(p, is->blocksize);
495 U32PUT(p, is->blockbase);
497 U32PUT(p, is->blocks);
499 U32PUT(p, is->start);
503 if(buf + ISectSize1 != p)
504 sysfatal("packisect packed wrong amount");
505 if(is->version == ISectVersion2){
506 U32PUT(p, is->bucketmagic);
508 if(buf + ISectSize2 != p)
509 sysfatal("packisect packed wrong amount");
516 unpackientry(IEntry *ie, u8int *buf)
522 scorecp(ie->score, p);
524 ie->wtime = U32GET(p);
526 ie->train = U16GET(p);
528 ie->ia.addr = U64GET(p);
529 if(ie->ia.addr>>56) print("%.8H => %llux\n", p, ie->ia.addr);
531 ie->ia.size = U16GET(p);
533 if(p - buf != IEntryTypeOff)
534 sysfatal("unpackientry bad IEntryTypeOff amount");
535 ie->ia.type = vtfromdisktype(U8GET(p));
537 ie->ia.blocks = U8GET(p);
540 if(p - buf != IEntrySize)
541 sysfatal("unpackientry unpacked wrong amount");
545 packientry(IEntry *ie, u8int *buf)
552 scorecp(p, ie->score);
554 U32PUT(p, ie->wtime);
556 U16PUT(p, ie->train);
558 U64PUT(p, ie->ia.addr, t32);
560 U16PUT(p, ie->ia.size);
562 U8PUT(p, vttodisktype(ie->ia.type));
564 U8PUT(p, ie->ia.blocks);
567 if(p - buf != IEntrySize)
568 sysfatal("packientry packed wrong amount");
572 unpackibucket(IBucket *b, u8int *buf, u32int magic)
575 b->data = buf + IBucketSize;
576 if(magic && magic != U32GET(buf+U16Size))
581 packibucket(IBucket *b, u8int *buf, u32int magic)
584 U32PUT(buf+U16Size, magic);
588 packbloomhead(Bloom *b, u8int *buf)
593 U32PUT(p, BloomMagic);
594 U32PUT(p+4, BloomVersion);
595 U32PUT(p+8, b->nhash);
596 U32PUT(p+12, b->size);
600 unpackbloomhead(Bloom *b, u8int *buf)
610 seterr(ECorrupt, "bloom filter has wrong magic number: %s expected BloomMagic (%lux)", fmtmagic(fbuf, m), (ulong)BloomMagic);
616 if(m != BloomVersion){
617 seterr(ECorrupt, "bloom filter has wrong version %ud expected %ud", (uint)m, (uint)BloomVersion);
622 b->nhash = U32GET(p);
628 if(buf + BloomHeadSize != p)
629 sysfatal("unpackarena unpacked wrong amount");