diff options
author | spew <devnull@localhost> | 2017-03-27 21:27:45 -0500 |
---|---|---|
committer | spew <devnull@localhost> | 2017-03-27 21:27:45 -0500 |
commit | 2e64925b91b4fc19d770dc685c3182121ce6e551 (patch) | |
tree | 97df0d3aaa06e87a50a8dfc36353a26be5a38ceb /sys/src/cmd/hjfs/cons.c | |
parent | e02bc28aaf0acd21195914dc1f116651ade2b7b5 (diff) |
hjfs: add simple scan check of directory entry blocks
Diffstat (limited to 'sys/src/cmd/hjfs/cons.c')
-rw-r--r-- | sys/src/cmd/hjfs/cons.c | 91 |
1 files changed, 89 insertions, 2 deletions
diff --git a/sys/src/cmd/hjfs/cons.c b/sys/src/cmd/hjfs/cons.c index b8b9278f1..b97e3610e 100644 --- a/sys/src/cmd/hjfs/cons.c +++ b/sys/src/cmd/hjfs/cons.c @@ -103,10 +103,74 @@ cmdchatty(int, char **) return 0; } +static void +checkfile(FLoc *l, Buf *b) +{ + Buf *c; + Dentry *d; + char *ftype; + int btype; + uvlong i, r; + + d = getdent(l, b); + if((d->type & QTDIR) == 0){ + ftype = "file"; + btype = TRAW; + }else{ + ftype = "directory"; + btype = TDENTRY; + } + + for(i = 0; i < d->size; i++){ + if(getblk(fsmain, l, b, i, &r, GBREAD) <= 0){ + dprint("hjfs: %s in block %ulld at index %d has a bad block at index %ulld: %r\n", ftype, l->blk, l->deind, i); + continue; + } + c = getbuf(fsmain->d, r, btype, 0); + if(c == nil) + dprint("hjfs: %s in block %ulld at index %d has a bad block %ulld at directory index %ulld: %r\n", ftype, l->blk, l->deind, r, i); + putbuf(c); + if(chref(fsmain, r, 0) == 0) + dprint("hjfs: %s in block %ulld at index %d has a block %ulld at index %ulld whose reference count is 0", ftype, l->blk, l->deind, r, i); + } +} + +static int +checkblk(uvlong blk) +{ + Dentry *d; + Buf *b; + FLoc l; + int i, type; + + b = getbuf(fsmain->d, blk, TDONTCARE, 0); + if(b == nil) + return -1; + switch(type = b->type){ + case TSUPERBLOCK: + dprint("hjfs: 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]; + l.deind = i; + l.Qid = d->Qid; + checkfile(&l, b); + } + break; + case TINDIR: + break; + } + putbuf(b); + return type; +} + int cmdcheck(int, char**) { uvlong fblk, fend, blk; + uvlong ndentry, nindir, nraw, nref, nsuperblock; int j; Buf *b, *sb; @@ -120,18 +184,41 @@ cmdcheck(int, char**) fend = sb->sb.fend; putbuf(sb); + ndentry = nindir = nraw = nref = nsuperblock = 0; for(blk = 0; fblk < fend; fblk++){ b = getbuf(fsmain->d, fblk, TREF, 0); if(b == nil){ blk += REFPERBLK; continue; } - for(j = 0; j < REFPERBLK; j++, blk++) + for(j = 0; j < REFPERBLK; j++, blk++) { if(b->refs[j] > 0) - checkblk(blk); + switch(checkblk(blk)) { + case TDENTRY: + ndentry++; + break; + case TINDIR: + nindir++; + break; + case TRAW: + nraw++; + break; + case TREF: + nref++; + break; + case TSUPERBLOCK: + nsuperblock++; + break; + } + } putbuf(b); } wunlock(fsmain); + dprint("hjfs: %T block count %ulld\n", TDENTRY, ndentry); + dprint("hjfs: %T block count %ulld\n", TINDIR, nindir); + dprint("hjfs: %T block count %ulld\n", TRAW, nraw); + dprint("hjfs: %T block count %ulld\n", TREF, nref); + dprint("hjfs: %T block count %ulld\n", TSUPERBLOCK, nsuperblock); return 1; } |