mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-12 11:10:07 +00:00
vac: clean up, add unvac
This commit is contained in:
parent
01cea2ecb8
commit
64f9764ea9
16 changed files with 488 additions and 2421 deletions
|
@ -1,2 +0,0 @@
|
|||
This is somewhat untested but is believed to work.
|
||||
|
|
@ -564,8 +564,6 @@ vacfileread(VacFile *f, void *buf, int cnt, vlong offset)
|
|||
VtBlock *b;
|
||||
uchar *p;
|
||||
|
||||
if(0)fprint(2, "fileRead: %s %d, %lld\n", f->dir.elem, cnt, offset);
|
||||
|
||||
if(filerlock(f) < 0)
|
||||
return -1;
|
||||
|
||||
|
@ -620,64 +618,6 @@ Err1:
|
|||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Changes the file block bn to be the given block score.
|
||||
* Very sneaky. Only used by flfmt.
|
||||
*/
|
||||
int
|
||||
filemapblock(VacFile *f, ulong bn, uchar score[VtScoreSize], ulong tag)
|
||||
{
|
||||
VtBlock *b;
|
||||
VtEntry e;
|
||||
VtFile *s;
|
||||
|
||||
if(filelock(f) < 0)
|
||||
return -1;
|
||||
|
||||
s = nil;
|
||||
if(f->dir.mode & ModeDir){
|
||||
werrstr(ENotFile);
|
||||
goto Err;
|
||||
}
|
||||
|
||||
if(f->source->mode != VtORDWR){
|
||||
werrstr(EReadOnly);
|
||||
goto Err;
|
||||
}
|
||||
|
||||
if(vtfilelock(f->source, -1) < 0)
|
||||
goto Err;
|
||||
|
||||
s = f->source;
|
||||
b = _vtfileblock(s, bn, VtORDWR, 1, tag);
|
||||
if(b == nil)
|
||||
goto Err;
|
||||
|
||||
if(vtfilegetentry(s, &e) < 0)
|
||||
goto Err;
|
||||
if(b->l.type == BtDir){
|
||||
memmove(e.score, score, VtScoreSize);
|
||||
assert(e.tag == tag || e.tag == 0);
|
||||
e.tag = tag;
|
||||
e.flags |= VtEntryLocal;
|
||||
vtentrypack(&e, b->data, f->source->offset % f->source->epb);
|
||||
}else
|
||||
memmove(b->data + (bn%(e.psize/VtScoreSize))*VtScoreSize, score, VtScoreSize);
|
||||
/* vtblockdirty(b); */
|
||||
vtblockput(b);
|
||||
vtfileunlock(s);
|
||||
fileunlock(f);
|
||||
return 0;
|
||||
|
||||
Err:
|
||||
if(s)
|
||||
vtfileunlock(s);
|
||||
fileunlock(f);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
vacfilesetsize(VacFile *f, uvlong size)
|
||||
{
|
||||
|
@ -713,8 +653,6 @@ filewrite(VacFile *f, void *buf, int cnt, vlong offset, char *uid)
|
|||
uchar *p;
|
||||
vlong eof;
|
||||
|
||||
if(0)fprint(2, "fileWrite: %s %d, %lld\n", f->dir.elem, cnt, offset);
|
||||
|
||||
if(filelock(f) < 0)
|
||||
return -1;
|
||||
|
||||
|
@ -1064,7 +1002,7 @@ vacfilemetaflush(VacFile *f, int rec)
|
|||
vtfree(kids);
|
||||
}
|
||||
|
||||
/* assumes metaLock is held */
|
||||
/* assumes metalock is held */
|
||||
static int
|
||||
filemetaflush2(VacFile *f, char *oelem)
|
||||
{
|
||||
|
@ -1097,15 +1035,14 @@ filemetaflush2(VacFile *f, char *oelem)
|
|||
if(mbsearch(&mb, oelem, &i, &me) < 0)
|
||||
goto Err;
|
||||
|
||||
n = vdsize(&f->dir);
|
||||
if(0)fprint(2, "old size %d new size %d\n", me.size, n);
|
||||
n = vdsize(&f->dir, VacDirVersion);
|
||||
|
||||
if(mbresize(&mb, &me, n) >= 0){
|
||||
/* fits in the block */
|
||||
mbdelete(&mb, i, &me);
|
||||
if(strcmp(f->dir.elem, oelem) != 0)
|
||||
mbsearch(&mb, f->dir.elem, &i, &me2);
|
||||
vdpack(&f->dir, &me);
|
||||
vdpack(&f->dir, &me, VacDirVersion);
|
||||
mbinsert(&mb, i, &me);
|
||||
mbpack(&mb);
|
||||
/* vtblockdirty(b); */
|
||||
|
@ -1126,19 +1063,17 @@ if(0)fprint(2, "old size %d new size %d\n", me.size, n);
|
|||
*/
|
||||
boff = filemetaalloc(fp, &f->dir, f->boff+1);
|
||||
if(boff == NilBlock){
|
||||
/* mbResize might have modified block */
|
||||
/* mbresize might have modified block */
|
||||
mbpack(&mb);
|
||||
/* vtblockdirty(b); */
|
||||
goto Err;
|
||||
}
|
||||
fprint(2, "fileMetaFlush moving entry from %ud -> %ud\n", f->boff, boff);
|
||||
f->boff = boff;
|
||||
|
||||
/* make sure deletion goes to disk after new entry */
|
||||
bb = vtfileblock(fp->msource, f->boff, VtORDWR);
|
||||
mbdelete(&mb, i, &me);
|
||||
mbpack(&mb);
|
||||
/* blockDependency(b, bb, -1, nil, nil); */
|
||||
vtblockput(bb);
|
||||
/* vtblockdirty(b); */
|
||||
vtblockput(b);
|
||||
|
@ -1522,6 +1457,16 @@ Return:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
vdeunread(VacDirEnum *vde)
|
||||
{
|
||||
if(vde->i > 0){
|
||||
vde->i--;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
vdeclose(VacDirEnum *vde)
|
||||
{
|
||||
|
@ -1555,7 +1500,7 @@ filemetaalloc(VacFile *f, VacDir *dir, u32int start)
|
|||
s = f->source;
|
||||
ms = f->msource;
|
||||
|
||||
n = vdsize(dir);
|
||||
n = vdsize(dir, VacDirVersion);
|
||||
nb = (vtfilegetsize(ms)+ms->dsize-1)/ms->dsize;
|
||||
b = nil;
|
||||
if(start > nb)
|
||||
|
@ -1584,9 +1529,8 @@ filemetaalloc(VacFile *f, VacDir *dir, u32int start)
|
|||
|
||||
p = mballoc(&mb, n);
|
||||
if(p == nil){
|
||||
/* mbAlloc might have changed block */
|
||||
/* mballoc might have changed block */
|
||||
mbpack(&mb);
|
||||
/* vtblockdirty(b); */
|
||||
werrstr(EBadMeta);
|
||||
goto Err;
|
||||
}
|
||||
|
@ -1595,29 +1539,10 @@ filemetaalloc(VacFile *f, VacDir *dir, u32int start)
|
|||
assert(me.p == nil);
|
||||
me.p = p;
|
||||
me.size = n;
|
||||
vdpack(dir, &me);
|
||||
vdpack(dir, &me, VacDirVersion);
|
||||
mbinsert(&mb, i, &me);
|
||||
mbpack(&mb);
|
||||
|
||||
#ifdef notdef /* XXX */
|
||||
/* meta block depends on super block for qid ... */
|
||||
bb = cacheLocal(b->c, PartSuper, 0, VtOREAD);
|
||||
blockDependency(b, bb, -1, nil, nil);
|
||||
vtblockput(bb);
|
||||
|
||||
/* ... and one or two dir entries */
|
||||
epb = s->dsize/VtEntrySize;
|
||||
bb = vtfileblock(s, dir->entry/epb, VtOREAD);
|
||||
blockDependency(b, bb, -1, nil, nil);
|
||||
vtblockput(bb);
|
||||
if(dir->mode & ModeDir){
|
||||
bb = sourceBlock(s, dir->mentry/epb, VtOREAD);
|
||||
blockDependency(b, bb, -1, nil, nil);
|
||||
vtblockput(bb);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* vtblockdirty(b); */
|
||||
vtblockput(b);
|
||||
return bo;
|
||||
Err:
|
||||
|
@ -1676,7 +1601,7 @@ fileunlock(VacFile *f)
|
|||
|
||||
/*
|
||||
* f->source and f->msource must NOT be locked.
|
||||
* fileMetaFlush locks the fileMeta and then the source (in fileMetaFlush2).
|
||||
* vacfilemetaflush locks the filemeta and then the source (in filemetaflush2).
|
||||
* We have to respect that ordering.
|
||||
*/
|
||||
static void
|
||||
|
@ -1736,130 +1661,3 @@ filewaccess(VacFile* f, char *mid)
|
|||
*/
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
markCopied(Block *b)
|
||||
{
|
||||
VtBlock *lb;
|
||||
Label l;
|
||||
|
||||
if(globalToLocal(b->score) == NilBlock)
|
||||
return;
|
||||
|
||||
if(!(b->l.state & BsCopied)){
|
||||
/*
|
||||
* We need to record that there are now pointers in
|
||||
* b that are not unique to b. We do this by marking
|
||||
* b as copied. Since we don't return the label block,
|
||||
* the caller can't get the dependencies right. So we have
|
||||
* to flush the block ourselves. This is a rare occurrence.
|
||||
*/
|
||||
l = b->l;
|
||||
l.state |= BsCopied;
|
||||
lb = _blockSetLabel(b, &l);
|
||||
WriteAgain:
|
||||
while(!blockWrite(lb)){
|
||||
fprint(2, "getEntry: could not write label block\n");
|
||||
sleep(10*1000);
|
||||
}
|
||||
while(lb->iostate != BioClean && lb->iostate != BioDirty){
|
||||
assert(lb->iostate == BioWriting);
|
||||
vtSleep(lb->ioready);
|
||||
}
|
||||
if(lb->iostate == BioDirty)
|
||||
goto WriteAgain;
|
||||
vtblockput(lb);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
getEntry(VtFile *r, Entry *e, int mark)
|
||||
{
|
||||
Block *b;
|
||||
|
||||
if(r == nil){
|
||||
memset(&e, 0, sizeof e);
|
||||
return 1;
|
||||
}
|
||||
|
||||
b = cacheGlobal(r->fs->cache, r->score, BtDir, r->tag, VtOREAD);
|
||||
if(b == nil)
|
||||
return 0;
|
||||
if(!entryUnpack(e, b->data, r->offset % r->epb)){
|
||||
vtblockput(b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(mark)
|
||||
markCopied(b);
|
||||
vtblockput(b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
setEntry(Source *r, Entry *e)
|
||||
{
|
||||
Block *b;
|
||||
Entry oe;
|
||||
|
||||
b = cacheGlobal(r->fs->cache, r->score, BtDir, r->tag, VtORDWR);
|
||||
if(0) fprint(2, "setEntry: b %#ux %d score=%V\n", b->addr, r->offset % r->epb, e->score);
|
||||
if(b == nil)
|
||||
return 0;
|
||||
if(!entryUnpack(&oe, b->data, r->offset % r->epb)){
|
||||
vtblockput(b);
|
||||
return 0;
|
||||
}
|
||||
e->gen = oe.gen;
|
||||
entryPack(e, b->data, r->offset % r->epb);
|
||||
|
||||
/* BUG b should depend on the entry pointer */
|
||||
|
||||
markCopied(b);
|
||||
/* vtblockdirty(b); */
|
||||
vtblockput(b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* assumes hold elk */
|
||||
int
|
||||
fileSnapshot(VacFile *dst, VacFile *src, u32int epoch, int doarchive)
|
||||
{
|
||||
Entry e, ee;
|
||||
|
||||
/* add link to snapshot */
|
||||
if(!getEntry(src->source, &e, 1) || !getEntry(src->msource, &ee, 1))
|
||||
return 0;
|
||||
|
||||
e.snap = epoch;
|
||||
e.archive = doarchive;
|
||||
ee.snap = epoch;
|
||||
ee.archive = doarchive;
|
||||
|
||||
if(!setEntry(dst->source, &e) || !setEntry(dst->msource, &ee))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
fileGetSources(VacFile *f, Entry *e, Entry *ee, int mark)
|
||||
{
|
||||
if(!getEntry(f->source, e, mark)
|
||||
|| !getEntry(f->msource, ee, mark))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
fileWalkSources(VacFile *f)
|
||||
{
|
||||
if(f->mode == VtOREAD)
|
||||
return 1;
|
||||
if(!sourceLock2(f->source, f->msource, VtORDWR))
|
||||
return 0;
|
||||
vtfileunlock(f->source);
|
||||
vtfileunlock(f->msource);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,9 +8,13 @@ int meunpack(MetaEntry*, MetaBlock *mb, int i);
|
|||
int mecmp(MetaEntry*, char *s);
|
||||
int mecmpnew(MetaEntry*, char *s);
|
||||
|
||||
int vdsize(VacDir *dir);
|
||||
enum {
|
||||
VacDirVersion = 8,
|
||||
FossilDirVersion = 9,
|
||||
};
|
||||
int vdsize(VacDir *dir, int);
|
||||
int vdunpack(VacDir *dir, MetaEntry*);
|
||||
void vdpack(VacDir *dir, MetaEntry*);
|
||||
void vdpack(VacDir *dir, MetaEntry*, int);
|
||||
|
||||
VacFile *_vacfileroot(VacFs *fs, VtFile *file);
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ HFILES=\
|
|||
dat.h\
|
||||
fns.h\
|
||||
|
||||
TARG=vac vacfs # vtdump
|
||||
TARG=vac vacfs unvac # vtdump
|
||||
|
||||
default:V: all
|
||||
|
||||
|
|
|
@ -200,7 +200,7 @@ if(0)print("eo = %d en = %d\n", eo, en);
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* assumes a small amount of checking has been done in mbEntry */
|
||||
/* assumes a small amount of checking has been done in mbentry */
|
||||
int
|
||||
mecmp(MetaEntry *me, char *s)
|
||||
{
|
||||
|
@ -372,18 +372,17 @@ mballoc(MetaBlock *mb, int n)
|
|||
}
|
||||
|
||||
int
|
||||
vdsize(VacDir *dir)
|
||||
vdsize(VacDir *dir, int version)
|
||||
{
|
||||
int n;
|
||||
|
||||
/* constant part */
|
||||
if(version < 8 || version > 9)
|
||||
sysfatal("bad version %d in vdpack", version);
|
||||
|
||||
/* constant part */
|
||||
n = 4 + /* magic */
|
||||
2 + /* version */
|
||||
4 + /* entry */
|
||||
4 + /* guid */
|
||||
4 + /* mentry */
|
||||
4 + /* mgen */
|
||||
8 + /* qid */
|
||||
4 + /* mtime */
|
||||
4 + /* mcount */
|
||||
|
@ -392,6 +391,13 @@ vdsize(VacDir *dir)
|
|||
4 + /* mode */
|
||||
0;
|
||||
|
||||
if(version == 9){
|
||||
n += 4 + /* gen */
|
||||
4 + /* mentry */
|
||||
4 + /* mgen */
|
||||
0;
|
||||
}
|
||||
|
||||
/* strings */
|
||||
n += 2 + strlen(dir->elem);
|
||||
n += 2 + strlen(dir->uid);
|
||||
|
@ -399,35 +405,53 @@ vdsize(VacDir *dir)
|
|||
n += 2 + strlen(dir->mid);
|
||||
|
||||
/* optional sections */
|
||||
if(version < 9 && dir->plan9) {
|
||||
n += 3 + /* option header */
|
||||
8 + /* path */
|
||||
4; /* version */
|
||||
}
|
||||
if(dir->qidspace) {
|
||||
n += 3 + /* option header */
|
||||
8 + /* qid offset */
|
||||
8; /* qid max */
|
||||
}
|
||||
if(version < 9 && dir->gen) {
|
||||
n += 3 + /* option header */
|
||||
4; /* gen */
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
vdpack(VacDir *dir, MetaEntry *me)
|
||||
vdpack(VacDir *dir, MetaEntry *me, int version)
|
||||
{
|
||||
uchar *p;
|
||||
ulong t32;
|
||||
|
||||
if(version < 8 || version > 9)
|
||||
sysfatal("bad version %d in vdpack", version);
|
||||
|
||||
p = me->p;
|
||||
|
||||
U32PUT(p, DirMagic);
|
||||
U16PUT(p+4, 9); /* version */
|
||||
U16PUT(p+4, version); /* version */
|
||||
p += 6;
|
||||
|
||||
p += stringpack(dir->elem, p);
|
||||
|
||||
U32PUT(p, dir->entry);
|
||||
U32PUT(p+4, dir->gen);
|
||||
U32PUT(p+8, dir->mentry);
|
||||
U32PUT(p+12, dir->mgen);
|
||||
U64PUT(p+16, dir->qid, t32);
|
||||
p += 24;
|
||||
p += 4;
|
||||
|
||||
if(version == 9){
|
||||
U32PUT(p, dir->gen);
|
||||
U32PUT(p+4, dir->mentry);
|
||||
U32PUT(p+8, dir->mgen);
|
||||
p += 12;
|
||||
}
|
||||
|
||||
U64PUT(p, dir->qid, t32);
|
||||
p += 8;
|
||||
|
||||
p += stringpack(dir->uid, p);
|
||||
p += stringpack(dir->gid, p);
|
||||
|
@ -439,6 +463,15 @@ vdpack(VacDir *dir, MetaEntry *me)
|
|||
U32PUT(p+12, dir->atime);
|
||||
U32PUT(p+16, dir->mode);
|
||||
p += 5*4;
|
||||
|
||||
if(dir->plan9 && version < 9) {
|
||||
U8PUT(p, DirPlan9Entry);
|
||||
U16PUT(p+1, 8+4);
|
||||
p += 3;
|
||||
U64PUT(p, dir->p9path, t32);
|
||||
U32PUT(p+8, dir->p9version);
|
||||
p += 12;
|
||||
}
|
||||
|
||||
if(dir->qidspace) {
|
||||
U8PUT(p, DirQidSpaceEntry);
|
||||
|
@ -446,12 +479,20 @@ vdpack(VacDir *dir, MetaEntry *me)
|
|||
p += 3;
|
||||
U64PUT(p, dir->qidoffset, t32);
|
||||
U64PUT(p+8, dir->qidmax, t32);
|
||||
p += 16;
|
||||
}
|
||||
|
||||
if(dir->gen && version < 9) {
|
||||
U8PUT(p, DirGenEntry);
|
||||
U16PUT(p+1, 4);
|
||||
p += 3;
|
||||
U32PUT(p, dir->gen);
|
||||
p += 4;
|
||||
}
|
||||
|
||||
assert(p == me->p + me->size);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
vdunpack(VacDir *dir, MetaEntry *me)
|
||||
{
|
||||
|
@ -463,14 +504,12 @@ vdunpack(VacDir *dir, MetaEntry *me)
|
|||
|
||||
memset(dir, 0, sizeof(VacDir));
|
||||
|
||||
if(0)print("vdUnpack\n");
|
||||
/* magic */
|
||||
if(n < 4 || U32GET(p) != DirMagic)
|
||||
goto Err;
|
||||
p += 4;
|
||||
n -= 4;
|
||||
|
||||
if(0)print("vdUnpack: got magic\n");
|
||||
/* version */
|
||||
if(n < 2)
|
||||
goto Err;
|
||||
|
@ -480,14 +519,10 @@ if(0)print("vdUnpack: got magic\n");
|
|||
p += 2;
|
||||
n -= 2;
|
||||
|
||||
if(0)print("vdUnpack: got version\n");
|
||||
|
||||
/* elem */
|
||||
if(stringunpack(&dir->elem, &p, &n) < 0)
|
||||
goto Err;
|
||||
|
||||
if(0)print("vdUnpack: got elem\n");
|
||||
|
||||
/* entry */
|
||||
if(n < 4)
|
||||
goto Err;
|
||||
|
@ -495,8 +530,6 @@ if(0)print("vdUnpack: got elem\n");
|
|||
p += 4;
|
||||
n -= 4;
|
||||
|
||||
if(0)print("vdUnpack: got entry\n");
|
||||
|
||||
if(version < 9) {
|
||||
dir->gen = 0;
|
||||
dir->mentry = dir->entry+1;
|
||||
|
@ -511,8 +544,6 @@ if(0)print("vdUnpack: got entry\n");
|
|||
n -= 3*4;
|
||||
}
|
||||
|
||||
if(0)print("vdUnpack: got gen etc\n");
|
||||
|
||||
/* size is gotten from DirEntry */
|
||||
|
||||
/* qid */
|
||||
|
@ -522,7 +553,6 @@ if(0)print("vdUnpack: got gen etc\n");
|
|||
p += 8;
|
||||
n -= 8;
|
||||
|
||||
if(0)print("vdUnpack: got qid\n");
|
||||
/* skip replacement */
|
||||
if(version == 7) {
|
||||
if(n < VtScoreSize)
|
||||
|
@ -543,7 +573,6 @@ if(0)print("vdUnpack: got qid\n");
|
|||
if(stringunpack(&dir->mid, &p, &n) < 0)
|
||||
goto Err;
|
||||
|
||||
if(0)print("vdUnpack: got ids\n");
|
||||
if(n < 5*4)
|
||||
goto Err;
|
||||
dir->mtime = U32GET(p);
|
||||
|
@ -554,7 +583,6 @@ if(0)print("vdUnpack: got ids\n");
|
|||
p += 5*4;
|
||||
n -= 5*4;
|
||||
|
||||
if(0)print("vdUnpack: got times\n");
|
||||
/* optional meta data */
|
||||
while(n > 0) {
|
||||
if(n < 3)
|
||||
|
@ -594,15 +622,12 @@ if(0)print("vdUnpack: got times\n");
|
|||
p += nn;
|
||||
n -= nn;
|
||||
}
|
||||
if(0)print("vdUnpack: got options\n");
|
||||
|
||||
if(p != me->p + me->size)
|
||||
goto Err;
|
||||
|
||||
if(0)print("vdUnpack: correct size\n");
|
||||
return 0;
|
||||
Err:
|
||||
if(0)print("vdUnpack: XXXXXXXXXXXX EbadMeta\n");
|
||||
werrstr(EBadMeta);
|
||||
vdcleanup(dir);
|
||||
return -1;
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
#include "stdinc.h"
|
||||
|
||||
enum {
|
||||
Nblock = 300000,
|
||||
BlockSize = 8*1024
|
||||
};
|
||||
|
||||
uchar data[Nblock*VtScoreSize];
|
||||
int rflag;
|
||||
int nblock = 10000;
|
||||
int perm[Nblock];
|
||||
|
||||
void
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
VtSession *z;
|
||||
int i, j, t;
|
||||
int start;
|
||||
uchar buf[BlockSize];
|
||||
|
||||
srand(time(0));
|
||||
|
||||
ARGBEGIN{
|
||||
case 'r':
|
||||
rflag++;
|
||||
break;
|
||||
case 'n':
|
||||
nblock = atoi(ARGF());
|
||||
break;
|
||||
}ARGEND
|
||||
|
||||
for(i=0; i<nblock; i++)
|
||||
perm[i] = i;
|
||||
|
||||
if(rflag) {
|
||||
for(i=0; i<nblock; i++) {
|
||||
j = nrand(nblock);
|
||||
t = perm[j];
|
||||
perm[j] = perm[i];
|
||||
perm[i] = t;
|
||||
}
|
||||
}
|
||||
|
||||
if(readn(0, data, VtScoreSize*nblock) < VtScoreSize*nblock)
|
||||
sysfatal("read failed: %r");
|
||||
|
||||
vtAttach();
|
||||
|
||||
z = vtDial("iolaire2");
|
||||
if(z == nil)
|
||||
sysfatal("cound not connect to venti");
|
||||
if(!vtConnect(z, 0))
|
||||
vtFatal("vtConnect: %s", vtGetError());
|
||||
|
||||
print("starting\n");
|
||||
|
||||
start = times(0);
|
||||
|
||||
if(rflag && nblock > 10000)
|
||||
nblock = 10000;
|
||||
|
||||
for(i=0; i<nblock; i++) {
|
||||
if(vtRead(z, data+perm[i]*VtScoreSize, VtDataType, buf, BlockSize) < 0)
|
||||
vtFatal("vtRead failed: %d: %s", i, vtGetError());
|
||||
}
|
||||
|
||||
print("time = %f\n", (times(0) - start)*0.001);
|
||||
|
||||
vtClose(z);
|
||||
vtDetach();
|
||||
}
|
|
@ -1,302 +0,0 @@
|
|||
#include "stdinc.h"
|
||||
#include <bio.h>
|
||||
#include "vac.h"
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "error.h"
|
||||
|
||||
int num = 1000;
|
||||
int length = 20*1024;
|
||||
int block= 1024;
|
||||
int bush = 4;
|
||||
int iter = 10000;
|
||||
Biobuf *bout;
|
||||
int maxdepth;
|
||||
|
||||
Source *mkroot(Cache*);
|
||||
void new(Source*, int trace, int);
|
||||
int delete(Source*);
|
||||
void dump(Source*, int indent, ulong nentry);
|
||||
void dumpone(Source *s);
|
||||
int count(Source *s, int);
|
||||
void stats(Source *s);
|
||||
|
||||
void
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
Cache *c;
|
||||
char *host = nil;
|
||||
VtSession *z;
|
||||
int csize = 10000;
|
||||
Source *r;
|
||||
ulong t;
|
||||
|
||||
t = time(0);
|
||||
fprint(1, "time = %lud\n", t);
|
||||
|
||||
srand(t);
|
||||
|
||||
ARGBEGIN{
|
||||
case 'i':
|
||||
iter = atoi(ARGF());
|
||||
break;
|
||||
case 'n':
|
||||
num = atoi(ARGF());
|
||||
break;
|
||||
case 'l':
|
||||
length = atoi(ARGF());
|
||||
break;
|
||||
case 'b':
|
||||
block = atoi(ARGF());
|
||||
break;
|
||||
case 'h':
|
||||
host = ARGF();
|
||||
break;
|
||||
case 'u':
|
||||
bush = atoi(ARGF());
|
||||
break;
|
||||
case 'c':
|
||||
csize = atoi(ARGF());
|
||||
break;
|
||||
}ARGEND;
|
||||
|
||||
vtAttach();
|
||||
|
||||
bout = vtMemAllocZ(sizeof(Biobuf));
|
||||
Binit(bout, 1, OWRITE);
|
||||
|
||||
fmtinstall('V', vtScoreFmt);
|
||||
fmtinstall('R', vtErrFmt);
|
||||
|
||||
z = vtDial(host);
|
||||
if(z == nil)
|
||||
vtFatal("could not connect to server: %s", vtGetError());
|
||||
|
||||
if(!vtConnect(z, 0))
|
||||
sysfatal("vtConnect: %r");
|
||||
|
||||
c = cacheAlloc(z, block, csize);
|
||||
r = mkroot(c);
|
||||
for(i=0; i<num; i++)
|
||||
new(r, 0, 0);
|
||||
|
||||
for(i=0; i<iter; i++) {
|
||||
if(i % 10000 == 0)
|
||||
stats(r);
|
||||
new(r, 0, 0);
|
||||
delete(r);
|
||||
}
|
||||
|
||||
fprint(2, "count = %d top = %lud\n", count(r, 0), sourceGetDirSize(r));
|
||||
/* cacheCheck(c); */
|
||||
fprint(2, "deleting\n");
|
||||
for(i=0; i<num; i++)
|
||||
delete(r);
|
||||
|
||||
/* dump(r, 0, 0); */
|
||||
|
||||
lumpDecRef(r->lump, 0);
|
||||
sourceRemove(r);
|
||||
cacheCheck(c);
|
||||
|
||||
vtClose(z);
|
||||
vtDetach();
|
||||
|
||||
exits(0);
|
||||
}
|
||||
|
||||
|
||||
Source *
|
||||
mkroot(Cache *c)
|
||||
{
|
||||
Lump *u;
|
||||
VtEntry *dir;
|
||||
Source *r;
|
||||
|
||||
u = cacheAllocLump(c, VtDirType, cacheGetBlockSize(c), 1);
|
||||
dir = (VtEntry*)u->data;
|
||||
vtPutUint16(dir->psize, cacheGetBlockSize(c));
|
||||
vtPutUint16(dir->dsize, cacheGetBlockSize(c));
|
||||
dir->flag = VtEntryActive|VtEntryDir;
|
||||
memmove(dir->score, vtZeroScore, VtScoreSize);
|
||||
|
||||
r = sourceAlloc(c, u, 0, 0);
|
||||
vtUnlock(u->lk);
|
||||
if(r == nil)
|
||||
sysfatal("could not create root source: %r");
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
new(Source *s, int trace, int depth)
|
||||
{
|
||||
int i, n;
|
||||
Source *ss;
|
||||
|
||||
if(depth > maxdepth)
|
||||
maxdepth = depth;
|
||||
|
||||
n = sourceGetDirSize(s);
|
||||
for(i=0; i<n; i++) {
|
||||
ss = sourceOpen(s, nrand(n), 0);
|
||||
if(ss == nil)
|
||||
continue;
|
||||
if(ss->dir && frand() < 1./bush) {
|
||||
if(trace) {
|
||||
int j;
|
||||
for(j=0; j<trace; j++)
|
||||
Bprint(bout, " ");
|
||||
Bprint(bout, "decend %d\n", i);
|
||||
}
|
||||
new(ss, trace?trace+1:0, depth+1);
|
||||
sourceFree(ss);
|
||||
return;
|
||||
}
|
||||
sourceFree(ss);
|
||||
}
|
||||
ss = sourceCreate(s, s->psize, s->dsize, 1+frand()>.5, 0);
|
||||
if(ss == nil)
|
||||
fprint(2, "could not create directory: %r\n");
|
||||
if(trace) {
|
||||
int j;
|
||||
for(j=1; j<trace; j++)
|
||||
Bprint(bout, " ");
|
||||
Bprint(bout, "create %d %V\n", ss->entry, ss->lump->score);
|
||||
}
|
||||
sourceFree(ss);
|
||||
}
|
||||
|
||||
int
|
||||
delete(Source *s)
|
||||
{
|
||||
int i, n;
|
||||
Source *ss;
|
||||
|
||||
assert(s->dir);
|
||||
|
||||
n = sourceGetDirSize(s);
|
||||
/* check if empty */
|
||||
for(i=0; i<n; i++) {
|
||||
ss = sourceOpen(s, i, 1);
|
||||
if(ss != nil) {
|
||||
sourceFree(ss);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i == n)
|
||||
return 0;
|
||||
|
||||
for(;;) {
|
||||
ss = sourceOpen(s, nrand(n), 0);
|
||||
if(ss == nil)
|
||||
continue;
|
||||
if(ss->dir && delete(ss)) {
|
||||
sourceFree(ss);
|
||||
return 1;
|
||||
}
|
||||
if(1)
|
||||
break;
|
||||
sourceFree(ss);
|
||||
}
|
||||
|
||||
|
||||
sourceRemove(ss);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
dumpone(Source *s)
|
||||
{
|
||||
ulong i, n;
|
||||
Source *ss;
|
||||
|
||||
Bprint(bout, "gen %4lud depth %d %V", s->gen, s->depth, s->lump->score);
|
||||
if(!s->dir) {
|
||||
Bprint(bout, " data size: %llud\n", s->size);
|
||||
return;
|
||||
}
|
||||
n = sourceGetDirSize(s);
|
||||
Bprint(bout, " dir size: %lud\n", n);
|
||||
for(i=0; i<n; i++) {
|
||||
ss = sourceOpen(s, i, 1);
|
||||
if(ss == nil) {
|
||||
fprint(2, "%lud: %r\n", i);
|
||||
continue;
|
||||
}
|
||||
Bprint(bout, "\t%lud %d %llud %V\n", i, ss->dir, ss->size, ss->lump->score);
|
||||
sourceFree(ss);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dump(Source *s, int ident, ulong entry)
|
||||
{
|
||||
ulong i, n;
|
||||
Source *ss;
|
||||
|
||||
for(i=0; i<ident; i++)
|
||||
Bprint(bout, " ");
|
||||
Bprint(bout, "%4lud: gen %4lud depth %d", entry, s->gen, s->depth);
|
||||
if(!s->dir) {
|
||||
Bprint(bout, " data size: %llud\n", s->size);
|
||||
return;
|
||||
}
|
||||
n = sourceGetDirSize(s);
|
||||
Bprint(bout, " dir size: %lud\n", n);
|
||||
for(i=0; i<n; i++) {
|
||||
ss = sourceOpen(s, i, 1);
|
||||
if(ss == nil)
|
||||
continue;
|
||||
dump(ss, ident+1, i);
|
||||
sourceFree(ss);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
count(Source *s, int rec)
|
||||
{
|
||||
ulong i, n;
|
||||
int c;
|
||||
Source *ss;
|
||||
|
||||
if(!s->dir)
|
||||
return 0;
|
||||
n = sourceGetDirSize(s);
|
||||
c = 0;
|
||||
for(i=0; i<n; i++) {
|
||||
ss = sourceOpen(s, i, 1);
|
||||
if(ss == nil)
|
||||
continue;
|
||||
if(rec)
|
||||
c += count(ss, rec);
|
||||
c++;
|
||||
sourceFree(ss);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
stats(Source *s)
|
||||
{
|
||||
int n, i, c, cc, max;
|
||||
Source *ss;
|
||||
|
||||
cc = 0;
|
||||
max = 0;
|
||||
n = sourceGetDirSize(s);
|
||||
for(i=0; i<n; i++) {
|
||||
ss = sourceOpen(s, i, 1);
|
||||
if(ss == nil)
|
||||
continue;
|
||||
cc++;
|
||||
c = count(ss, 1);
|
||||
if(c > max)
|
||||
max = c;
|
||||
sourceFree(ss);
|
||||
}
|
||||
fprint(2, "count = %d top = %d depth=%d maxcount %d\n", cc, n, maxdepth, max);
|
||||
}
|
293
src/cmd/vac/unvac.c
Normal file
293
src/cmd/vac/unvac.c
Normal file
|
@ -0,0 +1,293 @@
|
|||
#include "stdinc.h"
|
||||
#include <auth.h>
|
||||
#include <fcall.h>
|
||||
#include <thread.h>
|
||||
#include "vac.h"
|
||||
|
||||
VacFs *fs;
|
||||
int tostdout;
|
||||
int nwant;
|
||||
char **want;
|
||||
int *found;
|
||||
int chatty;
|
||||
VtConn *conn;
|
||||
int errors;
|
||||
int settimes;
|
||||
int table;
|
||||
|
||||
int mtimefmt(Fmt*);
|
||||
void unvac(VacFile*, char*, VacDir*);
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
fprint(2, "usage: unvac [-TVctv] [-h host] file.vac [file ...]\n");
|
||||
threadexitsall("usage");
|
||||
}
|
||||
|
||||
void
|
||||
threadmain(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
char *host;
|
||||
VacFile *f;
|
||||
|
||||
fmtinstall('H', encodefmt);
|
||||
fmtinstall('V', vtscorefmt);
|
||||
fmtinstall('F', vtfcallfmt);
|
||||
fmtinstall('T', mtimefmt);
|
||||
fmtinstall('M', dirmodefmt);
|
||||
|
||||
host = nil;
|
||||
ARGBEGIN{
|
||||
case 'T':
|
||||
settimes = 1;
|
||||
break;
|
||||
case 'V':
|
||||
chattyventi = 1;
|
||||
break;
|
||||
case 'c':
|
||||
tostdout++;
|
||||
break;
|
||||
case 'h':
|
||||
host = EARGF(usage());
|
||||
break;
|
||||
case 't':
|
||||
table++;
|
||||
break;
|
||||
case 'v':
|
||||
chatty++;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}ARGEND
|
||||
|
||||
if(argc < 1)
|
||||
usage();
|
||||
|
||||
conn = vtdial(host);
|
||||
if(conn == nil)
|
||||
sysfatal("could not connect to server: %r");
|
||||
|
||||
if(vtconnect(conn) < 0)
|
||||
sysfatal("vtconnect: %r");
|
||||
|
||||
fs = vacfsopen(conn, argv[0], VtOREAD, 128);
|
||||
if(fs == nil)
|
||||
sysfatal("vacfsopen: %r");
|
||||
|
||||
nwant = argc-1;
|
||||
want = argv+1;
|
||||
found = vtmallocz(nwant*sizeof found[0]);
|
||||
|
||||
if((f = vacfsgetroot(fs)) == nil)
|
||||
sysfatal("vacfsgetroot: %r");
|
||||
|
||||
unvac(f, nil, nil);
|
||||
for(i=0; i<nwant; i++){
|
||||
if(want[i] && !found[i]){
|
||||
fprint(2, "warning: didn't find %s\n", want[i]);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
if(errors)
|
||||
threadexitsall("errors");
|
||||
threadexitsall(0);
|
||||
}
|
||||
|
||||
int
|
||||
writen(int fd, char *buf, int n)
|
||||
{
|
||||
int m;
|
||||
int oldn;
|
||||
|
||||
oldn = n;
|
||||
while(n > 0){
|
||||
m = write(fd, buf, n);
|
||||
if(m <= 0)
|
||||
return -1;
|
||||
buf += m;
|
||||
n -= m;
|
||||
}
|
||||
return oldn;
|
||||
}
|
||||
|
||||
int
|
||||
wantfile(char *name)
|
||||
{
|
||||
int i, namelen, n;
|
||||
|
||||
if(nwant == 0)
|
||||
return 1;
|
||||
|
||||
namelen = strlen(name);
|
||||
for(i=0; i<nwant; i++){
|
||||
if(want[i] == nil)
|
||||
continue;
|
||||
n = strlen(want[i]);
|
||||
if(n < namelen && name[n] == '/' && memcmp(name, want[i], n) == 0)
|
||||
return 1;
|
||||
if(namelen < n && want[i][namelen] == '/' && memcmp(want[i], name, n) == 0)
|
||||
return 1;
|
||||
if(n == namelen && memcmp(name, want[i], n) == 0){
|
||||
found[i] = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
unvac(VacFile *f, char *name, VacDir *vdir)
|
||||
{
|
||||
static char buf[65536];
|
||||
int fd, mode, n, mode9;
|
||||
char *newname;
|
||||
char *what;
|
||||
vlong off;
|
||||
Dir d, *dp;
|
||||
VacDirEnum *vde;
|
||||
VacDir newvdir;
|
||||
VacFile *newf;
|
||||
|
||||
if(vdir)
|
||||
mode = vdir->mode;
|
||||
else
|
||||
mode = vacfilegetmode(f);
|
||||
|
||||
if(vdir){
|
||||
if(table){
|
||||
if(chatty){
|
||||
mode9 = vdir->mode&0777;
|
||||
if(mode&ModeDir)
|
||||
mode9 |= DMDIR;
|
||||
if(mode&ModeLink)
|
||||
mode9 |= DMSYMLINK;
|
||||
if(mode&ModeAppend)
|
||||
mode9 |= DMAPPEND;
|
||||
if(mode&ModeExclusive)
|
||||
mode9 |= DMEXCL;
|
||||
if(mode&ModeNamedPipe)
|
||||
mode9 |= DMNAMEDPIPE;
|
||||
if(mode&ModeSetUid)
|
||||
mode9 |= DMSETUID;
|
||||
if(mode&ModeSetGid)
|
||||
mode9 |= DMSETGID;
|
||||
if(mode&ModeDevice)
|
||||
mode9 |= DMDEVICE;
|
||||
print("%M %-10s %-10s %11lld %T %s\n",
|
||||
mode9, vdir->uid, vdir->gid, vdir->size,
|
||||
vdir->mtime, name);
|
||||
}else
|
||||
print("%s%s\n", name, (mode&ModeDir) ? "/" : "");
|
||||
}
|
||||
else if(chatty)
|
||||
fprint(2, "%s%s\n", name, (mode&ModeDir) ? "/" : "");
|
||||
}
|
||||
|
||||
if(mode&(ModeDevice|ModeLink|ModeNamedPipe|ModeExclusive)){
|
||||
if(table)
|
||||
return;
|
||||
if(mode&ModeDevice)
|
||||
what = "device";
|
||||
else if(mode&ModeLink)
|
||||
what = "link";
|
||||
else if(mode&ModeNamedPipe)
|
||||
what = "named pipe";
|
||||
else if(mode&ModeExclusive)
|
||||
what = "lock";
|
||||
else
|
||||
what = "unknown type of file";
|
||||
fprint(2, "warning: ignoring %s %s\n", what, name);
|
||||
return;
|
||||
}
|
||||
|
||||
if(mode&ModeDir){
|
||||
if((vde = vdeopen(f)) == nil){
|
||||
fprint(2, "vdeopen %s: %r", name);
|
||||
errors++;
|
||||
return;
|
||||
}
|
||||
if(!table && !tostdout && vdir){
|
||||
// create directory
|
||||
if((dp = dirstat(name)) == nil){
|
||||
if((fd = create(name, OREAD, DMDIR|(mode&0777))) < 0){
|
||||
fprint(2, "mkdir %s: %r\n", name);
|
||||
vdeclose(vde);
|
||||
}
|
||||
close(fd);
|
||||
}else{
|
||||
if(!(dp->mode&DMDIR)){
|
||||
fprint(2, "%s already exists and is not a directory\n", name);
|
||||
errors++;
|
||||
free(dp);
|
||||
vdeclose(vde);
|
||||
return;
|
||||
}
|
||||
free(dp);
|
||||
}
|
||||
}
|
||||
while(vderead(vde, &newvdir) > 0){
|
||||
if(name == nil)
|
||||
newname = newvdir.elem;
|
||||
else
|
||||
newname = smprint("%s/%s", name, newvdir.elem);
|
||||
if(wantfile(newname)){
|
||||
if((newf = vacfilewalk(f, newvdir.elem)) == nil){
|
||||
fprint(2, "walk %s: %r\n", name);
|
||||
errors++;
|
||||
}else if(newf == f){
|
||||
fprint(2, "walk loop: %s\n", newname);
|
||||
vacfiledecref(newf);
|
||||
}else{
|
||||
unvac(newf, newname, &newvdir);
|
||||
vacfiledecref(newf);
|
||||
}
|
||||
}
|
||||
if(newname != newvdir.elem)
|
||||
free(newname);
|
||||
vdcleanup(&newvdir);
|
||||
}
|
||||
vdeclose(vde);
|
||||
}else{
|
||||
if(!table){
|
||||
if(tostdout)
|
||||
fd = dup(1, -1);
|
||||
else if((fd = create(name, OWRITE, mode&0777)) < 0){
|
||||
fprint(2, "create %s: %r\n", name);
|
||||
errors++;
|
||||
return;
|
||||
}
|
||||
off = 0;
|
||||
while((n = vacfileread(f, buf, sizeof buf, off)) > 0){
|
||||
if(writen(fd, buf, n) != n){
|
||||
fprint(2, "write %s: %r\n", name);
|
||||
errors++;
|
||||
close(fd);
|
||||
remove(name);
|
||||
return;
|
||||
}
|
||||
off += n;
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
if(vdir && settimes && !tostdout){
|
||||
nulldir(&d);
|
||||
d.mtime = vdir->mtime;
|
||||
if(dirwstat(name, &d) < 0)
|
||||
fprint(2, "warning: setting mtime on %s: %r", name);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
mtimefmt(Fmt *f)
|
||||
{
|
||||
Tm *tm;
|
||||
|
||||
tm = localtime(va_arg(f->args, ulong));
|
||||
fmtprint(f, "%04d-%02d-%02d %02d:%02d",
|
||||
tm->year+1900, tm->mon+1, tm->mday,
|
||||
tm->hour, tm->min);
|
||||
return 0;
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
#include "stdinc.h"
|
||||
#include "vac.h"
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
|
||||
int
|
||||
vtGetUint16(uchar *p)
|
||||
{
|
||||
return (p[0]<<8)|p[1];
|
||||
}
|
||||
|
||||
ulong
|
||||
vtGetUint32(uchar *p)
|
||||
{
|
||||
return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
|
||||
}
|
||||
|
||||
uvlong
|
||||
vtGetUint48(uchar *p)
|
||||
{
|
||||
return ((uvlong)p[0]<<40)|((uvlong)p[1]<<32)|
|
||||
(p[2]<<24)|(p[3]<<16)|(p[4]<<8)|p[5];
|
||||
}
|
||||
|
||||
uvlong
|
||||
vtGetUint64(uchar *p)
|
||||
{
|
||||
return ((uvlong)p[0]<<56)|((uvlong)p[1]<<48)|((uvlong)p[2]<<40)|
|
||||
((uvlong)p[3]<<32)|(p[4]<<24)|(p[5]<<16)|(p[6]<<8)|p[7];
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vtPutUint16(uchar *p, int x)
|
||||
{
|
||||
p[0] = x>>8;
|
||||
p[1] = x;
|
||||
}
|
||||
|
||||
void
|
||||
vtPutUint32(uchar *p, ulong x)
|
||||
{
|
||||
p[0] = x>>24;
|
||||
p[1] = x>>16;
|
||||
p[2] = x>>8;
|
||||
p[3] = x;
|
||||
}
|
||||
|
||||
void
|
||||
vtPutUint48(uchar *p, uvlong x)
|
||||
{
|
||||
p[0] = x>>40;
|
||||
p[1] = x>>32;
|
||||
p[2] = x>>24;
|
||||
p[3] = x>>16;
|
||||
p[4] = x>>8;
|
||||
p[5] = x;
|
||||
}
|
||||
|
||||
void
|
||||
vtPutUint64(uchar *p, uvlong x)
|
||||
{
|
||||
p[0] = x>>56;
|
||||
p[1] = x>>48;
|
||||
p[2] = x>>40;
|
||||
p[3] = x>>32;
|
||||
p[4] = x>>24;
|
||||
p[5] = x>>16;
|
||||
p[6] = x>>8;
|
||||
p[7] = x;
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -5,7 +5,18 @@
|
|||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
|
||||
int mainstacksize = 128*1024;
|
||||
/*
|
||||
* We're between a rock and a hard place here.
|
||||
* The pw library (getpwnam, etc.) reads the
|
||||
* password and group files into an on-stack buffer,
|
||||
* so if you have some huge groups, you overflow
|
||||
* the stack. Because of this, the thread library turns
|
||||
* it off by default, so that dirstat returns "14571" instead of "rsc".
|
||||
* But for vac we want names. So cautiously turn the pwlibrary
|
||||
* back on (see threadmain) and make the main thread stack huge.
|
||||
*/
|
||||
extern int _p9usepwlibrary;
|
||||
int mainstacksize = 4*1024*1024;
|
||||
|
||||
typedef struct Sink Sink;
|
||||
typedef struct MetaSink MetaSink;
|
||||
|
@ -101,6 +112,8 @@ int nowrite;
|
|||
int merge;
|
||||
char *isi;
|
||||
|
||||
char **expandargv(char**);
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
@ -116,6 +129,9 @@ threadmain(int argc, char *argv[])
|
|||
char *host = nil;
|
||||
int statsflag = 0;
|
||||
|
||||
/* see comment above */
|
||||
_p9usepwlibrary = 1;
|
||||
|
||||
atexit(cleanup);
|
||||
|
||||
ARGBEGIN{
|
||||
|
@ -194,20 +210,71 @@ threadmain(int argc, char *argv[])
|
|||
|
||||
qsort(exclude, nexclude, sizeof(char*), strpcmp);
|
||||
|
||||
argv = expandargv(argv);
|
||||
|
||||
vac(z, argv);
|
||||
|
||||
if(vtsync(z) < 0)
|
||||
fprint(2, "warning: could not ask server to flush pending writes: %r\n");
|
||||
|
||||
if(statsflag)
|
||||
if(statsflag){
|
||||
fprint(2, "files %ld:%ld data %ld:%ld:%ld meta %ld\n", stats.file, stats.sfile,
|
||||
stats.data, stats.skip, stats.sdata, stats.meta);
|
||||
/*packetStats(); */
|
||||
dup(2, 1);
|
||||
packetstats();
|
||||
}
|
||||
vthangup(z);
|
||||
|
||||
threadexitsall(0);
|
||||
}
|
||||
|
||||
// Expand special directory names like / and . and .. into a list of their files.
|
||||
char**
|
||||
expandargv(char **argv)
|
||||
{
|
||||
char **nargv;
|
||||
int nargc;
|
||||
int i, n;
|
||||
Dir *d;
|
||||
int fd;
|
||||
char *s;
|
||||
|
||||
nargc = 0;
|
||||
nargv = nil;
|
||||
for(; *argv; argv++){
|
||||
cleanname(*argv);
|
||||
if(strcmp(*argv, "/") == 0 || strcmp(*argv, ".") == 0 || strcmp(*argv, "..") == 0
|
||||
|| (strlen(*argv) > 3 && strcmp(*argv+strlen(*argv)-3, "/..") == 0)){
|
||||
if((fd = open(*argv, OREAD)) < 0){
|
||||
warn("could not open %s: %r", *argv);
|
||||
continue;
|
||||
}
|
||||
n = dirreadall(fd, &d);
|
||||
close(fd);
|
||||
if(n < 0){
|
||||
warn("could not read %s: %r", *argv);
|
||||
continue;
|
||||
}
|
||||
nargv = vtrealloc(nargv, (nargc+n)*sizeof nargv[0]);
|
||||
for(i=0; i<n; i++){
|
||||
s = vtmalloc(strlen(*argv)+1+strlen(d[i].name)+1);
|
||||
strcpy(s, *argv);
|
||||
strcat(s, "/");
|
||||
strcat(s, d[i].name);
|
||||
cleanname(s);
|
||||
nargv[nargc++] = s;
|
||||
}
|
||||
free(d);
|
||||
continue;
|
||||
}
|
||||
nargv = vtrealloc(nargv, (nargc+1)*sizeof nargv[0]);
|
||||
nargv[nargc++] = *argv;
|
||||
}
|
||||
nargv = vtrealloc(nargv, (nargc+1)*sizeof nargv[0]);
|
||||
nargv[nargc] = nil;
|
||||
return nargv;
|
||||
}
|
||||
|
||||
static int
|
||||
strpcmp(const void *p0, const void *p1)
|
||||
{
|
||||
|
@ -353,7 +420,7 @@ vac(VtConn *z, char *argv[])
|
|||
|
||||
vtrootpack(&root, buf);
|
||||
if(vacwrite(z, score, VtRootType, buf, VtRootSize) < 0)
|
||||
sysfatal("vacWrite failed: %r");
|
||||
sysfatal("vacwrite: %r");
|
||||
|
||||
fprint(fd, "vac:%V\n", score);
|
||||
|
||||
|
@ -566,7 +633,6 @@ vacdata(DirSink *dsink, int fd, char *lname, VacFile *vf, Dir *dir)
|
|||
if(vfblocks > 1)
|
||||
block += vacdataskip(sink, vf, fd, vfblocks, buf, lname);
|
||||
|
||||
if(0) fprint(2, "vacData: %s: %ld\n", lname, block);
|
||||
for(;;) {
|
||||
n = readn(fd, buf, bsize);
|
||||
if(0 && n < 0)
|
||||
|
@ -857,7 +923,7 @@ sinkwrite(Sink *k, uchar *p, int n)
|
|||
return;
|
||||
|
||||
if(n > k->dir.dsize)
|
||||
sysfatal("sinkWrite: size too big");
|
||||
sysfatal("sinkwrite: size too big");
|
||||
|
||||
if((k->dir.type&~VtTypeDepthMask) == VtDirType){
|
||||
type = VtDirType;
|
||||
|
@ -867,7 +933,7 @@ sinkwrite(Sink *k, uchar *p, int n)
|
|||
stats.data++;
|
||||
}
|
||||
if(vacwrite(k->z, score, type, p, n) < 0)
|
||||
sysfatal("vacWrite failed: %r");
|
||||
sysfatal("vacwrite: %r");
|
||||
|
||||
sinkwritescore(k, score, n);
|
||||
}
|
||||
|
@ -924,7 +990,7 @@ sinkclose(Sink *k)
|
|||
p = k->buf+i*kd->psize;
|
||||
stats.meta++;
|
||||
if(vacwrite(k->z, k->pbuf[i+1], base+1+i, p, k->pbuf[i]-p) < 0)
|
||||
sysfatal("vacWrite failed: %r");
|
||||
sysfatal("vacwrite: %r");
|
||||
k->pbuf[i+1] += VtScoreSize;
|
||||
}
|
||||
memmove(kd->score, k->pbuf[i] - VtScoreSize, VtScoreSize);
|
||||
|
@ -1141,6 +1207,7 @@ metasinkwrite(MetaSink *k, uchar *data, int n)
|
|||
void
|
||||
metasinkwritedir(MetaSink *ms, VacDir *dir)
|
||||
{
|
||||
|
||||
metasinkputuint32(ms, DirMagic);
|
||||
metasinkputc(ms, Version>>8);
|
||||
metasinkputc(ms, Version);
|
||||
|
@ -1218,7 +1285,6 @@ plan9tovacdir(VacDir *vd, Dir *dir, ulong entry, uvlong qid)
|
|||
vd->p9version = dir->qid.vers;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
metasinkeor(MetaSink *k)
|
||||
{
|
||||
|
|
|
@ -101,13 +101,6 @@ int vacfssync(VacFs *fs);
|
|||
int vacfssnapshot(VacFs *fs, char *src, char *dst);
|
||||
int vacfsgetscore(VacFs *fs, u8int *score);
|
||||
|
||||
/*
|
||||
* other ideas
|
||||
*
|
||||
* VacFs *vfsSnapshot(VacFs*, char *src);
|
||||
* int vfsGraft(VacFs*, char *name, VacFs*);
|
||||
*/
|
||||
|
||||
VacFile *vacfsgetroot(VacFs *fs);
|
||||
VacFile *vacfileopen(VacFs *fs, char *path);
|
||||
VacFile *vacfilecreate(VacFile *file, char *elem, ulong perm, char *muid);
|
||||
|
@ -140,4 +133,4 @@ void vdcopy(VacDir *dst, VacDir *src);
|
|||
VacDirEnum *vdeopen(VacFile*);
|
||||
int vderead(VacDirEnum*, VacDir *);
|
||||
void vdeclose(VacDirEnum*);
|
||||
|
||||
int vdeunread(VacDirEnum*);
|
||||
|
|
|
@ -5,18 +5,12 @@
|
|||
#include "vac.h"
|
||||
|
||||
typedef struct Fid Fid;
|
||||
typedef struct DirBuf DirBuf;
|
||||
|
||||
enum
|
||||
{
|
||||
OPERM = 0x3 /* mask of all permission types in open mode */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
DirBufSize = 20
|
||||
};
|
||||
|
||||
struct Fid
|
||||
{
|
||||
short busy;
|
||||
|
@ -25,18 +19,8 @@ struct Fid
|
|||
char *user;
|
||||
Qid qid;
|
||||
VacFile *file;
|
||||
|
||||
DirBuf *db;
|
||||
|
||||
Fid *next;
|
||||
};
|
||||
|
||||
struct DirBuf
|
||||
{
|
||||
VacDirEnum *vde;
|
||||
VacDir buf[DirBufSize];
|
||||
int i, n;
|
||||
int eof;
|
||||
Fid *next;
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -73,12 +57,8 @@ int perm(Fid*, int);
|
|||
int permf(VacFile*, char*, int);
|
||||
ulong getl(void *p);
|
||||
void init(char*, char*, long, int);
|
||||
DirBuf *dirBufAlloc(VacFile*);
|
||||
VacDir *dirBufGet(DirBuf*);
|
||||
int dirBufUnget(DirBuf*);
|
||||
void dirBufFree(DirBuf*);
|
||||
int vacdirread(Fid *f, char *p, long off, long cnt);
|
||||
int vdStat(VacFile *parent, VacDir *vd, uchar *p, int np);
|
||||
int vacstat(VacFile *parent, VacDir *vd, uchar *p, int np);
|
||||
void srv(void* a);
|
||||
|
||||
|
||||
|
@ -141,7 +121,6 @@ threadmain(int argc, char *argv[])
|
|||
int stdio = 0;
|
||||
char *host = nil;
|
||||
long ncache = 1000;
|
||||
int readOnly = 1;
|
||||
|
||||
fmtinstall('H', encodefmt);
|
||||
fmtinstall('V', vtscorefmt);
|
||||
|
@ -184,7 +163,20 @@ threadmain(int argc, char *argv[])
|
|||
usage();
|
||||
|
||||
initfcalls();
|
||||
init(argv[0], host, ncache, readOnly);
|
||||
|
||||
notify(notifyf);
|
||||
user = getuser();
|
||||
|
||||
conn = vtdial(host);
|
||||
if(conn == nil)
|
||||
sysfatal("could not connect to server: %r");
|
||||
|
||||
if(vtconnect(conn) < 0)
|
||||
sysfatal("vtconnect: %r");
|
||||
|
||||
fs = vacfsopen(conn, argv[0], VtOREAD, ncache);
|
||||
if(fs == nil)
|
||||
sysfatal("vacfsopen: %r");
|
||||
|
||||
if(pipe(p) < 0)
|
||||
sysfatal("pipe failed: %r");
|
||||
|
@ -294,19 +286,6 @@ rattach(Fid *f)
|
|||
return 0;
|
||||
}
|
||||
|
||||
VacFile*
|
||||
_vfWalk(VacFile *file, char *name)
|
||||
{
|
||||
VacFile *n;
|
||||
|
||||
n = vacfilewalk(file, name);
|
||||
if(n)
|
||||
return n;
|
||||
if(strcmp(name, "SLASH") == 0)
|
||||
return vacfilewalk(file, "/");
|
||||
return nil;
|
||||
}
|
||||
|
||||
char*
|
||||
rwalk(Fid *f)
|
||||
{
|
||||
|
@ -356,7 +335,7 @@ rwalk(Fid *f)
|
|||
err = Eperm;
|
||||
break;
|
||||
}
|
||||
nfile = _vfWalk(file, rhdr.wname[nqid]);
|
||||
nfile = vacfilewalk(file, rhdr.wname[nqid]);
|
||||
if(nfile == nil)
|
||||
break;
|
||||
vacfiledecref(file);
|
||||
|
@ -410,7 +389,7 @@ ropen(Fid *f)
|
|||
if(!perm(f, Pread))
|
||||
return vtstrdup(Eperm);
|
||||
thdr.qid = f->qid;
|
||||
f->db = nil;
|
||||
f->vde = nil;
|
||||
f->open = 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -564,8 +543,8 @@ rclunk(Fid *f)
|
|||
if(f->file)
|
||||
vacfiledecref(f->file);
|
||||
f->file = nil;
|
||||
dirBufFree(f->db);
|
||||
f->db = nil;
|
||||
vdeclose(f->vde);
|
||||
f->vde = nil;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -588,8 +567,6 @@ rremove(Fid *f)
|
|||
|
||||
if(!vacfileremove(vf, "none")) {
|
||||
rerrstr(errbuf, sizeof errbuf);
|
||||
print("vfRemove failed: %s\n", errbuf);
|
||||
|
||||
err = errbuf;
|
||||
}
|
||||
|
||||
|
@ -611,7 +588,7 @@ rstat(Fid *f)
|
|||
parent = vacfilegetparent(f->file);
|
||||
vacfilegetdir(f->file, &dir);
|
||||
thdr.stat = statbuf;
|
||||
thdr.nstat = vdStat(parent, &dir, thdr.stat, sizeof statbuf);
|
||||
thdr.nstat = vacstat(parent, &dir, thdr.stat, sizeof statbuf);
|
||||
vdcleanup(&dir);
|
||||
vacfiledecref(parent);
|
||||
return 0;
|
||||
|
@ -626,7 +603,7 @@ rwstat(Fid *f)
|
|||
}
|
||||
|
||||
int
|
||||
vdStat(VacFile *parent, VacDir *vd, uchar *p, int np)
|
||||
vacstat(VacFile *parent, VacDir *vd, uchar *p, int np)
|
||||
{
|
||||
char *ext;
|
||||
int n, ret;
|
||||
|
@ -694,96 +671,39 @@ vdStat(VacFile *parent, VacDir *vd, uchar *p, int np)
|
|||
return ret;
|
||||
}
|
||||
|
||||
DirBuf*
|
||||
dirBufAlloc(VacFile *vf)
|
||||
{
|
||||
DirBuf *db;
|
||||
|
||||
db = vtmallocz(sizeof(DirBuf));
|
||||
db->vde = vdeopen(vf);
|
||||
return db;
|
||||
}
|
||||
|
||||
VacDir *
|
||||
dirBufGet(DirBuf *db)
|
||||
{
|
||||
VacDir *vd;
|
||||
int n;
|
||||
|
||||
if(db->eof)
|
||||
return nil;
|
||||
|
||||
if(db->i >= db->n) {
|
||||
n = vderead(db->vde, db->buf);
|
||||
if(n < 0)
|
||||
return nil;
|
||||
db->i = 0;
|
||||
db->n = n;
|
||||
if(n == 0) {
|
||||
db->eof = 1;
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
vd = db->buf + db->i;
|
||||
db->i++;
|
||||
|
||||
return vd;
|
||||
}
|
||||
|
||||
int
|
||||
dirBufUnget(DirBuf *db)
|
||||
{
|
||||
assert(db->i > 0);
|
||||
db->i--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
dirBufFree(DirBuf *db)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(db == nil)
|
||||
return;
|
||||
|
||||
for(i=db->i; i<db->n; i++)
|
||||
vdcleanup(db->buf + i);
|
||||
vdeclose(db->vde);
|
||||
vtfree(db);
|
||||
}
|
||||
|
||||
int
|
||||
vacdirread(Fid *f, char *p, long off, long cnt)
|
||||
{
|
||||
int n, nb;
|
||||
VacDir *vd;
|
||||
int i, n, nb;
|
||||
VacDir vd;
|
||||
|
||||
/*
|
||||
* special case of rewinding a directory
|
||||
* otherwise ignore the offset
|
||||
*/
|
||||
if(off == 0 && f->db) {
|
||||
dirBufFree(f->db);
|
||||
f->db = nil;
|
||||
if(off == 0 && f->vde){
|
||||
vdeclose(f->vde);
|
||||
f->vde = nil;
|
||||
}
|
||||
|
||||
if(f->db == nil)
|
||||
f->db = dirBufAlloc(f->file);
|
||||
if(f->vde == nil){
|
||||
f->vde = vdeopen(f->file);
|
||||
if(f->vde == nil)
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(nb = 0; nb < cnt; nb += n) {
|
||||
vd = dirBufGet(f->db);
|
||||
if(vd == nil) {
|
||||
if(!f->db->eof)
|
||||
return -1;
|
||||
i = vderead(f->vde, &vd);
|
||||
if(i < 0)
|
||||
return -1;
|
||||
if(i == 0)
|
||||
break;
|
||||
}
|
||||
n = vdStat(f->file, vd, (uchar*)p, cnt-nb);
|
||||
n = vacstat(f->file, &vd, (uchar*)p, cnt-nb);
|
||||
if(n <= BIT16SZ) {
|
||||
dirBufUnget(f->db);
|
||||
vdeunread(f->vde);
|
||||
break;
|
||||
}
|
||||
vdcleanup(vd);
|
||||
vdcleanup(&vd);
|
||||
p += n;
|
||||
}
|
||||
return nb;
|
||||
|
@ -885,24 +805,6 @@ perm(Fid *f, int p)
|
|||
return permf(f->file, f->user, p);
|
||||
}
|
||||
|
||||
void
|
||||
init(char *file, char *host, long ncache, int readOnly)
|
||||
{
|
||||
notify(notifyf);
|
||||
user = getuser();
|
||||
|
||||
conn = vtdial(host);
|
||||
if(conn == nil)
|
||||
sysfatal("could not connect to server: %r");
|
||||
|
||||
if(vtconnect(conn) < 0)
|
||||
sysfatal("vtconnect: %r");
|
||||
|
||||
fs = vacfsopen(conn, file, /*readOnly ? ModeSnapshot :*/ VtOREAD, ncache);
|
||||
if(fs == nil)
|
||||
sysfatal("vfsOpen: %r");
|
||||
}
|
||||
|
||||
void
|
||||
vacshutdown(void)
|
||||
{
|
||||
|
|
|
@ -1,182 +0,0 @@
|
|||
#include "stdinc.h"
|
||||
#include "vac.h"
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
|
||||
void usage(void);
|
||||
int unvac(VacFS *fs);
|
||||
int readScore(int fd, uchar score[VtScoreSize]);
|
||||
static void warn(char *fmt, ...);
|
||||
void dirlist(VacFS *fs, char *path);
|
||||
|
||||
static int nwant;
|
||||
static char **want;
|
||||
static int dflag = 1;
|
||||
static int cflag;
|
||||
static int lower;
|
||||
static int verbose;
|
||||
static int settimes;
|
||||
|
||||
void
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char *zfile;
|
||||
int ok, table;
|
||||
VtSession *z;
|
||||
char *vsrv = nil;
|
||||
char *host = nil;
|
||||
char *p;
|
||||
int ncache = 1000;
|
||||
VacFS *fs;
|
||||
|
||||
table = 0;
|
||||
zfile = nil;
|
||||
ARGBEGIN{
|
||||
case 'D':
|
||||
dflag++;
|
||||
break;
|
||||
case 'c':
|
||||
cflag++;
|
||||
break;
|
||||
case 'C':
|
||||
p = ARGF();
|
||||
if(p == nil)
|
||||
usage();
|
||||
ncache = atoi(p);
|
||||
if(ncache < 10)
|
||||
ncache = 10;
|
||||
if(ncache > 1000000)
|
||||
ncache = 1000000;
|
||||
break;
|
||||
case 'i':
|
||||
lower++;
|
||||
break;
|
||||
case 'f':
|
||||
zfile = ARGF();
|
||||
if(zfile == nil)
|
||||
usage();
|
||||
break;
|
||||
case 'h':
|
||||
host = ARGF();
|
||||
break;
|
||||
case 't':
|
||||
table++;
|
||||
break;
|
||||
case 'T':
|
||||
settimes++;
|
||||
break;
|
||||
case 's':
|
||||
vsrv = ARGF();
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
}ARGEND
|
||||
|
||||
nwant = argc;
|
||||
want = argv;
|
||||
|
||||
vtAttach();
|
||||
|
||||
if(zfile == nil)
|
||||
usage();
|
||||
|
||||
if(vsrv != nil)
|
||||
z = vtStdioServer(vsrv);
|
||||
else
|
||||
z = vtDial(host);
|
||||
if(z == nil)
|
||||
vtFatal("could not connect to server: %s", vtGetError());
|
||||
vtSetDebug(z, 0);
|
||||
if(!vtConnect(z, 0))
|
||||
vtFatal("vtConnect: %s", vtGetError());
|
||||
fs = vfsOpen(z, zfile, 1, ncache);
|
||||
if(fs == nil)
|
||||
vtFatal("vfsOpen: %s", vtGetError());
|
||||
ok = unvac(fs);
|
||||
vtClose(z);
|
||||
vtDetach();
|
||||
|
||||
exits(ok? 0 : "error");
|
||||
}
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
fprint(2, "usage: %s [-tTcDv] -f zipfile [-s ventid] [-h host] [file ...]\n", argv0);
|
||||
exits("usage");
|
||||
}
|
||||
|
||||
void
|
||||
suck(VacFile *f)
|
||||
{
|
||||
USED(f);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vacfile(VacFS *fs, char *path, VacDir *vd)
|
||||
{
|
||||
char *path2;
|
||||
|
||||
path2 = vtMemAlloc(strlen(path) + 1 + strlen(vd->elem) + 1);
|
||||
if(path[1] == 0)
|
||||
sprintf(path2, "/%s", vd->elem);
|
||||
else
|
||||
sprintf(path2, "%s/%s", path, vd->elem);
|
||||
fprint(2, "vac file: %s\n", path2);
|
||||
if(vd->mode & ModeDir)
|
||||
dirlist(fs, path2);
|
||||
vtMemFree(path2);
|
||||
}
|
||||
|
||||
void
|
||||
dirlist(VacFS *fs, char *path)
|
||||
{
|
||||
VacDir vd[50];
|
||||
VacDirEnum *ds;
|
||||
int i, n;
|
||||
|
||||
ds = vdeOpen(fs, path);
|
||||
if(ds == nil) {
|
||||
fprint(2, "could not open: %s: %s\n", path, vtGetError());
|
||||
return;
|
||||
}
|
||||
for(;;) {
|
||||
n = vdeRead(ds, vd, sizeof(vd)/sizeof(VacDir));
|
||||
if(n < 0) {
|
||||
warn("vdRead failed: %s: %s", path, vtGetError());
|
||||
return;
|
||||
}
|
||||
if(n == 0)
|
||||
break;
|
||||
for(i=0; i<n; i++) {
|
||||
vacfile(fs, path, &vd[i]);
|
||||
vdCleanup(&vd[i]);
|
||||
}
|
||||
}
|
||||
vdeFree(ds);
|
||||
}
|
||||
|
||||
int
|
||||
unvac(VacFS *fs)
|
||||
{
|
||||
dirlist(fs, "/");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
warn(char *fmt, ...)
|
||||
{
|
||||
va_list arg;
|
||||
|
||||
va_start(arg, fmt);
|
||||
fprint(2, "%s: ", argv0);
|
||||
vfprint(2, fmt, arg);
|
||||
fprint(2, "\n");
|
||||
va_end(arg);
|
||||
}
|
|
@ -1,126 +0,0 @@
|
|||
#include "stdinc.h"
|
||||
#include <bio.h>
|
||||
|
||||
typedef struct Source Source;
|
||||
|
||||
struct Source
|
||||
{
|
||||
ulong gen;
|
||||
int psize;
|
||||
int dsize;
|
||||
int dir;
|
||||
int active;
|
||||
int depth;
|
||||
uvlong size;
|
||||
uchar score[VtScoreSize];
|
||||
int reserved;
|
||||
};
|
||||
|
||||
int bsize;
|
||||
Biobuf *bout;
|
||||
VtRootLump root;
|
||||
int ver;
|
||||
int cmp;
|
||||
int all;
|
||||
int find;
|
||||
uchar fscore[VtScoreSize];
|
||||
int dirSize;
|
||||
void (*parse)(Source*, uchar*);
|
||||
VtSession *z;
|
||||
|
||||
int vtGetUint16(uchar *p);
|
||||
ulong vtGetUint32(uchar *p);
|
||||
uvlong vtGetUint48(uchar *p);
|
||||
void usage(void);
|
||||
int parseScore(uchar *score, char *buf, int n);
|
||||
void readRoot(VtRootLump*, uchar *score, char *file);
|
||||
void parse1(Source*, uchar*);
|
||||
void parse2(Source*, uchar*);
|
||||
int dumpDir(Source*, int indent);
|
||||
|
||||
void
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char *host = nil;
|
||||
uchar score[VtScoreSize];
|
||||
uchar buf[VtMaxLumpSize];
|
||||
int type;
|
||||
int n;
|
||||
|
||||
type = VtDataType;
|
||||
|
||||
ARGBEGIN{
|
||||
case 't':
|
||||
type = atoi(ARGF());
|
||||
break;
|
||||
}ARGEND
|
||||
|
||||
vtAttach();
|
||||
|
||||
bout = vtMemAllocZ(sizeof(Biobuf));
|
||||
Binit(bout, 1, OWRITE);
|
||||
|
||||
if(argc != 1)
|
||||
usage();
|
||||
|
||||
vtAttach();
|
||||
|
||||
fmtinstall('V', vtScoreFmt);
|
||||
fmtinstall('R', vtErrFmt);
|
||||
|
||||
z = vtDial(host);
|
||||
if(z == nil)
|
||||
vtFatal("could not connect to server: %s", vtGetError());
|
||||
|
||||
if(!vtConnect(z, 0))
|
||||
sysfatal("vtConnect: %r");
|
||||
|
||||
if(!parseScore(score, argv[0], strlen(argv[0])))
|
||||
vtFatal("could not parse score: %s", vtGetError());
|
||||
|
||||
n = vtRead(z, score, type, buf, VtMaxLumpSize);
|
||||
if(n < 0)
|
||||
vtFatal("could not read block: %s", vtGetError());
|
||||
Bwrite(bout, buf, n);
|
||||
|
||||
Bterm(bout);
|
||||
|
||||
vtClose(z);
|
||||
vtDetach();
|
||||
exits(0);
|
||||
}
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
fprint(2, "%s: -t type score\n", argv0);
|
||||
exits("usage");
|
||||
}
|
||||
|
||||
int
|
||||
parseScore(uchar *score, char *buf, int n)
|
||||
{
|
||||
int i, c;
|
||||
|
||||
memset(score, 0, VtScoreSize);
|
||||
|
||||
if(n < VtScoreSize*2)
|
||||
return 0;
|
||||
for(i=0; i<VtScoreSize*2; i++) {
|
||||
if(buf[i] >= '0' && buf[i] <= '9')
|
||||
c = buf[i] - '0';
|
||||
else if(buf[i] >= 'a' && buf[i] <= 'f')
|
||||
c = buf[i] - 'a' + 10;
|
||||
else if(buf[i] >= 'A' && buf[i] <= 'F')
|
||||
c = buf[i] - 'A' + 10;
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if((i & 1) == 0)
|
||||
c <<= 4;
|
||||
|
||||
score[i>>1] |= c;
|
||||
}
|
||||
return 1;
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
#include "stdinc.h"
|
||||
|
||||
enum {
|
||||
Nblock = 10000,
|
||||
BlockSize = 8*1024
|
||||
};
|
||||
|
||||
uchar data[Nblock*BlockSize];
|
||||
|
||||
void
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
VtSession *z;
|
||||
int i;
|
||||
uchar score[VtScoreSize];
|
||||
int start;
|
||||
|
||||
ARGBEGIN{
|
||||
}ARGEND
|
||||
|
||||
for(i=0; i<Nblock; i++) {
|
||||
if(readn(0, data+i*BlockSize, BlockSize) < BlockSize)
|
||||
sysfatal("read failed: %r");
|
||||
}
|
||||
|
||||
vtAttach();
|
||||
|
||||
z = vtDial("iolaire2");
|
||||
if(z == nil)
|
||||
sysfatal("cound not connect to venti");
|
||||
if(!vtConnect(z, 0))
|
||||
vtFatal("vtConnect: %s", vtGetError());
|
||||
|
||||
print("starting\n");
|
||||
|
||||
start = times(0);
|
||||
|
||||
for(i=0; i<Nblock; i++) {
|
||||
if(!vtWrite(z, score, VtDataType, data+i*BlockSize, BlockSize))
|
||||
vtFatal("vtWrite failed: %s", vtGetError());
|
||||
}
|
||||
|
||||
print("time = %f\n", (times(0) - start)*0.001);
|
||||
|
||||
vtClose(z);
|
||||
vtDetach();
|
||||
}
|
Loading…
Reference in a new issue