ref: 1c13d41b8c1f2b94c5e9dcbf3154252c823f14d3
parent: e51044884b329d808015c7972d1c8409303faab3
author: spew <devnull@localhost>
date: Tue Mar 28 16:39:14 EDT 2017
hjfs: Fix bugs in ref count scan check. Enable as a console command (caveat: command arguments will change as I implement more functionality)
--- a/sys/src/cmd/hjfs/buf.c
+++ b/sys/src/cmd/hjfs/buf.c
@@ -273,7 +273,7 @@
}
if(nodata)
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",d->name, off, b->type, type, getcallerpc(&d));
werrstr("phase error -- type mismatch");--- a/sys/src/cmd/hjfs/cons.c
+++ b/sys/src/cmd/hjfs/cons.c
@@ -110,20 +110,26 @@
Dentry *d;
char *ftype;
int btype;
- uvlong i, r;
+ uvlong i, r, blocks;
d = getdent(l, b);
+ if(d == nil){+ dprint("checkfile: bad entry: %r\n");+ return;
+ }
if((d->type & QTDIR) == 0){ftype = "file";
btype = TRAW;
+ blocks = HOWMANY(d->size);
}else{ftype = "directory";
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){- 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;
}
c = getbuf(fsmain->d, r, btype, 0);
@@ -148,19 +154,20 @@
return -1;
switch(type = b->type){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;
case TDENTRY:
l.blk = blk;
for(i = 0; i < DEPERBLK; i++){d = &b->de[i];
+ if((d->mode & (DGONE | DALLOC)) == 0)
+ break;
l.deind = i;
l.Qid = d->Qid;
checkfile(&l, b);
}
break;
- case TINDIR:
- break;
}
putbuf(b);
return type;
@@ -169,6 +176,7 @@
int
cmdcheck(int, char**)
{+ static ulong refs[REFPERBLK];
uvlong fblk, fend, blk;
uvlong ndentry, nindir, nraw, nref, nsuperblock;
int j;
@@ -191,9 +199,11 @@
blk += REFPERBLK;
continue;
}
- for(j = 0; j < REFPERBLK; j++, blk++) {- if(b->refs[j] > 0)
- switch(checkblk(blk)) {+ memcpy(refs, b->refs, sizeof(refs));
+ putbuf(b);
+ for(j = 0; j < REFPERBLK; j++, blk++){+ if(refs[j] > 0 && refs[j] != REFSENTINEL){+ switch(checkblk(blk)){case TDENTRY:
ndentry++;
break;
@@ -210,8 +220,8 @@
nsuperblock++;
break;
}
+ }
}
- putbuf(b);
}
wunlock(fsmain);
dprint("%T block count %ulld\n", TDENTRY, ndentry);@@ -454,6 +464,7 @@
{"allow", 1, cmdallow}, {"noauth", 1, cmdnoauth}, {"chatty", 1, cmdchatty},+ {"check", 0, cmdcheck}, {"create", 0, cmdcreate}, {"disallow", 1, cmddisallow}, {"dump", 1, cmddump},--- a/sys/src/cmd/hjfs/dat.h
+++ b/sys/src/cmd/hjfs/dat.h
@@ -87,6 +87,7 @@
OFFPERBLK = RBLOCK / 12,
REFSIZ = 3,
REFPERBLK = RBLOCK / REFSIZ,
+ REFSENTINEL = (1 << 8*REFSIZ) - 1,
};
struct BufReq {--
⑨