hjfs: Fix bugs in ref count scan check. Enable as a console command (caveat: command arguments will change as I implement more functionality)

This commit is contained in:
spew 2017-03-28 20:39:14 -05:00
parent e51044884b
commit 1c13d41b8c
3 changed files with 23 additions and 11 deletions

View file

@ -273,7 +273,7 @@ getbuf(Dev *d, uvlong off, int type, int nodata)
} }
if(nodata) if(nodata)
b->type = type; b->type = type;
if(b->type != type && type != -1){ if(b->type != type && type != TDONTCARE){
dprint("type mismatch, dev %s, block %lld, got %T, want %T, caller %#p\n", dprint("type mismatch, dev %s, block %lld, got %T, want %T, caller %#p\n",
d->name, off, b->type, type, getcallerpc(&d)); d->name, off, b->type, type, getcallerpc(&d));
werrstr("phase error -- type mismatch"); werrstr("phase error -- type mismatch");

View file

@ -110,20 +110,26 @@ checkfile(FLoc *l, Buf *b)
Dentry *d; Dentry *d;
char *ftype; char *ftype;
int btype; int btype;
uvlong i, r; uvlong i, r, blocks;
d = getdent(l, b); d = getdent(l, b);
if(d == nil){
dprint("checkfile: bad entry: %r\n");
return;
}
if((d->type & QTDIR) == 0){ if((d->type & QTDIR) == 0){
ftype = "file"; ftype = "file";
btype = TRAW; btype = TRAW;
blocks = HOWMANY(d->size);
}else{ }else{
ftype = "directory"; ftype = "directory";
btype = TDENTRY; btype = TDENTRY;
blocks = d->size;
} }
for(i = 0; i < d->size; i++){ for(i = 0; i < blocks; i++){
if(getblk(fsmain, l, b, i, &r, GBREAD) <= 0){ if(getblk(fsmain, l, b, i, &r, GBREAD) <= 0){
dprint("%s in block %ulld at index %d has a bad block at index %ulld: %r\n", ftype, l->blk, l->deind, i); dprint("%s %s in block %ulld at index %d has a bad block at index %ulld: %r\n", ftype, d->name, l->blk, l->deind, i);
continue; continue;
} }
c = getbuf(fsmain->d, r, btype, 0); c = getbuf(fsmain->d, r, btype, 0);
@ -148,19 +154,20 @@ checkblk(uvlong blk)
return -1; return -1;
switch(type = b->type){ switch(type = b->type){
case TSUPERBLOCK: case TSUPERBLOCK:
dprint("checkblk: should not have found superblock at %ulld\n", blk); if(blk != SUPERBLK)
dprint("checkblk: should not have found superblock at %ulld\n", blk);
break; break;
case TDENTRY: case TDENTRY:
l.blk = blk; l.blk = blk;
for(i = 0; i < DEPERBLK; i++){ for(i = 0; i < DEPERBLK; i++){
d = &b->de[i]; d = &b->de[i];
if((d->mode & (DGONE | DALLOC)) == 0)
break;
l.deind = i; l.deind = i;
l.Qid = d->Qid; l.Qid = d->Qid;
checkfile(&l, b); checkfile(&l, b);
} }
break; break;
case TINDIR:
break;
} }
putbuf(b); putbuf(b);
return type; return type;
@ -169,6 +176,7 @@ checkblk(uvlong blk)
int int
cmdcheck(int, char**) cmdcheck(int, char**)
{ {
static ulong refs[REFPERBLK];
uvlong fblk, fend, blk; uvlong fblk, fend, blk;
uvlong ndentry, nindir, nraw, nref, nsuperblock; uvlong ndentry, nindir, nraw, nref, nsuperblock;
int j; int j;
@ -191,9 +199,11 @@ cmdcheck(int, char**)
blk += REFPERBLK; blk += REFPERBLK;
continue; continue;
} }
for(j = 0; j < REFPERBLK; j++, blk++) { memcpy(refs, b->refs, sizeof(refs));
if(b->refs[j] > 0) putbuf(b);
switch(checkblk(blk)) { for(j = 0; j < REFPERBLK; j++, blk++){
if(refs[j] > 0 && refs[j] != REFSENTINEL){
switch(checkblk(blk)){
case TDENTRY: case TDENTRY:
ndentry++; ndentry++;
break; break;
@ -210,8 +220,8 @@ cmdcheck(int, char**)
nsuperblock++; nsuperblock++;
break; break;
} }
}
} }
putbuf(b);
} }
wunlock(fsmain); wunlock(fsmain);
dprint("%T block count %ulld\n", TDENTRY, ndentry); dprint("%T block count %ulld\n", TDENTRY, ndentry);
@ -454,6 +464,7 @@ Cmd cmds[] = {
{"allow", 1, cmdallow}, {"allow", 1, cmdallow},
{"noauth", 1, cmdnoauth}, {"noauth", 1, cmdnoauth},
{"chatty", 1, cmdchatty}, {"chatty", 1, cmdchatty},
{"check", 0, cmdcheck},
{"create", 0, cmdcreate}, {"create", 0, cmdcreate},
{"disallow", 1, cmddisallow}, {"disallow", 1, cmddisallow},
{"dump", 1, cmddump}, {"dump", 1, cmddump},

View file

@ -87,6 +87,7 @@ enum {
OFFPERBLK = RBLOCK / 12, OFFPERBLK = RBLOCK / 12,
REFSIZ = 3, REFSIZ = 3,
REFPERBLK = RBLOCK / REFSIZ, REFPERBLK = RBLOCK / REFSIZ,
REFSENTINEL = (1 << 8*REFSIZ) - 1,
}; };
struct BufReq { struct BufReq {