From 6d242b3aa03cac144e39962deec195d56d2819ad Mon Sep 17 00:00:00 2001 From: Giacomo Tesio Date: Fri, 11 Aug 2017 05:09:34 +0200 Subject: [PATCH] hjfs: import improvements from 9front --- sys/src/cmd/hjfs/9p.c | 4 +- sys/src/cmd/hjfs/auth.c | 2 +- sys/src/cmd/hjfs/buf.c | 6 +- sys/src/cmd/hjfs/cons.c | 205 +++++++++++++++++++++++++++++++++------- sys/src/cmd/hjfs/dat.h | 14 ++- sys/src/cmd/hjfs/dev.c | 4 +- sys/src/cmd/hjfs/dump.c | 2 +- sys/src/cmd/hjfs/fs1.c | 37 ++++---- sys/src/cmd/hjfs/fs2.c | 1 - sys/src/cmd/hjfs/main.c | 13 ++- 10 files changed, 219 insertions(+), 69 deletions(-) diff --git a/sys/src/cmd/hjfs/9p.c b/sys/src/cmd/hjfs/9p.c index 36a2e76..486f7e6 100644 --- a/sys/src/cmd/hjfs/9p.c +++ b/sys/src/cmd/hjfs/9p.c @@ -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; diff --git a/sys/src/cmd/hjfs/auth.c b/sys/src/cmd/hjfs/auth.c index c36ade6..63e2f59 100644 --- a/sys/src/cmd/hjfs/auth.c +++ b/sys/src/cmd/hjfs/auth.c @@ -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); diff --git a/sys/src/cmd/hjfs/buf.c b/sys/src/cmd/hjfs/buf.c index 176f700..6549c05 100644 --- a/sys/src/cmd/hjfs/buf.c +++ b/sys/src/cmd/hjfs/buf.c @@ -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); diff --git a/sys/src/cmd/hjfs/cons.c b/sys/src/cmd/hjfs/cons.c index 0d8766b..e13a777 100644 --- a/sys/src/cmd/hjfs/cons.c +++ b/sys/src/cmd/hjfs/cons.c @@ -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); } diff --git a/sys/src/cmd/hjfs/dat.h b/sys/src/cmd/hjfs/dat.h index c464685..fada226 100644 --- a/sys/src/cmd/hjfs/dat.h +++ b/sys/src/cmd/hjfs/dat.h @@ -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) diff --git a/sys/src/cmd/hjfs/dev.c b/sys/src/cmd/hjfs/dev.c index 440a339..71fde37 100644 --- a/sys/src/cmd/hjfs/dev.c +++ b/sys/src/cmd/hjfs/dev.c @@ -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; } diff --git a/sys/src/cmd/hjfs/dump.c b/sys/src/cmd/hjfs/dump.c index f631b52..0b41360 100644 --- a/sys/src/cmd/hjfs/dump.c +++ b/sys/src/cmd/hjfs/dump.c @@ -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; } diff --git a/sys/src/cmd/hjfs/fs1.c b/sys/src/cmd/hjfs/fs1.c index 9233fea..33bf7d0 100644 --- a/sys/src/cmd/hjfs/fs1.c +++ b/sys/src/cmd/hjfs/fs1.c @@ -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]); diff --git a/sys/src/cmd/hjfs/fs2.c b/sys/src/cmd/hjfs/fs2.c index b70bde8..c1c8c3a 100644 --- a/sys/src/cmd/hjfs/fs2.c +++ b/sys/src/cmd/hjfs/fs2.c @@ -100,7 +100,6 @@ namevalid(char *name) return p - name < NAMELEN; } - int chancreat(Chan *ch, char *name, int perm, int mode) { diff --git a/sys/src/cmd/hjfs/main.c b/sys/src/cmd/hjfs/main.c index eb862d8..760fdd7 100644 --- a/sys/src/cmd/hjfs/main.c +++ b/sys/src/cmd/hjfs/main.c @@ -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);