venti/copy: synchronize with Plan 9; indent in verbose mode

http://codereview.appspot.com/110062
This commit is contained in:
Venkatesh Srinivas 2009-08-21 15:55:56 -04:00
parent c0cc7cc4da
commit da0a205ed6
2 changed files with 146 additions and 14 deletions

View file

@ -3,6 +3,8 @@
#include <venti.h>
#include <libsec.h>
#include <thread.h>
#include <avl.h>
#include <bin.h>
enum
{
@ -15,25 +17,93 @@ int rewrite;
int ignoreerrors;
int fast;
int verbose;
int nskip;
int nwrite;
VtConn *zsrc, *zdst;
uchar zeroscore[VtScoreSize]; /* all zeros */
typedef struct ScoreTree ScoreTree;
struct ScoreTree
{
Avl avl;
uchar score[VtScoreSize];
int type;
};
Avltree *scoretree;
Bin *scorebin;
static int
scoretreecmp(Avl *va, Avl *vb)
{
ScoreTree *a, *b;
int i;
a = (ScoreTree*)va;
b = (ScoreTree*)vb;
i = memcmp(a->score, b->score, VtScoreSize);
if(i != 0)
return i;
return a->type - b->type;
}
static int
havevisited(uchar score[VtScoreSize], int type)
{
ScoreTree a;
if(scoretree == nil)
return 0;
memmove(a.score, score, VtScoreSize);
a.type = type;
return lookupavl(scoretree, &a.avl) != nil;
}
static void
markvisited(uchar score[VtScoreSize], int type)
{
ScoreTree *a;
Avl *old;
if(scoretree == nil)
return;
a = binalloc(&scorebin, sizeof *a, 1);
memmove(a->score, score, VtScoreSize);
a->type = type;
insertavl(scoretree, &a->avl, &old);
}
void
usage(void)
{
fprint(2, "usage: copy [-fir] [-t type] srchost dsthost score\n");
fprint(2, "usage: copy [-fimrVv] [-t type] srchost dsthost score\n");
threadexitsall("usage");
}
void
walk(uchar score[VtScoreSize], uint type, int base)
walk(uchar score[VtScoreSize], uint type, int base, int depth)
{
int i, n;
uchar *buf;
uchar nscore[VtScoreSize];
VtEntry e;
VtRoot root;
if(memcmp(score, vtzeroscore, VtScoreSize) == 0)
if(verbose){
for(i = 0; i < depth; i++)
fprint(2, " ");
fprint(2, "-> %d %d %d %V\n", depth, type, base, score);
}
if(memcmp(score, vtzeroscore, VtScoreSize) == 0 || memcmp(score, zeroscore, VtScoreSize) == 0)
return;
if(havevisited(score, type)){
nskip++;
return;
}
buf = vtmallocz(VtMaxLumpSize);
if(fast && vtread(zdst, score, type, buf, VtMaxLumpSize) >= 0){
@ -59,8 +129,8 @@ walk(uchar score[VtScoreSize], uint type, int base)
fprint(2, "warning: could not unpack root in %V %d\n", score, type);
break;
}
walk(root.score, VtDirType, 0);
walk(root.prev, VtRootType, 0);
walk(root.prev, VtRootType, 0, depth+1);
walk(root.score, VtDirType, 0, depth+1);
if(rewrite)
vtrootpack(&root, buf); /* walk might have changed score */
break;
@ -73,7 +143,14 @@ walk(uchar score[VtScoreSize], uint type, int base)
}
if(!(e.flags & VtEntryActive))
continue;
walk(e.score, e.type, e.type&VtTypeBaseMask);
walk(e.score, e.type, e.type&VtTypeBaseMask, depth+1);
/*
* Don't repack unless we're rewriting -- some old
* vac files have psize==0 and dsize==0, and these
* get rewritten by vtentryunpack to have less strange
* block sizes. So vtentryunpack; vtentrypack does not
* guarantee to preserve the exact bytes in buf.
*/
if(rewrite)
vtentrypack(&e, buf, i);
}
@ -85,17 +162,31 @@ walk(uchar score[VtScoreSize], uint type, int base)
default: /* pointers */
for(i=0; i<n; i+=VtScoreSize)
if(memcmp(buf+i, vtzeroscore, VtScoreSize) != 0)
walk(buf+i, type-1, base);
walk(buf+i, type-1, base, depth+1);
break;
}
if(vtwrite(zdst, score, type, buf, n) < 0){
nwrite++;
if(vtwrite(zdst, nscore, type, buf, n) < 0){
/* figure out score for better error message */
/* can't use input argument - might have changed contents */
n = vtzerotruncate(type, buf, n);
sha1(buf, n, score, nil);
sysfatal("writing block %V (type %d): %r", score, type);
}
if(!rewrite && memcmp(score, nscore, VtScoreSize) != 0)
sysfatal("not rewriting: wrote %V got %V", score, nscore);
if((type !=0 || base !=0) && verbose){
n = vtzerotruncate(type, buf, n);
sha1(buf, n, score, nil);
for(i = 0; i < depth; i++)
fprint(2, " ");
fprint(2, "<- %V\n", score);
}
markvisited(score, type);
free(buf);
}
@ -112,6 +203,9 @@ threadmain(int argc, char *argv[])
type = -1;
ARGBEGIN{
case 'V':
chattyventi++;
break;
case 'f':
fast = 1;
break;
@ -120,6 +214,9 @@ threadmain(int argc, char *argv[])
usage();
ignoreerrors = 1;
break;
case 'm':
scoretree = mkavltree(scoretreecmp);
break;
case 'r':
if(ignoreerrors)
usage();
@ -128,6 +225,9 @@ threadmain(int argc, char *argv[])
case 't':
type = atoi(EARGF(usage()));
break;
case 'v':
verbose = 1;
break;
default:
usage();
break;
@ -167,10 +267,13 @@ threadmain(int argc, char *argv[])
sysfatal("could not find block %V of any type", score);
}
walk(score, type, VtDirType);
walk(score, type, VtDirType, 0);
if(changes)
print("%s:%V (%d pointers rewritten)\n", prefix, score, changes);
if(verbose)
print("%d skipped, %d written\n", nskip, nwrite);
if(vtsync(zdst) < 0)
sysfatal("could not sync dst server: %r");