Block* dataBlock(uchar score[VtScoreSize], uint type, uint tag) { Block *b, *bl; int lpb; Label l; u32int addr; addr = globalToLocal(score); if(addr == NilBlock) return ventiBlock(score, type); lpb = h.blockSize/LabelSize; bl = readBlock(PartLabel, addr/lpb); if(bl == nil) return nil; if(!labelUnpack(&l, bl->data, addr%lpb)) { werrstr("%r"); blockPut(bl); return nil; } blockPut(bl); if(l.type != type) { werrstr("type mismatch; got %d (%s) wanted %d (%s)", l.type, btStr(l.type), type, btStr(type)); return nil; } if(tag && l.tag != tag) { werrstr("tag mismatch; got 0x%.8ux wanted 0x%.8ux", l.tag, tag); return nil; } b = readBlock(PartData, addr); if(b == nil) return nil; b->l = l; return b; }
static u32int blockAlloc(int type, u32int tag) { static u32int addr; Label l; int lpb; lpb = bsize/LabelSize; blockRead(PartLabel, addr/lpb); if(!labelUnpack(&l, buf, addr % lpb)) vtFatal("bad label: %r"); if(l.state != BsFree) vtFatal("want to allocate block already in use"); l.epoch = 1; l.epochClose = ~(u32int)0; l.type = type; l.state = BsAlloc; l.tag = tag; labelPack(&l, buf, addr % lpb); blockWrite(PartLabel, addr/lpb); return addr++; }