hjfs: import improvements from 9front

This commit is contained in:
Giacomo Tesio 2017-08-11 05:09:34 +02:00
parent fa0a121f17
commit 6d242b3aa0
10 changed files with 219 additions and 69 deletions

View File

@ -114,7 +114,7 @@ tdestroyfid(Fid *fid)
}
static void
tend(Srv* _1)
tend(Srv* _)
{
shutdown();
}
@ -175,7 +175,7 @@ twalk(Chan *ch, Fid *fid, Fid *nfid, int n, char **name, Qid *qid)
}
static void
workerproc(void* _1)
workerproc(void* _)
{
Chan *ch;
Req *req;

View File

@ -456,7 +456,7 @@ found:
}
continue;
erropt:
dprint("hjfs: newuser: ignoring erroneous option %s\n", argv[i]);
dprint("newuser: ignoring erroneous option %s\n", argv[i]);
}
if(resort)
qsort(fs->udata, fs->nudata, sizeof(User), usercomp);

View File

@ -189,7 +189,7 @@ handlesync(Channel *resp)
}
static void
bufproc(void* _1)
bufproc(void* _)
{
BufReq req;
Buf *buf;
@ -273,8 +273,8 @@ getbuf(Dev *d, uint64_t off, int type, int nodata)
}
if(nodata)
b->type = type;
if(b->type != type && type != -1){
dprint("hjfs: type mismatch, dev %s, block %lld, got %T, want %T, caller %#p\n",
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());
werrstr("phase error -- type mismatch");
putbuf(b);

View File

@ -65,38 +65,38 @@ walkpath(Chan *ch, char *path, char **cr)
}
int
cmdsync(int _1, char** _2)
cmdsync(int _, char** __)
{
sync(1);
dprint("hjfs: sync\n");
dprint("sync\n");
return 0;
}
int
cmdhalt(int _1, char** _2)
cmdhalt(int _, char** __)
{
shutdown();
return 0;
}
int
cmddump(int _1, char** _2)
cmddump(int _, char** __)
{
fsdump(fsmain);
dprint("hjfs: dumped\n");
dprint("dumped\n");
return 0;
}
int
cmdallow(int _1, char** _2)
cmdallow(int _, char** __)
{
fsmain->flags |= FSNOPERM | FSCHOWN;
dprint("hjfs: allow\n");
dprint("allow\n");
return 0;
}
int
cmdchatty(int _1, char** _2)
cmdchatty(int _, char** __)
{
extern int chatty9p;
@ -104,22 +104,160 @@ cmdchatty(int _1, char** _2)
return 0;
}
static void
checkfile(FLoc *l, Buf *b)
{
Buf *c;
Dentry *d;
char *ftype;
int btype, rc;
uint64_t 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 < blocks; i++){
rc = getblk(fsmain, l, b, i, &r, GBREAD);
if(rc < 0){
dprint("bad block %ulld of %ulld in %s %s with directory entry index %d in block %ulld: %r\n", i, blocks, ftype, d->name, l->deind, l->blk);
continue;
}
if(rc == 0){
dprint("block %ulld of %ulld not found in %s %s with directory index %d in block %ulld\n", i, blocks, ftype, d->name, l->deind, l->blk);
continue;
}
c = getbuf(fsmain->d, r, btype, 0);
if(c == nil)
dprint("bad block %ulld of %ulld in %s %s with directory entry index %d in block %ulld: %r\n", i, blocks, ftype, d->name, l->deind, l->blk);
putbuf(c);
if(chref(fsmain, r, 0) == 0)
dprint("block %ulld of %ulld in %s %s with directory entry index %d in block %ulld has a reference count of 0", i, blocks, ftype, d->name, l->deind, l->blk);
}
}
static int
checkblk(uint64_t 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:
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;
}
putbuf(b);
return type;
}
int
cmddisallow(int _1, char** _2)
cmdcheck(int _, char** __)
{
static uint32_t refs[REFPERBLK];
uint64_t fblk, fend, blk;
uint64_t ndentry, nindir, nraw, nref, nsuperblock;
int j;
Buf *b, *sb;
wlock(fsmain);
sb = getbuf(fsmain->d, SUPERBLK, TSUPERBLOCK, 0);
if(sb == nil){
wunlock(fsmain);
return -1;
}
fblk = sb->sb.fstart;
fend = sb->sb.fend;
putbuf(sb);
ndentry = 0;
nindir = 0;
nraw = 0;
nref = 0;
nsuperblock = 0;
for(blk = 0; fblk < fend; fblk++){
b = getbuf(fsmain->d, fblk, TREF, 0);
if(b == nil){
blk += REFPERBLK;
continue;
}
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;
case TINDIR:
nindir++;
break;
case TRAW:
nraw++;
break;
case TREF:
nref++;
break;
case TSUPERBLOCK:
nsuperblock++;
break;
}
}
}
}
wunlock(fsmain);
dprint("%T block count %ulld\n", TDENTRY, ndentry);
dprint("%T block count %ulld\n", TINDIR, nindir);
dprint("%T block count %ulld\n", TRAW, nraw);
dprint("%T block count %ulld\n", TREF, nref);
dprint("%T block count %ulld\n", TSUPERBLOCK, nsuperblock);
return 1;
}
int
cmddisallow(int _, char** __)
{
fsmain->flags &= ~(FSNOPERM | FSCHOWN);
dprint("hjfs: disallow\n");
dprint("disallow\n");
return 0;
}
int
cmdnoauth(int _1, char** _2)
cmdnoauth(int _, char** __)
{
fsmain->flags ^= FSNOAUTH;
if((fsmain->flags & FSNOAUTH) == 0)
dprint("hjfs: auth enabled\n");
dprint("auth enabled\n");
else
dprint("hjfs: auth disabled\n");
dprint("auth disabled\n");
return 1;
}
@ -169,14 +307,14 @@ cmdcreate(int argc, char **argv)
}
int
cmdecho(int _1, char **argv)
cmdecho(int _, char **argv)
{
echo = strcmp(argv[1], "on") == 0;
return 1;
}
int
cmddf(int _1, char** _2)
cmddf(int _, char** __)
{
uint64_t n;
uint64_t i;
@ -199,15 +337,15 @@ cmddf(int _1, char** _2)
n++;
putbuf(b);
}
dprint("hjfs: (blocks) free %ulld, used %ulld, total %ulld\n", n, sb->sb.size - n, sb->sb.size);
dprint("hjfs: (MB) free %ulld, used %ulld, total %ulld\n", n * BLOCK / 1048576, (sb->sb.size - n) * BLOCK / 1048576, sb->sb.size * BLOCK / 1048576);
dprint("(blocks) free %ulld, used %ulld, total %ulld\n", n, sb->sb.size - n, sb->sb.size);
dprint("(MB) free %ulld, used %ulld, total %ulld\n", n * BLOCK / 1048576, (sb->sb.size - n) * BLOCK / 1048576, sb->sb.size * BLOCK / 1048576);
putbuf(sb);
wunlock(fsmain);
return 1;
}
int
cmddebugdeind(int _1, char **argv)
cmddebugdeind(int _, char **argv)
{
Chan *ch;
Buf *b;
@ -220,18 +358,18 @@ cmddebugdeind(int _1, char **argv)
if(walkpath(ch, argv[1], nil) < 0)
goto error;
rlock(fsmain);
dprint("hjfs: loc %ulld / %uld, offset %ulld\n", ch->loc->blk, ch->loc->deind, BLOCK * ch->loc->blk + (RBLOCK - BLOCK) + DENTRYSIZ * ch->loc->deind);
dprint("loc %ulld / %uld, offset %ulld\n", ch->loc->blk, ch->loc->deind, BLOCK * ch->loc->blk + (RBLOCK - BLOCK) + DENTRYSIZ * ch->loc->deind);
b = getbuf(fsmain->d, ch->loc->blk, TDENTRY, 0);
if(b == nil){
runlock(fsmain);
goto error;
}
d = &b->de[ch->loc->deind];
dprint("hjfs: name %s\n", d->name);
dprint("hjfs: uid %d, muid %d, gid %d\n", d->uid, d->muid, d->gid);
dprint("hjfs: mode %#o, qid %ulld, type %#x, version %d\n", d->mode, d->path, d->type, d->vers);
dprint("hjfs: size %d\n", d->size);
dprint("hjfs: atime %ulld, mtime %ulld\n", d->atime, d->mtime);
dprint("name %s\n", d->name);
dprint("uid %d, muid %d, gid %d\n", d->uid, d->muid, d->gid);
dprint("mode %#o, qid %ulld, type %#x, version %d\n", d->mode, d->path, d->type, d->vers);
dprint("size %d\n", d->size);
dprint("atime %ulld, mtime %ulld\n", d->atime, d->mtime);
putbuf(b);
runlock(fsmain);
chanclunk(ch);
@ -242,7 +380,7 @@ error:
}
int
cmddebugchdeind(int _1, char **argv)
cmddebugchdeind(int _, char **argv)
{
Chan *ch;
uint8_t *c;
@ -266,7 +404,7 @@ cmddebugchdeind(int _1, char **argv)
goto error;
}
c = (uint8_t *) &b->de[ch->loc->deind];
dprint("hjfs: loc %d, old value %#.2x, new value %#.2x\n", loc, c[loc], new);
dprint("loc %d, old value %#.2x, new value %#.2x\n", loc, c[loc], new);
c[loc] = new;
b->op |= BDELWRI;
putbuf(b);
@ -308,11 +446,11 @@ cmddebuggetblk(int argc, char **argv)
for(i = start; i <= end; i++){
rc = getblk(fsmain, ch->loc, b, i, &r, GBREAD);
if(rc > 0)
dprint("hjfs: getblk %ulld = %ulld\n", i, r);
dprint("getblk %ulld = %ulld\n", i, r);
if(rc == 0)
dprint("hjfs: getblk %ulld not found\n", i);
dprint("getblk %ulld not found\n", i);
if(rc < 0)
dprint("hjfs: getblk %ulld: %r\n", i);
dprint("getblk %ulld: %r\n", i);
}
putbuf(b);
runlock(fsmain);
@ -324,7 +462,7 @@ error:
}
int
cmdusers(int _1, char** _2)
cmdusers(int _, char** __)
{
readusers(fsmain);
return 0;
@ -336,6 +474,7 @@ Cmd cmds[] = {
{"allow", 1, cmdallow},
{"noauth", 1, cmdnoauth},
{"chatty", 1, cmdchatty},
// {"check", 0, cmdcheck},
{"create", 0, cmdcreate},
{"disallow", 1, cmddisallow},
{"dump", 1, cmddump},
@ -366,7 +505,7 @@ consproc(void *v)
if(s == nil)
continue;
if(echo)
dprint("hjfs: >%s\n", s);
dprint(">%s\n", s);
rc = tokenize(s, args, MAXARGS);
if(rc == 0)
goto syntax;
@ -379,12 +518,12 @@ consproc(void *v)
if(rc == -9001)
goto syntax;
if(rc < 0)
dprint("hjfs: %r\n");
dprint("%r\n");
goto done;
}
}
syntax:
dprint("hjfs: syntax error\n");
dprint("syntax error\n");
done:
free(s);
}

