hjfs: add simple scan check of directory entry blocks

This commit is contained in:
spew 2017-03-27 21:27:45 -05:00
parent e02bc28aaf
commit 2e64925b91
5 changed files with 94 additions and 79 deletions

View file

@ -1,72 +0,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;
}

View file

@ -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;
}

View file

@ -54,4 +54,3 @@ int ingroup(Fs *, short, short, int);
void workerinit(void);
void writeusers(Fs *);
void readusers(Fs *);
int checkblk(uvlong);

View file

@ -52,13 +52,13 @@ getdent(FLoc *l, Buf *b)
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 @@ getfree(Fs *fs, uvlong *r)
}
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);

View file

@ -13,7 +13,6 @@ OFILES=\
9p.$O\
dump.$O\
cons.$O\
check.$O\
HFILES=\
dat.h\