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:
parent
e51044884b
commit
1c13d41b8c
|
@ -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");
|
||||||
|
|
|
@ -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},
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue