diff options
Diffstat (limited to 'src/cmd/vac/source.c')
| -rw-r--r-- | src/cmd/vac/source.c | 390 |
1 files changed, 0 insertions, 390 deletions
diff --git a/src/cmd/vac/source.c b/src/cmd/vac/source.c deleted file mode 100644 index e7245a2f..00000000 --- a/src/cmd/vac/source.c +++ /dev/null @@ -1,390 +0,0 @@ -#include "stdinc.h" -#include "vac.h" -#include "dat.h" -#include "fns.h" -#include "error.h" - -static int sizeToDepth(uvlong s, int psize, int dsize); - -static int -sizeToDepth(uvlong s, int psize, int dsize) -{ - int np; - int d; - - /* determine pointer depth */ - np = psize/VtScoreSize; - s = (s + dsize - 1)/dsize; - for(d = 0; s > 1; d++) - s = (s + np - 1)/np; - return d; -} - -/* assumes u is lock? */ -Source * -sourceAlloc(Cache *c, Lump *u, ulong block, int entry, int readOnly) -{ - Source *r; - VtEntry d; - - if(u->asize < (entry+1)*VtEntrySize) { - vtSetError(ENoDir); - return nil; - } - - if(!vtEntryUnpack(&d, u->data, entry)) - return nil; - - if(!(d.flags & VtEntryActive)) { -fprint(2, "bad flags %#ux %V\n", d.flags, d.score); - vtSetError(ENoDir); - return nil; - } - - /* HACK for backwards compatiblity - should go away at some point */ - if(d.depth == 0) { -if(d.size > d.dsize) fprint(2, "depth == 0! size = %ulld\n", d.size); - d.depth = sizeToDepth(d.size, d.psize, d.dsize); - } - - if(d.depth < sizeToDepth(d.size, d.psize, d.dsize)) { - vtSetError(EBadDir); - return nil; - } - - r = vtMemAllocZ(sizeof(Source)); - r->lk = vtLockAlloc(); - r->cache = c; - r->readOnly = readOnly; - r->lump = lumpIncRef(u); - r->block = block; - r->entry = entry; - r->gen = d.gen; - r->dir = (d.flags & VtEntryDir) != 0; - r->depth = d.depth; - r->psize = d.psize; - r->dsize = d.dsize; - r->size = d.size; - - r->epb = r->dsize/VtEntrySize; - - return r; -} - -Source * -sourceOpen(Source *r, ulong entry, int readOnly) -{ - ulong bn; - Lump *u; - -if(0)fprint(2, "sourceOpen: %V:%d: %lud\n", r->lump->score, r->entry, entry); - if(r->readOnly && !readOnly) { - vtSetError(EReadOnly); - return nil; - } - - bn = entry/r->epb; - - u = sourceGetLump(r, bn, readOnly, 1); - if(u == nil) - return nil; - - r = sourceAlloc(r->cache, u, bn, entry%r->epb, readOnly); - lumpDecRef(u, 1); - return r; -} - -Source * -sourceCreate(Source *r, int psize, int dsize, int isdir, ulong entry) -{ - Source *rr; - int i; - Lump *u; - ulong bn; - VtEntry dir; - - if(r->readOnly) { - vtSetError(EReadOnly); - return nil; - } - - if(entry == 0) { - /* - * look at a random block to see if we can find an empty entry - */ - entry = sourceGetDirSize(r); - entry = r->epb*lnrand(entry/r->epb+1); - } - - /* - * need to loop since multiple threads could be trying to allocate - */ - for(;;) { - bn = entry/r->epb; - sourceSetDepth(r, (uvlong)(bn+1)*r->dsize); - u = sourceGetLump(r, bn, 0, 1); - if(u == nil) - return nil; - for(i=entry%r->epb; i<r->epb; i++) { - vtEntryUnpack(&dir, u->data, i); - if((dir.flags&VtEntryActive) == 0 && dir.gen != ~0) - goto Found; - } - lumpDecRef(u, 1); - entry = sourceGetDirSize(r); - } -Found: - /* found an entry */ - dir.psize = psize; - dir.dsize = dsize; - dir.flags = VtEntryActive; - if(isdir) - dir.flags |= VtEntryDir; - dir.depth = 0; - dir.size = 0; - memmove(dir.score, vtZeroScore, VtScoreSize); - vtEntryPack(&dir, u->data, i); - - sourceSetDirSize(r, bn*r->epb + i + 1); - rr = sourceAlloc(r->cache, u, bn, i, 0); - - lumpDecRef(u, 1); - return rr; -} - -void -sourceRemove(Source *r) -{ - lumpFreeEntry(r->lump, r->entry); - sourceFree(r); -} - -int -sourceSetDepth(Source *r, uvlong size) -{ - Lump *u, *v; - VtEntry dir; - int depth; - - if(r->readOnly){ - vtSetError(EReadOnly); - return 0; - } - - depth = sizeToDepth(size, r->psize, r->dsize); - - assert(depth >= 0); - - if(depth > VtPointerDepth) { - vtSetError(ETooBig); - return 0; - } - - vtLock(r->lk); - - if(r->depth >= depth) { - vtUnlock(r->lk); - return 1; - } - - u = r->lump; - vtLock(u->lk); - if(!vtEntryUnpack(&dir, u->data, r->entry)) { - vtUnlock(u->lk); - vtUnlock(r->lk); - return 0; - } - while(dir.depth < depth) { - v = cacheAllocLump(r->cache, VtPointerType0+r->depth, r->psize, r->dir); - if(v == nil) - break; - memmove(v->data, dir.score, VtScoreSize); - memmove(dir.score, v->score, VtScoreSize); - dir.depth++; - vtUnlock(v->lk); - } - vtEntryPack(&dir, u->data, r->entry); - vtUnlock(u->lk); - - r->depth = dir.depth; - vtUnlock(r->lk); - - return dir.depth == depth; -} - -int -sourceGetVtEntry(Source *r, VtEntry *dir) -{ - Lump *u; - - u = r->lump; - vtLock(u->lk); - if(!vtEntryUnpack(dir, u->data, r->entry)) { - vtUnlock(u->lk); - return 0; - } - vtUnlock(u->lk); - return 1; -} - -uvlong -sourceGetSize(Source *r) -{ - uvlong size; - - vtLock(r->lk); - size = r->size; - vtUnlock(r->lk); - - return size; -} - - -int -sourceSetSize(Source *r, uvlong size) -{ - Lump *u; - VtEntry dir; - int depth; - - if(r->readOnly) { - vtSetError(EReadOnly); - return 0; - } - - if(size > VtMaxFileSize || size > ((uvlong)MaxBlock)*r->dsize) { - vtSetError(ETooBig); - return 0; - } - - vtLock(r->lk); - depth = sizeToDepth(size, r->psize, r->dsize); - if(size < r->size) { - vtUnlock(r->lk); - return 1; - } - if(depth > r->depth) { - vtSetError(EBadDir); - vtUnlock(r->lk); - return 0; - } - - u = r->lump; - vtLock(u->lk); - vtEntryUnpack(&dir, u->data, r->entry); - dir.size = size; - vtEntryPack(&dir, u->data, r->entry); - vtUnlock(u->lk); - r->size = size; - vtUnlock(r->lk); - return 1; -} - -int -sourceSetDirSize(Source *r, ulong ds) -{ - uvlong size; - - size = (uvlong)r->dsize*(ds/r->epb); - size += VtEntrySize*(ds%r->epb); - return sourceSetSize(r, size); -} - -ulong -sourceGetDirSize(Source *r) -{ - ulong ds; - uvlong size; - - size = sourceGetSize(r); - ds = r->epb*(size/r->dsize); - ds += (size%r->dsize)/VtEntrySize; - return ds; -} - -ulong -sourceGetNumBlocks(Source *r) -{ - return (sourceGetSize(r)+r->dsize-1)/r->dsize; -} - -Lump * -sourceWalk(Source *r, ulong block, int readOnly, int *off) -{ - int depth; - int i, np; - Lump *u, *v; - int elem[VtPointerDepth+1]; - ulong b; - - if(r->readOnly && !readOnly) { - vtSetError(EReadOnly); - return nil; - } - - vtLock(r->lk); - np = r->psize/VtScoreSize; - b = block; - for(i=0; i<r->depth; i++) { - elem[i] = b % np; - b /= np; - } - if(b != 0) { - vtUnlock(r->lk); - vtSetError(EBadOffset); - return nil; - } - elem[i] = r->entry; - u = lumpIncRef(r->lump); - depth = r->depth; - *off = elem[0]; - vtUnlock(r->lk); - - for(i=depth; i>0; i--) { - v = lumpWalk(u, elem[i], VtPointerType0+i-1, r->psize, readOnly, 0); - lumpDecRef(u, 0); - if(v == nil) - return nil; - u = v; - } - - return u; -} - -Lump * -sourceGetLump(Source *r, ulong block, int readOnly, int lock) -{ - int type, off; - Lump *u, *v; - - if(r->readOnly && !readOnly) { - vtSetError(EReadOnly); - return nil; - } - if(block == NilBlock) { - vtSetError(ENilBlock); - return nil; - } -if(0)fprint(2, "sourceGetLump: %V:%d %lud\n", r->lump->score, r->entry, block); - u = sourceWalk(r, block, readOnly, &off); - if(u == nil) - return nil; - if(r->dir) - type = VtDirType; - else - type = VtDataType; - v = lumpWalk(u, off, type, r->dsize, readOnly, lock); - lumpDecRef(u, 0); - return v; -} - -void -sourceFree(Source *k) -{ - if(k == nil) - return; - lumpDecRef(k->lump, 0); - vtLockFree(k->lk); - memset(k, ~0, sizeof(*k)); - vtMemFree(k); -} |
