From 1c13d41b8c1f2b94c5e9dcbf3154252c823f14d3 Mon Sep 17 00:00:00 2001 From: spew Date: Tue, 28 Mar 2017 20:39:14 -0500 Subject: [PATCH] hjfs: Fix bugs in ref count scan check. Enable as a console command (caveat: command arguments will change as I implement more functionality) --- sys/src/cmd/hjfs/buf.c | 2 +- sys/src/cmd/hjfs/cons.c | 31 +++++++++++++++++++++---------- sys/src/cmd/hjfs/dat.h | 1 + 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/sys/src/cmd/hjfs/buf.c b/sys/src/cmd/hjfs/buf.c index b8eca9bdf..e739e3a55 100644 --- a/sys/src/cmd/hjfs/buf.c +++ b/sys/src/cmd/hjfs/buf.c @@ -273,7 +273,7 @@ getbuf(Dev *d, uvlong off, int type, int nodata) } 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"); diff --git a/sys/src/cmd/hjfs/cons.c b/sys/src/cmd/hjfs/cons.c index 00312f557..5b5acbe34 100644 --- a/sys/src/cmd/hjfs/cons.c +++ b/sys/src/cmd/hjfs/cons.c @@ -110,20 +110,26 @@ checkfile(FLoc *l, Buf *b) 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 @@ checkblk(uvlong blk) 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 @@ checkblk(uvlong blk) int cmdcheck(int, char**) { + static ulong refs[REFPERBLK]; uvlong fblk, fend, blk; uvlong ndentry, nindir, nraw, nref, nsuperblock; int j; @@ -191,9 +199,11 @@ cmdcheck(int, char**) 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 @@ cmdcheck(int, char**) nsuperblock++; break; } + } } - putbuf(b); } wunlock(fsmain); dprint("%T block count %ulld\n", TDENTRY, ndentry); @@ -454,6 +464,7 @@ Cmd cmds[] = { {"allow", 1, cmdallow}, {"noauth", 1, cmdnoauth}, {"chatty", 1, cmdchatty}, + {"check", 0, cmdcheck}, {"create", 0, cmdcreate}, {"disallow", 1, cmddisallow}, {"dump", 1, cmddump}, diff --git a/sys/src/cmd/hjfs/dat.h b/sys/src/cmd/hjfs/dat.h index bc336a7b2..0a7ff5167 100644 --- a/sys/src/cmd/hjfs/dat.h +++ b/sys/src/cmd/hjfs/dat.h @@ -87,6 +87,7 @@ enum { OFFPERBLK = RBLOCK / 12, REFSIZ = 3, REFPERBLK = RBLOCK / REFSIZ, + REFSENTINEL = (1 << 8*REFSIZ) - 1, }; struct BufReq {