ref: 2e64925b91b4fc19d770dc685c3182121ce6e551
parent: e02bc28aaf0acd21195914dc1f116651ade2b7b5
author: spew <devnull@localhost>
date: Mon Mar 27 17:27:45 EDT 2017
hjfs: add simple scan check of directory entry blocks
--- a/sys/src/cmd/hjfs/check.c
+++ /dev/null
@@ -1,72 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <thread.h>
-#include "dat.h"
-#include "fns.h"
-
-extern Fs *fsmain;
-
-static void
-checkdir(FLoc *l, Buf *b)
-{
- Buf *c;
- Dentry *d;
- uvlong i, r;
-
- d = getdent(l, b);
- for(i = 0; i < d->size; i++){
- if(getblk(fsmain, l, b, i, &r, GBREAD) <= 0) {
- dprint("hjfs: directory in block %ulld at index %d has a bad block %ulld at directory index %ulld\n", l->blk, l->deind, r, i);
- continue;
- }
- c = getbuf(fsmain->d, r, TDENTRY, 0);
- if(c == nil) {
- dprint("hjfs: directory in block %ulld at index %d has a block %ulld at directory index %ulld that is not a directory entry\n", l->blk, l->deind, r, i);
- continue;
- }
- if(chref(fsmain, r, 0) == 0)
- dprint("hjfs: directory in block %ulld at index %d has a block %ulld at index %ulld whose reference count is 0");
- }
-}
-
-static void
-checkfile(FLoc*, Buf*)
-{}
-
-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 TRAW:
- break;
- 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;
- if((d->type & QTDIR) != 0)
- checkdir(&l, b);
- else
- checkfile(&l, b);
- }
- break;
- case TINDIR:
- break;
- case TREF:
- break;
- }
- putbuf(b);
- return type;
-}
--- a/sys/src/cmd/hjfs/cons.c
+++ b/sys/src/cmd/hjfs/cons.c
@@ -103,10 +103,74 @@
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,6 +184,7 @@
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){
@@ -126,12 +191,34 @@
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;
}
--- a/sys/src/cmd/hjfs/fns.h
+++ b/sys/src/cmd/hjfs/fns.h
@@ -54,4 +54,3 @@
void workerinit(void);
void writeusers(Fs *);
void readusers(Fs *);
-int checkblk(uvlong);
--- a/sys/src/cmd/hjfs/fs1.c
+++ b/sys/src/cmd/hjfs/fs1.c
@@ -52,13 +52,13 @@
if((d->mode & (DGONE | DALLOC)) == 0){
dprint("hjfs: getdent: file gone, d=%llux, l=%llud/%d %llux, callerpc %#p\n",
d->path, l->blk, l->deind, l->path, getcallerpc(&l));
- werrstr("phase error -- getdent");
+ werrstr("phase error -- directory entry for nonexistent file");
return nil;
}
if(qidcmp(d, l) != 0){
dprint("hjfs: getdent: wrong qid d=%llux != l=%llud/%d %llux, callerpc %#p\n",
d->path, l->blk, l->deind, l->path, getcallerpc(&l));
- werrstr("phase error -- getdent");
+ werrstr("phase error -- qid mismatch");
return nil;
}
return d;
@@ -88,8 +88,10 @@
}
b = getbuf(d, SUPERBLK, TSUPERBLOCK, 0);
- if(b == nil)
+ if(b == nil) {
+ werrstr("could not find superblock");
return -1;
+ }
e = b->sb.fend;
putbuf(b);
--- a/sys/src/cmd/hjfs/mkfile
+++ b/sys/src/cmd/hjfs/mkfile
@@ -13,7 +13,6 @@
9p.$O\
dump.$O\
cons.$O\
- check.$O\
HFILES=\
dat.h\