venti updates
diff --git a/include/venti.h b/include/venti.h index acb255d..e1bb232 100644 --- a/include/venti.h +++ b/include/venti.h
@@ -463,6 +463,7 @@ VtFile *vtfilecreateroot(VtCache*, int psize, int dsize, int type); VtFile *vtfileopen(VtFile*, u32int, int); VtFile *vtfilecreate(VtFile*, int psize, int dsize, int dir); +VtFile *_vtfilecreate(VtFile*, int offset, int psize, int dsize, int dir); VtBlock *vtfileblock(VtFile*, u32int, int mode); long vtfileread(VtFile*, void*, long, vlong); long vtfilewrite(VtFile*, void*, long, vlong);
diff --git a/src/cmd/vac/file.c b/src/cmd/vac/file.c index bb0bb03..10c632c 100644 --- a/src/cmd/vac/file.c +++ b/src/cmd/vac/file.c
@@ -4,6 +4,8 @@ #include "fns.h" #include "error.h" +#define debug 0 + /* * locking order is upwards. A thread can hold the lock for a VacFile * and then acquire the lock of its parent @@ -122,12 +124,16 @@ VacFile* _vacfileroot(VacFs *fs, VtFile *r) { + int redirected; + char err[ERRMAX]; VtBlock *b; VtFile *r0, *r1, *r2; MetaBlock mb; MetaEntry me; VacFile *root, *mr; + redirected = 0; +Top: b = nil; root = nil; mr = nil; @@ -137,13 +143,30 @@ if(vtfilelock(r, -1) < 0) return nil; r0 = vtfileopen(r, 0, fs->mode); + if(debug) + fprint(2, "r0 %p\n", r0); if(r0 == nil) goto Err; - r1 = vtfileopen(r, 1, fs->mode); - if(r1 == nil) - goto Err; r2 = vtfileopen(r, 2, fs->mode); - if(r2 == nil) + if(debug) + fprint(2, "r2 %p\n", r2); + if(r2 == nil){ + /* + * some vac files (e.g., from fossil) + * have an extra layer of indirection. + */ + rerrstr(err, sizeof err); + if(!redirected && strstr(err, "not active")){ + vtfileunlock(r); + r = r0; + goto Top; + } + goto Err; + } + r1 = vtfileopen(r, 1, fs->mode); + if(debug) + fprint(2, "r1 %p\n", r1); + if(r1 == nil) goto Err; mr = filealloc(fs);
diff --git a/src/cmd/vac/fs.c b/src/cmd/vac/fs.c index f635d5d..d9ab258 100644 --- a/src/cmd/vac/fs.c +++ b/src/cmd/vac/fs.c
@@ -3,6 +3,8 @@ #include "dat.h" #include "fns.h" +#define debug 0 + static char EBadVacFormat[] = "bad format for vac file"; static VacFs * @@ -103,13 +105,15 @@ root = nil; if((r = vtfileopenroot(fs->cache, &e)) == nil) goto Err; - + if(debug) + fprint(2, "r %p\n", r); root = _vacfileroot(fs, r); + if(debug) + fprint(2, "root %p\n", root); vtfileclose(r); if(root == nil) goto Err; fs->root = root; - return fs; Err: if(root)
diff --git a/src/cmd/vac/mkfile b/src/cmd/vac/mkfile index dfc0e1a..1f8d999 100644 --- a/src/cmd/vac/mkfile +++ b/src/cmd/vac/mkfile
@@ -6,7 +6,7 @@ fs\ pack\ -LIB=${LIBFILES:%=%.$O} +LIB=${LIBFILES:%=%.$O} $PLAN9/lib/libventi.a HFILES=\ $PLAN9/include/venti.h\
diff --git a/src/cmd/vac/vac.c b/src/cmd/vac/vac.c index 0b4f818..bcb9b57 100644 --- a/src/cmd/vac/vac.c +++ b/src/cmd/vac/vac.c
@@ -318,9 +318,8 @@ /* build meta information for the root */ ms = metasinkalloc(z, bsize, bsize); /* fake into a directory */ - dir->mode |= (dir->mode&0444)>>2; + dir->mode = DMDIR|0555; dir->qid.type |= QTDIR; - dir->mode |= DMDIR; plan9tovacdir(&vd, dir, 0, fileid++); if(strcmp(vd.elem, "/") == 0){ vtfree(vd.elem);
diff --git a/src/cmd/vac/vacfs.c b/src/cmd/vac/vacfs.c index 6720919..4064cfa 100644 --- a/src/cmd/vac/vacfs.c +++ b/src/cmd/vac/vacfs.c
@@ -141,6 +141,10 @@ long ncache = 1000; int readOnly = 1; + fmtinstall('H', encodefmt); + fmtinstall('V', vtscorefmt); + fmtinstall('F', vtfcallfmt); + defsrv = nil; ARGBEGIN{ case 'd': @@ -164,6 +168,9 @@ case 'p': noperm = 1; break; + case 'V': + chattyventi = 1; + break; default: usage(); }ARGEND @@ -198,7 +205,6 @@ if(post9pservice(p[1], defsrv) != 0) sysfatal("post9pservice"); - threadexits(0); } @@ -840,9 +846,6 @@ notify(notifyf); user = getuser(); - fmtinstall('V', vtscorefmt); -// fmtinstall('R', vtErrFmt); - conn = vtdial(host); if(conn == nil) sysfatal("could not connect to server: %r");
diff --git a/src/cmd/venti/read.c b/src/cmd/venti/read.c index 3f3441e..a48e62e 100644 --- a/src/cmd/venti/read.c +++ b/src/cmd/venti/read.c
@@ -30,7 +30,7 @@ host = EARGF(usage()); break; case 't': - type = atoi(argv[1]); + type = atoi(EARGF(usage())); break; default: usage(); @@ -62,10 +62,9 @@ break; } } - }else{ - type = atoi(argv[1]); + }else n = vtread(z, score, type, buf, VtMaxLumpSize); - } + vthangup(z); if(n < 0) sysfatal("could not read block: %r");
diff --git a/src/cmd/venti/root.c b/src/cmd/venti/root.c new file mode 100644 index 0000000..5d67ad3 --- /dev/null +++ b/src/cmd/venti/root.c
@@ -0,0 +1,72 @@ +#include <u.h> +#include <libc.h> +#include <venti.h> +#include <libsec.h> +#include <thread.h> + +void +usage(void) +{ + fprint(2, "usage: root [-h host] score\n"); + threadexitsall("usage"); +} + +void +threadmain(int argc, char *argv[]) +{ + int i, n; + uchar score[VtScoreSize]; + uchar *buf; + VtConn *z; + char *host; + VtRoot root; + + fmtinstall('F', vtfcallfmt); + fmtinstall('V', vtscorefmt); + quotefmtinstall(); + + host = nil; + ARGBEGIN{ + case 'h': + host = EARGF(usage()); + break; + default: + usage(); + break; + }ARGEND + + if(argc == 0) + usage(); + + buf = vtmallocz(VtMaxLumpSize); + + z = vtdial(host); + if(z == nil) + sysfatal("could not connect to server: %r"); + + if(vtconnect(z) < 0) + sysfatal("vtconnect: %r"); + + for(i=0; i<argc; i++){ + if(vtparsescore(argv[i], nil, score) < 0){ + fprint(2, "cannot parse score '%s': %r\n", argv[i]); + continue; + } + n = vtread(z, score, VtRootType, buf, VtMaxLumpSize); + if(n < 0){ + fprint(2, "could not read block %V: %r\n", score); + continue; + } + if(n != VtRootSize){ + fprint(2, "block %V is wrong size %d != 300\n", score, n); + continue; + } + if(vtrootunpack(&root, buf) < 0){ + fprint(2, "unpacking block %V: %r\n", score); + continue; + } + print("%V: %q %q %V %d %V\n", score, root.name, root.type, root.score, root.blocksize, root.prev); + } + vthangup(z); + threadexitsall(0); +}
diff --git a/src/cmd/venti/srv/buildindex.c b/src/cmd/venti/srv/buildindex.c index 4cf6029..640b190 100644 --- a/src/cmd/venti/srv/buildindex.c +++ b/src/cmd/venti/srv/buildindex.c
@@ -119,6 +119,7 @@ zero = 1; bcmem = 0; + ventifmtinstall(); ARGBEGIN{ case 'B': bcmem = unittoull(ARGF());
diff --git a/src/cmd/venti/srv/wrarena.c b/src/cmd/venti/srv/wrarena.c index 4b8358c..7563fae 100644 --- a/src/cmd/venti/srv/wrarena.c +++ b/src/cmd/venti/srv/wrarena.c
@@ -190,14 +190,14 @@ if(arena == nil) sysfatal("initarena: %r"); - if(host && strcmp(host, "/dev/null") != 0){ + z = nil; + if(host==nil || strcmp(host, "/dev/null") != 0){ z = vtdial(host); if(z == nil) sysfatal("could not connect to server: %r"); if(vtconnect(z) < 0) sysfatal("vtconnect: %r"); - }else - z = nil; + } c = chancreate(sizeof(ZClump), 0); for(i=0; i<12; i++)
diff --git a/src/libventi/cache.c b/src/libventi/cache.c index 09ca5ea..71bdb62 100644 --- a/src/libventi/cache.c +++ b/src/libventi/cache.c
@@ -311,11 +311,13 @@ { VtBlock *b; - if(addr >= c->nblock) - sysfatal("vtcachelocal: asked for block #%ud; only %d blocks\n", + if(addr == 0) + sysfatal("vtcachelocal: asked for nonexistent block 0"); + if(addr > c->nblock) + sysfatal("vtcachelocal: asked for block #%ud; only %d blocks", addr, c->nblock); - b = &c->block[addr]; + b = &c->block[addr-1]; if(b->addr == NilBlock || b->iostate != BioLocal) sysfatal("vtcachelocal: block is not local"); @@ -340,7 +342,7 @@ b = vtcachebumpblock(c); b->iostate = BioLocal; b->type = type; - b->addr = b - c->block; + b->addr = (b - c->block)+1; vtzeroextend(type, b->data, 0, c->blocksize); vtlocaltoglobal(b->addr, b->score); qunlock(&c->lk);
diff --git a/src/libventi/entry.c b/src/libventi/entry.c index ca1d200..aeb8dad 100644 --- a/src/libventi/entry.c +++ b/src/libventi/entry.c
@@ -7,7 +7,7 @@ checksize(int n) { if(n < 256 || n > VtMaxLumpSize) { - werrstr("bad block size"); + werrstr("bad block size %#ux", n); return -1; } return 0; @@ -77,6 +77,16 @@ if(!(e->flags & VtEntryActive)) return 0; + /* + * Some old vac files use psize==0 and dsize==0 when the + * file itself has size 0 or is zeros. Just to make programs not + * have to figure out what block sizes of 0 means, rewrite them. + */ + if(e->psize == 0 && e->dsize == 0 + && memcmp(e->score, vtzeroscore, VtScoreSize) == 0){ + e->psize = 4096; + e->dsize = 4096; + } if(checksize(e->psize) < 0 || checksize(e->dsize) < 0) return -1;
diff --git a/src/libventi/file.c b/src/libventi/file.c index 89b307c..9b25011 100644 --- a/src/libventi/file.c +++ b/src/libventi/file.c
@@ -18,7 +18,6 @@ #define MaxBlock (1UL<<31) -static char EBadEntry[] = "bad VtEntry"; static char ENotDir[] = "walk in non-directory"; static char ETooBig[] = "file too big"; /* static char EBadAddr[] = "bad address"; */ @@ -49,8 +48,10 @@ }else epb = p->dsize / VtEntrySize; - if(b->type != VtDirType) - goto Bad; + if(b->type != VtDirType){ + werrstr("bad block type %#uo", b->type); + return nil; + } /* * a non-active entry is the only thing that @@ -58,28 +59,26 @@ * get prints. */ if(vtentryunpack(&e, b->data, offset % epb) < 0){ - fprint(2, "vtentryunpack failed\n"); - goto Bad; + fprint(2, "vtentryunpack failed: %r (%.*H)\n", VtEntrySize, b->data+VtEntrySize*(offset%epb)); + return nil; } if(!(e.flags & VtEntryActive)){ - if(0)fprint(2, "not active\n"); - goto Bad; - } - if(e.psize < 256 || e.dsize < 256){ - fprint(2, "psize %ud dsize %ud\n", e.psize, e.dsize); - goto Bad; + werrstr("entry not active"); + return nil; } if(DEPTH(e.type) < sizetodepth(e.size, e.psize, e.dsize)){ fprint(2, "depth %ud size %llud psize %ud dsize %ud\n", DEPTH(e.type), e.size, e.psize, e.dsize); - goto Bad; + werrstr("bad depth"); + return nil; } size = vtcacheblocksize(c); if(e.dsize > size || e.psize > size){ - fprint(2, "psize %ud dsize %ud blocksize %ud\n", e.psize, e.dsize, size); - goto Bad; + werrstr("block sizes %ud, %ud bigger than cache block size %ud", + e.psize, e.dsize, size); + return nil; } r = vtmallocz(sizeof(VtFile)); @@ -105,10 +104,6 @@ r->epb = epb; return r; -Bad: - werrstr(EBadEntry); - return nil; - } VtFile * @@ -178,17 +173,23 @@ return r; } -VtFile * +VtFile* vtfilecreate(VtFile *r, int psize, int dsize, int type) { + return _vtfilecreate(r, -1, psize, dsize, type); +} + +VtFile* +_vtfilecreate(VtFile *r, int o, int psize, int dsize, int type) +{ int i; VtBlock *b; u32int bn, size; VtEntry e; int epb; VtFile *rr; - u32int offset; - + u32int offset; + assert(ISLOCKED(r)); assert(psize <= VtMaxLumpSize); assert(dsize <= VtMaxLumpSize); @@ -205,8 +206,11 @@ /* * look at a random block to see if we can find an empty entry */ - offset = lnrand(size+1); - offset -= offset % epb; + if(o == -1){ + offset = lnrand(size+1); + offset -= offset % epb; + }else + offset = o; /* try the given block and then try the last block */ for(;;){