hjfs: add simple scan check of directory entry blocks
This commit is contained in:
parent
e02bc28aaf
commit
2e64925b91
|
@ -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;
|
|
||||||
}
|
|
|
@ -103,10 +103,74 @@ cmdchatty(int, char **)
|
||||||
return 0;
|
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
|
int
|
||||||
cmdcheck(int, char**)
|
cmdcheck(int, char**)
|
||||||
{
|
{
|
||||||
uvlong fblk, fend, blk;
|
uvlong fblk, fend, blk;
|
||||||
|
uvlong ndentry, nindir, nraw, nref, nsuperblock;
|
||||||
int j;
|
int j;
|
||||||
Buf *b, *sb;
|
Buf *b, *sb;
|
||||||
|
|
||||||
|
@ -120,18 +184,41 @@ cmdcheck(int, char**)
|
||||||
fend = sb->sb.fend;
|
fend = sb->sb.fend;
|
||||||
putbuf(sb);
|
putbuf(sb);
|
||||||
|
|
||||||
|
ndentry = nindir = nraw = nref = nsuperblock = 0;
|
||||||
for(blk = 0; fblk < fend; fblk++){
|
for(blk = 0; fblk < fend; fblk++){
|
||||||
b = getbuf(fsmain->d, fblk, TREF, 0);
|
b = getbuf(fsmain->d, fblk, TREF, 0);
|
||||||
if(b == nil){
|
if(b == nil){
|
||||||
blk += REFPERBLK;
|
blk += REFPERBLK;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for(j = 0; j < REFPERBLK; j++, blk++)
|
for(j = 0; j < REFPERBLK; j++, blk++) {
|
||||||
if(b->refs[j] > 0)
|
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);
|
putbuf(b);
|
||||||
}
|
}
|
||||||
wunlock(fsmain);
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,4 +54,3 @@ int ingroup(Fs *, short, short, int);
|
||||||
void workerinit(void);
|
void workerinit(void);
|
||||||
void writeusers(Fs *);
|
void writeusers(Fs *);
|
||||||
void readusers(Fs *);
|
void readusers(Fs *);
|
||||||
int checkblk(uvlong);
|
|
||||||
|
|
|
@ -52,13 +52,13 @@ getdent(FLoc *l, Buf *b)
|
||||||
if((d->mode & (DGONE | DALLOC)) == 0){
|
if((d->mode & (DGONE | DALLOC)) == 0){
|
||||||
dprint("hjfs: getdent: file gone, d=%llux, l=%llud/%d %llux, callerpc %#p\n",
|
dprint("hjfs: getdent: file gone, d=%llux, l=%llud/%d %llux, callerpc %#p\n",
|
||||||
d->path, l->blk, l->deind, l->path, getcallerpc(&l));
|
d->path, l->blk, l->deind, l->path, getcallerpc(&l));
|
||||||
werrstr("phase error -- getdent");
|
werrstr("phase error -- directory entry for nonexistent file");
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
if(qidcmp(d, l) != 0){
|
if(qidcmp(d, l) != 0){
|
||||||
dprint("hjfs: getdent: wrong qid d=%llux != l=%llud/%d %llux, callerpc %#p\n",
|
dprint("hjfs: getdent: wrong qid d=%llux != l=%llud/%d %llux, callerpc %#p\n",
|
||||||
d->path, l->blk, l->deind, l->path, getcallerpc(&l));
|
d->path, l->blk, l->deind, l->path, getcallerpc(&l));
|
||||||
werrstr("phase error -- getdent");
|
werrstr("phase error -- qid mismatch");
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
return d;
|
return d;
|
||||||
|
@ -88,8 +88,10 @@ getfree(Fs *fs, uvlong *r)
|
||||||
}
|
}
|
||||||
|
|
||||||
b = getbuf(d, SUPERBLK, TSUPERBLOCK, 0);
|
b = getbuf(d, SUPERBLK, TSUPERBLOCK, 0);
|
||||||
if(b == nil)
|
if(b == nil) {
|
||||||
|
werrstr("could not find superblock");
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
e = b->sb.fend;
|
e = b->sb.fend;
|
||||||
putbuf(b);
|
putbuf(b);
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@ OFILES=\
|
||||||
9p.$O\
|
9p.$O\
|
||||||
dump.$O\
|
dump.$O\
|
||||||
cons.$O\
|
cons.$O\
|
||||||
check.$O\
|
|
||||||
|
|
||||||
HFILES=\
|
HFILES=\
|
||||||
dat.h\
|
dat.h\
|
||||||
|
|
Loading…
Reference in a new issue