123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- #include "stdinc.h"
- #include "dat.h"
- #include "fns.h"
- #include "error.h"
- /*
- * integer conversion routines
- */
- #define U8GET(p) ((p)[0])
- #define U16GET(p) (((p)[0]<<8)|(p)[1])
- #define U32GET(p) (((p)[0]<<24)|((p)[1]<<16)|((p)[2]<<8)|(p)[3])
- #define U48GET(p) (((uint64_t)U16GET(p)<<32)|(uint64_t)U32GET((p)+2))
- #define U64GET(p) (((uint64_t)U32GET(p)<<32)|(uint64_t)U32GET((p)+4))
- #define U8PUT(p,v) (p)[0]=(v)
- #define U16PUT(p,v) (p)[0]=(v)>>8;(p)[1]=(v)
- //#define U32PUT(p,v) (p)[0]=(v)>>24;(p)[1]=(v)>>16;(p)[2]=(v)>>8;(p)[3]=(v)
- #define U32PUT(p,v) (p)[0]=((v)>>24)&0xFF;(p)[1]=((v)>>16)&0xFF;(p)[2]=((v)>>8)&0xFF;(p)[3]=(v)&0xFF
- #define U48PUT(p,v,t32) t32=(v)>>32;U16PUT(p,t32);t32=(v);U32PUT((p)+2,t32)
- #define U64PUT(p,v,t32) t32=(v)>>32;U32PUT(p,t32);t32=(v);U32PUT((p)+4,t32)
- void
- headerPack(Header *h, uint8_t *p)
- {
- memset(p, 0, HeaderSize);
- U32PUT(p, HeaderMagic);
- U16PUT(p+4, HeaderVersion);
- U16PUT(p+6, h->blockSize);
- U32PUT(p+8, h->super);
- U32PUT(p+12, h->label);
- U32PUT(p+16, h->data);
- U32PUT(p+20, h->end);
- }
- int
- headerUnpack(Header *h, uint8_t *p)
- {
- if(U32GET(p) != HeaderMagic){
- vtSetError("vac header bad magic");
- return 0;
- }
- h->version = U16GET(p+4);
- if(h->version != HeaderVersion){
- vtSetError("vac header bad version");
- return 0;
- }
- h->blockSize = U16GET(p+6);
- h->super = U32GET(p+8);
- h->label = U32GET(p+12);
- h->data = U32GET(p+16);
- h->end = U32GET(p+20);
- return 1;
- }
- void
- labelPack(Label *l, uint8_t *p, int i)
- {
- p += i*LabelSize;
- U8PUT(p, l->state);
- U8PUT(p+1, l->type);
- U32PUT(p+2, l->epoch);
- U32PUT(p+6, l->epochClose);
- U32PUT(p+10, l->tag);
- }
- int
- labelUnpack(Label *l, uint8_t *p, int i)
- {
- p += i*LabelSize;
- l->state = p[0];
- l->type = p[1];
- l->epoch = U32GET(p+2);
- l->epochClose = U32GET(p+6);
- l->tag = U32GET(p+10);
- if(l->type > BtMax){
- Bad:
- vtSetError(EBadLabel);
- fprint(2, "%s: labelUnpack: bad label: 0x%.2x 0x%.2x 0x%.8x "
- "0x%.8x 0x%.8x\n", argv0, l->state, l->type, l->epoch,
- l->epochClose, l->tag);
- return 0;
- }
- if(l->state != BsBad && l->state != BsFree){
- if(!(l->state&BsAlloc) || l->state & ~BsMask)
- goto Bad;
- if(l->state&BsClosed){
- if(l->epochClose == ~(uint32_t)0)
- goto Bad;
- }else{
- if(l->epochClose != ~(uint32_t)0)
- goto Bad;
- }
- }
- return 1;
- }
- uint32_t
- globalToLocal(uint8_t score[VtScoreSize])
- {
- int i;
- for(i=0; i<VtScoreSize-4; i++)
- if(score[i] != 0)
- return NilBlock;
- //return (int64_t)NilBlock;
- return U32GET(score+VtScoreSize-4);
- }
- void
- localToGlobal(uint32_t addr, uint8_t score[VtScoreSize])
- {
- memset(score, 0, VtScoreSize-4);
- U32PUT(score+VtScoreSize-4, addr);
- }
- void
- entryPack(Entry *e, uint8_t *p, int index)
- {
- uint32_t t32;
- int flags;
- p += index * VtEntrySize;
- U32PUT(p, e->gen);
- U16PUT(p+4, e->psize);
- U16PUT(p+6, e->dsize);
- flags = e->flags | ((e->depth << VtEntryDepthShift) & VtEntryDepthMask);
- U8PUT(p+8, flags);
- memset(p+9, 0, 5);
- U48PUT(p+14, e->size, t32);
- if(flags & VtEntryLocal){
- if(globalToLocal(e->score) == NilBlock)
- abort();
- memset(p+20, 0, 7);
- U8PUT(p+27, e->archive);
- U32PUT(p+28, e->snap);
- U32PUT(p+32, e->tag);
- memmove(p+36, e->score+16, 4);
- }else
- memmove(p+20, e->score, VtScoreSize);
- }
- int
- entryUnpack(Entry *e, uint8_t *p, int index)
- {
- p += index * VtEntrySize;
- e->gen = U32GET(p);
- e->psize = U16GET(p+4);
- e->dsize = U16GET(p+6);
- e->flags = U8GET(p+8);
- e->depth = (e->flags & VtEntryDepthMask) >> VtEntryDepthShift;
- e->flags &= ~VtEntryDepthMask;
- e->size = U48GET(p+14);
- if(e->flags & VtEntryLocal){
- e->archive = p[27];
- e->snap = U32GET(p+28);
- e->tag = U32GET(p+32);
- memset(e->score, 0, 16);
- memmove(e->score+16, p+36, 4);
- }else{
- e->archive = 0;
- e->snap = 0;
- e->tag = 0;
- memmove(e->score, p+20, VtScoreSize);
- }
- return 1;
- }
- int
- entryType(Entry *e)
- {
- return (((e->flags & VtEntryDir) != 0) << 3) | e->depth;
- }
- void
- superPack(Super *s, uint8_t *p)
- {
- uint32_t t32;
- memset(p, 0, SuperSize);
- U32PUT(p, SuperMagic);
- assert(s->version == SuperVersion);
- U16PUT(p+4, s->version);
- U32PUT(p+6, s->epochLow);
- U32PUT(p+10, s->epochHigh);
- U64PUT(p+14, s->qid, t32);
- U32PUT(p+22, s->active);
- U32PUT(p+26, s->next);
- U32PUT(p+30, s->current);
- memmove(p+34, s->last, VtScoreSize);
- memmove(p+54, s->name, sizeof(s->name));
- }
- int
- superUnpack(Super *s, uint8_t *p)
- {
- memset(s, 0, sizeof(*s));
- if(U32GET(p) != SuperMagic)
- goto Err;
- s->version = U16GET(p+4);
- if(s->version != SuperVersion)
- goto Err;
- s->epochLow = U32GET(p+6);
- s->epochHigh = U32GET(p+10);
- s->qid = U64GET(p+14);
- if(s->epochLow == 0 || s->epochLow > s->epochHigh || s->qid == 0)
- goto Err;
- s->active = U32GET(p+22);
- s->next = U32GET(p+26);
- s->current = U32GET(p+30);
- memmove(s->last, p+34, VtScoreSize);
- memmove(s->name, p+54, sizeof(s->name));
- s->name[sizeof(s->name)-1] = 0;
- return 1;
- Err:
- memset(s, 0, sizeof(*s));
- vtSetError(EBadSuper);
- return 0;
- }
|