From 34b0b3532283082d4a90afa728a1fc84b20a3f6f Mon Sep 17 00:00:00 2001 From: fredrik Date: Thu, 3 Aug 2006 01:36:38 +0000 Subject: [PATCH] Make blocktree indir block sizes variable. git-svn-id: svn+ssh://svn.dolda2000.com/srv/svn/repos/src/vcfs@679 959494ce-11ee-0310-bf91-de5d638817bd --- blocktree.c | 59 ++++++++++++++++++++++++++++++----------------------------- blocktree.h | 12 ++++-------- mkfs.vc.c | 6 +++--- vcfs.c | 23 ++++++++++++----------- vcfs.h | 3 +++ 5 files changed, 52 insertions(+), 51 deletions(-) diff --git a/blocktree.c b/blocktree.c index a973e8f..727628f 100644 --- a/blocktree.c +++ b/blocktree.c @@ -8,11 +8,11 @@ #define min(a, b) (((b) < (a))?(b):(a)) #define ISDELOP(op) (((op).buf == NULL) && ((op).fillfn == NULL)) -ssize_t btget(struct store *st, struct btnode *tree, block_t bl, void *buf, size_t len) +ssize_t btget(struct store *st, struct btnode *tree, block_t bl, void *buf, size_t len, size_t blsize) { int d; block_t c, sel; - struct btnode indir[BT_INDSZ]; + struct btnode indir[1 << blsize]; ssize_t sz; if(tree->d == 0) { @@ -24,7 +24,7 @@ ssize_t btget(struct store *st, struct btnode *tree, block_t bl, void *buf, size /* This check should really only be necessary on the first * iteration, but I felt it was easier to put it in the * loop. */ - if((bl >> (d * BT_INDBITS)) > 0) { + if((bl >> (d * blsize)) > 0) { errno = ERANGE; return(-1); } @@ -33,16 +33,16 @@ ssize_t btget(struct store *st, struct btnode *tree, block_t bl, void *buf, size return(storeget(st, buf, len, &tree->a)); /* Luckily, this is tail recursive */ - if((sz = storeget(st, indir, BT_INDBSZ, &tree->a)) < 0) + if((sz = storeget(st, indir, sizeof(indir), &tree->a)) < 0) return(-1); c = sz / sizeof(struct btnode); - sel = bl >> ((d - 1) * BT_INDBITS); + sel = bl >> ((d - 1) * blsize); if(sel >= c) { errno = ERANGE; return(-1); } tree = &indir[sel]; - bl &= (1LL << ((d - 1) * BT_INDBITS)) - 1; + bl &= (1LL << ((d - 1) * blsize)) - 1; } return(0); } @@ -88,12 +88,12 @@ static int countops(struct btop *ops, int numops, block_t bloff, block_t maxbl) * blputmany() in many ways makes the code uglier, but it saves a * *lot* of space, since it doesn't need to store intermediary blocks. */ -static int btputmany2(struct store *st, struct btnode *tree, struct btop *ops, int numops, block_t bloff) +static int btputmany2(struct store *st, struct btnode *tree, struct btop *ops, int numops, size_t blsize, block_t bloff) { int i, subops, d, f, hasid; block_t c, sel, bl, nextsz; struct addr na; - struct btnode indir[BT_INDSZ]; + struct btnode indir[1 << blsize]; ssize_t sz; d = tree->d & 0x7f; @@ -115,7 +115,7 @@ static int btputmany2(struct store *st, struct btnode *tree, struct btop *ops, i continue; } - if(f && (bl == (1LL << (d * BT_INDBITS)))) { + if(f && (bl == (1LL << (d * blsize)))) { /* New level of indirection */ if(hasid) { if(storeput(st, indir, c * sizeof(struct btnode), &na)) @@ -135,21 +135,21 @@ static int btputmany2(struct store *st, struct btnode *tree, struct btop *ops, i } /* Assume that numops == largest block number + 1 -- gaps * will be detected as errors later */ - for(bl = numops - 1; bl > 0; d++, bl <<= BT_INDBITS); + for(bl = numops - 1; bl > 0; d++, bl <<= blsize); tree->d = d; c = 0; hasid = 1; } else { /* Get indirect block */ if(!hasid) { - if((sz = storeget(st, indir, BT_INDBSZ, &tree->a)) < 0) + if((sz = storeget(st, indir, sizeof(indir), &tree->a)) < 0) return(-1); c = sz / sizeof(struct btnode); hasid = 1; } } - sel = bl >> ((d - 1) * BT_INDBITS); + sel = bl >> ((d - 1) * blsize); if(sel > c) { errno = ERANGE; return(-1); @@ -164,13 +164,13 @@ static int btputmany2(struct store *st, struct btnode *tree, struct btop *ops, i indir[c].d = 0; c++; } - nextsz = 1LL << ((d - 1) * BT_INDBITS); + nextsz = 1LL << ((d - 1) * blsize); subops = countops(ops + i, numops - i, bloff + (sel * nextsz), nextsz); - if(btputmany2(st, &indir[sel], ops + i, subops, bloff + (sel * nextsz))) + if(btputmany2(st, &indir[sel], ops + i, subops, blsize, bloff + (sel * nextsz))) return(-1); i += subops; - if((sel == BT_INDSZ - 1) && (indir[sel].d == ((d - 1) | 0x80))) { + if((sel == (1 << blsize) - 1) && (indir[sel].d == ((d - 1) | 0x80))) { /* Filled up */ tree->d |= 0x80; f = 1; @@ -190,19 +190,20 @@ static int btputmany2(struct store *st, struct btnode *tree, struct btop *ops, i return(0); } -int btputmany(struct store *st, struct btnode *tree, struct btop *ops, int numops) +int btputmany(struct store *st, struct btnode *tree, struct btop *ops, int numops, size_t blsize) { - return(btputmany2(st, tree, ops, numops, 0)); + return(btputmany2(st, tree, ops, numops, blsize, 0)); } -int btput(struct store *st, struct btnode *tree, block_t bl, void *buf, size_t len) +int btput(struct store *st, struct btnode *tree, block_t bl, void *buf, size_t len, size_t blsize) { - struct btop ops[1]; + struct btop ops; - ops[0].blk = bl; - ops[0].buf = buf; - ops[0].len = len; - return(btputmany(st, tree, ops, 1)); + memset(&ops, 0, sizeof(ops)); + ops.blk = bl; + ops.buf = buf; + ops.len = len; + return(btputmany(st, tree, &ops, 1, blsize)); } void btmkop(struct btop *op, block_t bl, void *buf, size_t len) @@ -230,10 +231,10 @@ void btsortops(struct btop *ops, int numops) qsort(ops, numops, sizeof(*ops), (int (*)(const void *, const void *))opcmp); } -block_t btcount(struct store *st, struct btnode *tree) +block_t btcount(struct store *st, struct btnode *tree, size_t blsize) { int d, f; - struct btnode indir[BT_INDSZ]; + struct btnode indir[1 << blsize]; block_t c, ret; ssize_t sz; @@ -241,21 +242,21 @@ block_t btcount(struct store *st, struct btnode *tree) f = tree->d & 0x80; if(f) - return(1LL << (d * BT_INDBITS)); + return(1LL << (d * blsize)); if(d == 0) return(0); ret = 0; while(1) { - if((sz = storeget(st, indir, BT_INDBSZ, &tree->a)) < 0) + if((sz = storeget(st, indir, sizeof(indir), &tree->a)) < 0) return(-1); c = sz / sizeof(struct btnode); - ret += (c - 1) * (1LL << ((d - 1) * BT_INDBITS)); + ret += (c - 1) * (1LL << ((d - 1) * blsize)); d = indir[c - 1].d & 0x7f; f = indir[c - 1].d & 0x80; if(f) - return(ret + (1LL << (d * BT_INDBITS))); + return(ret + (1LL << (d * blsize))); tree = &indir[c - 1]; } } diff --git a/blocktree.h b/blocktree.h index c962874..fd2ea99 100644 --- a/blocktree.h +++ b/blocktree.h @@ -4,10 +4,6 @@ #include "store.h" #include "inttypes.h" -#define BT_INDBITS 10 -#define BT_INDSZ (1 << BT_INDBITS) -#define BT_INDBSZ (sizeof(struct btnode) * BT_INDSZ) - typedef loff_t block_t; struct btnode { @@ -23,10 +19,10 @@ struct btop { void *pdata; }; -ssize_t btget(struct store *st, struct btnode *tree, block_t bl, void *buf, size_t len); -int btputmany(struct store *st, struct btnode *tree, struct btop *ops, int numops); -int btput(struct store *st, struct btnode *tree, block_t bl, void *buf, size_t len); -block_t btcount(struct store *st, struct btnode *tree); +ssize_t btget(struct store *st, struct btnode *tree, block_t bl, void *buf, size_t len, size_t blsize); +int btputmany(struct store *st, struct btnode *tree, struct btop *ops, int numops, size_t blsize); +int btput(struct store *st, struct btnode *tree, block_t bl, void *buf, size_t len, size_t blsize); +block_t btcount(struct store *st, struct btnode *tree, size_t blsize); void btsortops(struct btop *ops, int numops); void btmkop(struct btop *op, block_t bl, void *buf, size_t len); diff --git a/mkfs.vc.c b/mkfs.vc.c index a507abe..764c8e4 100644 --- a/mkfs.vc.c +++ b/mkfs.vc.c @@ -45,19 +45,19 @@ int main(int argc, char **argv) root.data.d = 0; root.xattr.d = 0; strcpy(dots.name, "."); - if(btput(st, &root.data, 0, &dots, sizeof(dots) - sizeof(dots.name) + 2)) { + if(btput(st, &root.data, 0, &dots, sizeof(dots) - sizeof(dots.name) + 2, DIRBLSIZE)) { fprintf(stderr, "mkfs.vc: could not create root directory entries: %s\n", strerror(errno)); exit(1); } strcpy(dots.name, ".."); - if(btput(st, &root.data, 1, &dots, sizeof(dots) - sizeof(dots.name) + 3)) { + if(btput(st, &root.data, 1, &dots, sizeof(dots) - sizeof(dots.name) + 3, DIRBLSIZE)) { fprintf(stderr, "mkfs.vc: could not create root directory entries: %s\n", strerror(errno)); exit(1); } frev.ct = now; frev.root.d = 0; - if(btput(st, &frev.root, 0, &root, sizeof(root))) { + if(btput(st, &frev.root, 0, &root, sizeof(root), INOBLSIZE)) { fprintf(stderr, "mkfs.vc: could not store root directory inode: %s\n", strerror(errno)); exit(1); } diff --git a/vcfs.c b/vcfs.c index ed1a57f..e49b437 100644 --- a/vcfs.c +++ b/vcfs.c @@ -226,7 +226,7 @@ static struct vcfsdata *initvcfs(char *dir) } fsd->inocser = 1; cacheinode(fsd, 0, nilnode); - if((fsd->nextino = btcount(fsd->st, &fsd->inotab)) < 0) { + if((fsd->nextino = btcount(fsd->st, &fsd->inotab, INOBLSIZE)) < 0) { flog(LOG_ERR, "could not count inodes: %s"); close(fsd->revfd); releasestore(fsd->st); @@ -243,7 +243,7 @@ static vc_ino_t dirlookup(struct vcfsdata *fsd, struct btnode *dirdata, const ch ssize_t sz; for(i = 0; ; i++) { - if((sz = btget(fsd->st, dirdata, i, &dent, sizeof(dent))) < 0) { + if((sz = btget(fsd->st, dirdata, i, &dent, sizeof(dent), DIRBLSIZE)) < 0) { if(errno == ERANGE) errno = ENOENT; return(-1); @@ -279,7 +279,7 @@ static int getinode(struct vcfsdata *fsd, struct btnode inotab, vc_ino_t ino, st if(inotab.d == 0) inotab = fsd->inotab; - if((sz = btget(fsd->st, &inotab, ino, buf, sizeof(*buf))) < 0) + if((sz = btget(fsd->st, &inotab, ino, buf, sizeof(*buf), INOBLSIZE)) < 0) return(-1); if(sz != sizeof(*buf)) { flog(LOG_ERR, "illegal size for inode %i", ino); @@ -364,7 +364,7 @@ static void fusereaddir(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, buf = NULL; while(bsz < size) { memset(&dent, 0, sizeof(dent)); - if((sz = btget(fsd->st, &file.data, off++, &dent, sizeof(dent))) < 0) { + if((sz = btget(fsd->st, &file.data, off++, &dent, sizeof(dent), DIRBLSIZE)) < 0) { if(errno == ERANGE) { if(buf != NULL) break; @@ -417,16 +417,17 @@ static int deldentry(struct vcfsdata *fsd, struct inode *ino, int di) return(-1); } if(di == ino->size - 1) { - if(btput(fsd->st, &ino->data, ino->size - 1, NULL, 0)) + if(btput(fsd->st, &ino->data, ino->size - 1, NULL, 0, DIRBLSIZE)) return(-1); } else { - if((sz = btget(fsd->st, &ino->data, ino->size - 1, &dent, sizeof(dent))) < 0) + if((sz = btget(fsd->st, &ino->data, ino->size - 1, &dent, sizeof(dent), DIRBLSIZE)) < 0) return(-1); btmkop(ops + 0, di, &dent, sz); btmkop(ops + 1, ino->size - 1, NULL, 0); - if(btputmany(fsd->st, &ino->data, ops, 2)) + if(btputmany(fsd->st, &ino->data, ops, 2, DIRBLSIZE)) return(-1); } + ino->size--; return(0); } @@ -444,12 +445,12 @@ static int setdentry(struct vcfsdata *fsd, struct inode *ino, int di, const char dent.inode = target; sz = sizeof(dent) - sizeof(dent.name) + strlen(name) + 1; if((di == -1) || (di == ino->size)) { - if(btput(fsd->st, &ino->data, ino->size, &dent, sz)) + if(btput(fsd->st, &ino->data, ino->size, &dent, sz, DIRBLSIZE)) return(-1); ino->size++; return(0); } - return(btput(fsd->st, &ino->data, di, &dent, sz)); + return(btput(fsd->st, &ino->data, di, &dent, sz, DIRBLSIZE)); } static void fusemkdir(fuse_req_t req, fuse_ino_t parent, const char *name, mode_t mode) @@ -505,7 +506,7 @@ static void fusemkdir(fuse_req_t req, fuse_ino_t parent, const char *name, mode_ file.links++; btmkop(ops + 0, inoc->inode, &file, sizeof(file)); btmkop(ops + 1, fsd->nextino, &new, sizeof(new)); - if(btputmany(fsd->st, &inotab, ops, 2)) { + if(btputmany(fsd->st, &inotab, ops, 2, INOBLSIZE)) { fuse_reply_err(req, errno); return; } @@ -561,7 +562,7 @@ static void fuseunlink(fuse_req_t req, fuse_ino_t parent, const char *name) fuse_reply_err(req, errno); return; } - if(btput(fsd->st, &inotab, inoc->inode, &file, sizeof(file))) { + if(btput(fsd->st, &inotab, inoc->inode, &file, sizeof(file), INOBLSIZE)) { fuse_reply_err(req, errno); return; } diff --git a/vcfs.h b/vcfs.h index 8fd2727..aa6d32c 100644 --- a/vcfs.h +++ b/vcfs.h @@ -6,6 +6,9 @@ #include "blocktree.h" +#define DIRBLSIZE 4 +#define INOBLSIZE 4 + typedef loff_t vc_ino_t; typedef loff_t vc_rev_t; -- 2.11.0