Make blocktree indir block sizes variable.
authorfredrik <fredrik@959494ce-11ee-0310-bf91-de5d638817bd>
Thu, 3 Aug 2006 01:36:38 +0000 (01:36 +0000)
committerfredrik <fredrik@959494ce-11ee-0310-bf91-de5d638817bd>
Thu, 3 Aug 2006 01:36:38 +0000 (01:36 +0000)
git-svn-id: svn+ssh://svn.dolda2000.com/srv/svn/repos/src/vcfs@679 959494ce-11ee-0310-bf91-de5d638817bd

blocktree.c
blocktree.h
mkfs.vc.c
vcfs.c
vcfs.h

index a973e8f..727628f 100644 (file)
@@ -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];
     }
 }
index c962874..fd2ea99 100644 (file)
@@ -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);
 
index a507abe..764c8e4 100644 (file)
--- 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 (file)
--- 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 (file)
--- 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;