View File

@ -79,8 +79,15 @@ struct Dentry {
enum {
DENTRYSIZ = NAMELEN + 4 * sizeof(uint16_t) + 13 + (3 + NDIRECT + NINDIRECT) * sizeof(uint64_t),
DEPERBLK = RBLOCK / DENTRYSIZ,
/* Given any opportunity to make a breaking change to hjfs,
* make this 12 an 8. Indirect offsets to blocks used to
* hold an incrementing 4 byte generation number. That
* design has changed.
*/
OFFPERBLK = RBLOCK / 12,
REFPERBLK = RBLOCK / 3,
REFSIZ = 3,
REFPERBLK = RBLOCK / REFSIZ,
REFSENTINEL = (1 << 8*REFSIZ) - 1,
};
struct BufReq {
@ -184,8 +191,8 @@ enum {
CHREAD = 1,
CHWRITE = 2,
CHRCLOSE = 4,
CHFDUMP = 1,
CHFDUMP = 1,
CHFNOLOCK = 2,
CHFRO = 4,
CHFNOPERM = 8,
@ -232,5 +239,4 @@ enum { /* getblk modes */
GBOVERWR = 3,
};
#define HOWMANY(a, b) (((a)+((b)-1))/(b))
#define ROUNDUP(a, b) (HOWMANY(a,b)*(b))
#define HOWMANY(a) (((a)+(RBLOCK-1))/RBLOCK)

View File

@ -35,7 +35,7 @@ devwork(void *v)
memset(buf, 0, sizeof(buf));
pack(b, buf);
if(pwrite(d->fd, buf, BLOCK, b->off*BLOCK) < BLOCK){
dprint("hjfs: write: %r\n");
dprint("write: %r\n");
b->error = Eio;
}
}else{
@ -44,7 +44,7 @@ devwork(void *v)
for(n = 0; n < BLOCK; n += m){
m = pread(d->fd, buf+n, BLOCK-n, b->off*BLOCK+n);
if(m < 0)
dprint("hjfs: read: %r\n");
dprint("read: %r\n");
if(m <= 0)
break;
}

View File

@ -135,7 +135,7 @@ again:
if(rc < 0)
goto err;
if(rc == 0){
dprint("hjfs: willmodify: block %lld has refcount 0\n", l->blk);
dprint("willmodify: block %lld has refcount 0\n", l->blk);
werrstr("phase error -- willmodify");
goto err;
}

View File

@ -50,15 +50,15 @@ getdent(FLoc *l, Buf *b)
d = &b->de[l->deind];
if((d->mode & (DGONE | DALLOC)) == 0){
dprint("hjfs: getdent: file gone, d=%llux, l=%llud/%d %llux, callerpc %#p\n",
dprint("getdent: file gone, d=%llux, l=%llud/%d %llux, callerpc %#p\n",
d->path, l->blk, l->deind, l->path, getcallerpc());
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",
dprint("getdent: wrong qid d=%llux != l=%llud/%d %llux, callerpc %#p\n",
d->path, l->blk, l->deind, l->path, getcallerpc());
werrstr("phase error -- getdent");
werrstr("phase error -- qid mismatch");
return nil;
}
return d;
@ -88,8 +88,10 @@ getfree(Fs *fs, uint64_t *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);
@ -106,8 +108,7 @@ getfree(Fs *fs, uint64_t *r)
b->refs[j] = 1;
*r = l;
have = 1;
}
else if(nbsend(fs->freelist, &l) <= 0)
}else if(nbsend(fs->freelist, &l) <= 0)
goto found;
}
if(have)
@ -237,7 +238,7 @@ readusers(Fs *fs)
err:
if(ch != nil)
chanclunk(ch);
dprint("hjfs: readusers: %r\nhjfs: using default user db\n");
dprint("readusers: %r\nhjfs: using default user db\n");
}
void
@ -249,7 +250,7 @@ ream(Fs *fs)
int j, je;
d = fs->d;
dprint("hjfs: reaming %s\n", d->name);
dprint("reaming %s\n", d->name);
b = getbuf(d, SUPERBLK, TSUPERBLOCK, 1);
if(b == nil)
err:
@ -259,7 +260,7 @@ ream(Fs *fs)
b->sb.size = d->size;
b->sb.fstart = SUPERBLK + 1;
fs->fstart = b->sb.fstart;
b->sb.fend = b->sb.fstart + HOWMANY(b->sb.size * 3, RBLOCK);
b->sb.fend = b->sb.fstart + HOWMANY(b->sb.size * REFSIZ);
b->sb.qidpath = DUMPROOTQID + 1;
firsti = b->sb.fstart + SUPERBLK / REFPERBLK;
lasti = b->sb.fstart + b->sb.fend / REFPERBLK;
@ -267,7 +268,7 @@ ream(Fs *fs)
c = getbuf(d, i, TREF, 1);
if(c == nil)
goto err;
memset(c->refs, 0, sizeof(b->data));
memset(c->refs, 0, sizeof(c->refs));
if(i >= firsti && i <= lasti){
j = 0;
je = REFPERBLK;
@ -291,7 +292,7 @@ ream(Fs *fs)
putbuf(b);
createroot(fs);
sync(1);
dprint("hjfs: ream successful\n");
dprint("ream successful\n");
}
Fs *
@ -325,7 +326,7 @@ initfs(Dev *d, int doream, int flags)
if(doream)
writeusers(fs);
readusers(fs);
dprint("hjfs: fs is %s\n", d->name);
dprint("fs is %s\n", d->name);
return fs;
error:
@ -450,7 +451,7 @@ freeit:
if((l->flags & LGONE) != 0){
/*
* safe to unlock here, the file is gone and
* we'r the last reference.
* we're the last reference.
*/
qunlock(&fs->loctree);
b = getbuf(fs->d, l->blk, TDENTRY, 0);
@ -480,7 +481,7 @@ freeit:
}
static int
dumpblk(Fs *fs, FLoc * _1, uint64_t *l)
dumpblk(Fs *fs, FLoc * _, uint64_t *l)
{
uint64_t n;
int i;
@ -568,7 +569,7 @@ getblk(Fs *fs, FLoc *L, Buf *bd, uint64_t blk, uint64_t *r, int mode)
b = bd;
d = getdent(L, b);
if(d == nil){
dprint("hjfs: getblk: dirent gone\n");
dprint("getblk: dirent gone\n");
return -1;
}
if(blk < NDIRECT){
@ -653,7 +654,7 @@ found:
if(rc < 0)
goto end;
if(rc == 0){
dprint("hjfs: getblk: block %lld has refcount 0\n");
dprint("getblk: block %lld has refcount 0\n");
werrstr("phase error -- getblk");
rc = -1;
goto end;
@ -760,7 +761,7 @@ trunc(Fs *fs, FLoc *ll, Buf *bd, uint64_t size)
return -1;
if(size >= d->size)
goto done;
blk = HOWMANY(size, RBLOCK);
blk = HOWMANY(size);
while(blk < NDIRECT){
if(d->db[blk] != 0){
putfree(fs, d->db[blk]);

View File

@ -100,7 +100,6 @@ namevalid(char *name)
return p - name < NAMELEN;
}
int
chancreat(Chan *ch, char *name, int perm, int mode)
{

View File

@ -65,17 +65,22 @@ Fs *fsmain;
int
dprint(char *fmt, ...)
{
static char buf[2048];
static QLock lk;
va_list va;
int rc;
qlock(&lk);
va_start(va, fmt);
rc = vfprint(2, fmt, va);
snprint(buf, 2048, "hjfs: %s", fmt);
rc = vfprint(2, buf, va);
va_end(va);
qunlock(&lk);
return rc;
}
static void
syncproc(void * _1)
syncproc(void * _)
{
for(;;){
sync(0);
@ -149,7 +154,7 @@ shutdown(void)
{
wlock(fsmain);
sync(1);
dprint("hjfs: ending\n");
dprint("ending\n");
sleep(1000);
sync(1);
threadexitsall(nil);