Daniel Phillips <[email protected]> writes:

> The new_btree function was a piece of prototype code that escaped and
> finally started causing problems now, when we decided to add a new lock
> and realized it had to be initialized in several places.  Its primary
> purpose is to create the persistent form of a btree, not to initialize
> the cache object.  So with this patch new_btree takes an existing btree
> object as a parameter and returns an error code as is proper.
>
> But the patch is not quite ready to apply, we still have destructive
> initialization of the btree cache object in unpack_sb and decode_attrs,
> which needs a clean fix I am not quite prepared to tackle at this time
> of night, so see you all tomorrow.

This is incremental patch of this patch.

This adds init_btree() to initialize btree. And it calls new
->btree_init() method to initialize per btree fields (it is only
->entries_per_leaf currently).

Then, this uses it except btree in main(). So, with this, new_btree()
allocates new btree, and init_btree initialize ->btree with existing
btree.

Thanks.
-- 
OGAWA Hirofumi <[email protected]>



diff -puN user/kernel/tux3.h~init-btree user/kernel/tux3.h
--- tux3/user/kernel/tux3.h~init-btree  2008-12-25 01:40:17.000000000 +0900
+++ tux3-hirofumi/user/kernel/tux3.h    2008-12-25 02:10:05.000000000 +0900
@@ -166,11 +166,11 @@ struct root {
 };
 
 struct btree {
+       struct rw_semaphore lock;
        struct sb *sb;          /* Convenience to reduce parameter list size */
        struct btree_ops *ops;  /* Generic btree low level operations */
        struct root root;       /* Cached description of btree root */
        u16 entries_per_leaf;   /* Used in btree leaf splitting */
-       struct rw_semaphore lock;
 };
 
 /* Define layout of btree root on disk, endian conversion is elsewhere. */
@@ -445,6 +445,7 @@ static inline void inc_dleaf_groups(stru
 typedef void vleaf;
 
 struct btree_ops {
+       void (*btree_init)(struct btree *btree);
        int (*leaf_sniff)(struct btree *btree, vleaf *leaf);
        int (*leaf_init)(struct btree *btree, vleaf *leaf);
        tuxkey_t (*leaf_split)(struct btree *btree, tuxkey_t key, vleaf *from, 
vleaf *into);
@@ -607,6 +608,7 @@ void free_cursor(struct cursor *cursor);
 void level_pop_brelse_dirty(struct cursor *cursor);
 void level_push(struct cursor *cursor, struct buffer_head *buffer, struct 
index_entry *next);
 
+void init_btree(struct btree *btree, struct sb *sb, struct root root, struct 
btree_ops *ops);
 int new_btree(struct btree *btree, struct sb *sb, struct btree_ops *ops);
 struct buffer_head *new_leaf(struct btree *btree);
 int probe(struct btree *btree, tuxkey_t key, struct cursor *cursor);
diff -puN user/kernel/btree.c~init-btree user/kernel/btree.c
--- tux3/user/kernel/btree.c~init-btree 2008-12-25 01:43:55.000000000 +0900
+++ tux3-hirofumi/user/kernel/btree.c   2008-12-25 02:57:00.000000000 +0900
@@ -586,22 +586,34 @@ void *tree_expand(struct btree *btree, t
        return NULL;
 }
 
+void init_btree(struct btree *btree, struct sb *sb, struct root root, struct 
btree_ops *ops)
+{
+       btree->sb = sb;
+       btree->ops = ops;
+       btree->root = root;
+       btree->entries_per_leaf = 0;
+       if (ops)
+               ops->btree_init(btree);
+}
+
 int new_btree(struct btree *btree, struct sb *sb, struct btree_ops *ops)
 {
+       /* Initialize btree with dummy root */
+       init_btree(btree, sb, (struct root){}, ops);
+
        struct buffer_head *rootbuf = new_node(btree);
        struct buffer_head *leafbuf = new_leaf(btree);
        if (!rootbuf || !leafbuf)
                goto eek;
-       struct bnode *root = bufdata(rootbuf);
-       root->entries[0].block = to_be_u64(bufindex(leafbuf));
-       root->count = to_be_u32(1);
-       btree->root = (struct root){ .block = bufindex(rootbuf), .depth = 1 };
+       struct bnode *rootnode = bufdata(rootbuf);
+       rootnode->entries[0].block = to_be_u64(bufindex(leafbuf));
+       rootnode->count = to_be_u32(1);
        printf("root at %Lx\n", (L)bufindex(rootbuf));
        printf("leaf at %Lx\n", (L)bufindex(leafbuf));
        brelse_dirty(rootbuf);
        brelse_dirty(leafbuf);
-       btree->ops = ops;
-       btree->sb = sb;
+       struct root root = { .block = bufindex(rootbuf), .depth = 1 };
+       init_btree(btree, sb, root, ops);
        return 0;
 eek:
        if (rootbuf)
diff -puN user/btree.c~init-btree user/btree.c
--- tux3/user/btree.c~init-btree        2008-12-25 01:52:29.000000000 +0900
+++ tux3-hirofumi/user/btree.c  2008-12-25 02:28:27.000000000 +0900
@@ -33,6 +33,12 @@ static inline struct uleaf *to_uleaf(vle
        return leaf;
 }
 
+static void uleaf_btree_init(struct btree *btree)
+{
+       struct sb *sb = btree->sb;
+       btree->entries_per_leaf = (sb->blocksize - offsetof(struct uleaf, 
entries)) / sizeof(struct entry);
+}
+
 int uleaf_sniff(struct btree *btree, vleaf *leaf)
 {
        return to_uleaf(leaf)->magic == 0xc0de;
@@ -112,6 +118,7 @@ void uleaf_merge(struct btree *btree, vl
 }
 
 struct btree_ops ops = {
+       .btree_init = uleaf_btree_init,
        .leaf_sniff = uleaf_sniff,
        .leaf_init = uleaf_init,
        .leaf_split = uleaf_split,
@@ -152,7 +159,6 @@ int main(int argc, char *argv[])
        printf("entries_per_node = %i\n", sb->entries_per_node);
        struct btree btree = { };
        assert(!new_btree(&btree, sb, &ops));
-       btree.entries_per_leaf = (sb->blocksize - offsetof(struct uleaf, 
entries)) / sizeof(struct entry);
 
        if (0) {
                struct buffer_head *buffer = new_leaf(&btree);
diff -puN user/dleaf.c~init-btree user/dleaf.c
diff -puN user/iattr.c~init-btree user/iattr.c
--- tux3/user/iattr.c~init-btree        2008-12-25 01:55:56.000000000 +0900
+++ tux3-hirofumi/user/iattr.c  2008-12-25 02:18:10.000000000 +0900
@@ -15,6 +15,13 @@
 
 #ifndef iattr_notmain_from_inode
 static struct btree_ops dtree_ops;
+static void init_btree(struct btree *btree, struct sb *sb, struct root root, 
struct btree_ops *ops)
+{
+       btree->sb = sb;
+       btree->root = root;
+       btree->ops = ops;
+       btree->entries_per_leaf = 0;
+}
 #endif
 
 #ifndef trace
diff -puN user/ileaf.c~init-btree user/ileaf.c
--- tux3/user/ileaf.c~init-btree        2008-12-25 01:57:12.000000000 +0900
+++ tux3-hirofumi/user/ileaf.c  2008-12-25 02:14:04.000000000 +0900
@@ -65,8 +65,11 @@ int main(int argc, char *argv[])
 {
        printf("--- test inode table leaf methods ---\n");
        struct sb *sb = &(struct sb){ .blocksize = 4096 };
-       struct btree *btree = &(struct btree){ .sb = sb, .ops = &itable_ops };
-       btree->entries_per_leaf = 64; // !!! should depend on blocksize
+       struct btree *btree = &(struct btree){
+               .sb = sb,
+               .ops = &itable_ops,
+               .entries_per_leaf = 64, // !!! should depend on blocksize
+       };
        struct ileaf *leaf = ileaf_create(btree);
        struct ileaf *dest = ileaf_create(btree);
        leaf->ibase = to_be_u64(0x10);
diff -puN user/kernel/iattr.c~init-btree user/kernel/iattr.c
--- tux3/user/kernel/iattr.c~init-btree 2008-12-25 01:59:30.000000000 +0900
+++ tux3-hirofumi/user/kernel/iattr.c   2008-12-25 02:08:19.000000000 +0900
@@ -126,16 +126,17 @@ void *encode_attrs(struct inode *inode, 
 void *decode_attrs(struct inode *inode, void *attrs, unsigned size)
 {
        trace_off("decode %u attr bytes", size);
-       u64 v64;
-       u32 v32;
+       struct sb *sb = tux_sb(inode->i_sb);
        tuxnode_t *tuxnode = tux_inode(inode);
        struct xattr *xattr = tuxnode->xcache ? tuxnode->xcache->xattrs : NULL;
        void *limit = attrs + size;
+       u64 v64;
+       u32 v32;
        while (attrs < limit - 1) {
                unsigned head;
                attrs = decode16(attrs, &head);
                unsigned version = head & 0xfff, kind = head >> 12;
-               if (version != tux_sb(inode->i_sb)->version) {
+               if (version != sb->version) {
                        attrs += atsize[kind];
                        continue;
                }
@@ -159,12 +160,7 @@ void *decode_attrs(struct inode *inode, 
                        break;
                case DATA_BTREE_ATTR:
                        attrs = decode64(attrs, &v64);
-                       tuxnode->btree = (struct btree){
-                               .sb = tux_sb(inode->i_sb),
-                               .entries_per_leaf = 64, // !!! should depend on 
blocksize
-                               .ops = &dtree_ops,
-                               .root = unpack_root(v64),
-                       };
+                       init_btree(&tuxnode->btree, sb, unpack_root(v64), 
&dtree_ops);
                        break;
                case LINK_COUNT_ATTR:
                        attrs = decode32(attrs, &inode->i_nlink);
diff -puN user/kernel/super.c~init-btree user/kernel/super.c
--- tux3/user/kernel/super.c~init-btree 2008-12-25 02:00:59.000000000 +0900
+++ tux3-hirofumi/user/kernel/super.c   2008-12-25 03:11:35.000000000 +0900
@@ -17,6 +17,7 @@
 
 static int unpack_sb(struct sb *sb, struct disksuper *super, int silent)
 {
+       u64 iroot = from_be_u64(super->iroot);
        if (memcmp(super->magic, (char[])SB_MAGIC, sizeof(super->magic))) {
                if (!silent)
                        printf("invalid superblock [%Lx]\n",
@@ -24,18 +25,10 @@ static int unpack_sb(struct sb *sb, stru
                return -EINVAL;
        }
 
-       int blockbits = from_be_u16(super->blockbits);
-
-       sb->itable = (struct btree){
-               .sb     = sb,
-               .ops    = &itable_ops,
-               .root   = unpack_root(from_be_u64(super->iroot)),
-               .entries_per_leaf = 1 << (blockbits - 6),
-       };
 //     sb->rootbuf;
-       sb->blockbits = blockbits;
-       sb->blocksize = 1 << blockbits;
-       sb->blockmask = (1 << blockbits) - 1;
+       sb->blockbits = from_be_u16(super->blockbits);
+       sb->blocksize = 1 << sb->blockbits;
+       sb->blockmask = (1 << sb->blockbits) - 1;
        /* FIXME: those should be initialized based on blocksize. */
        sb->entries_per_node = 20;
        sb->max_inodes_per_block = 64;
@@ -48,6 +41,9 @@ static int unpack_sb(struct sb *sb, stru
        sb->atomgen = from_be_u32(super->atomgen);
        sb->freeatom = from_be_u32(super->freeatom);
        sb->dictsize = from_be_u64(super->dictsize);
+
+       init_btree(&sb->itable, sb, unpack_root(iroot), &itable_ops);
+
        return 0;
 }
 
@@ -93,7 +89,7 @@ static struct inode *tux3_alloc_inode(st
        tuxnode_t *tuxi = kmem_cache_alloc(tux_inode_cachep, GFP_KERNEL);
        if (!tuxi)
                return NULL;
-       tuxi->btree = (struct btree){};
+       init_btree(&tuxi->btree, NULL, (struct root){}, NULL);
        tuxi->present = 0;
        tuxi->xcache = NULL;
 
diff -puN user/tux3.c~init-btree user/tux3.c
--- tux3/user/tux3.c~init-btree 2008-12-25 02:02:42.000000000 +0900
+++ tux3-hirofumi/user/tux3.c   2008-12-25 02:03:40.000000000 +0900
@@ -78,8 +78,8 @@ int main(int argc, const char *argv[])
                .blockmask = (1 << dev->bits) - 1,
                .volblocks = volsize >> dev->bits,
                .freeblocks = volsize >> dev->bits,
-               .itable = (struct btree){ .sb = sb, .ops = &itable_ops,
-                       .entries_per_leaf = 1 << (dev->bits - 6) } };
+       };
+       init_btree(&sb->itable, sb, (struct root){}, &itable_ops);
 
        if (!strcmp(command, "mkfs") || !strcmp(command, "make")) {
                if (poptPeekArg(popt))
diff -puN user/filemap.c~init-btree user/filemap.c
--- tux3/user/filemap.c~init-btree      2008-12-25 02:19:12.000000000 +0900
+++ tux3-hirofumi/user/filemap.c        2008-12-25 02:19:22.000000000 +0900
@@ -18,15 +18,15 @@
 #include "xattr.c"
 #undef main
 
+#define main notmain4
+#include "btree.c"
+#undef main
+
 #define iattr_notmain_from_inode
 #define main iattr_notmain_from_inode
 #include "ileaf.c"
 #undef main
 
-#define main notmain4
-#include "btree.c"
-#undef main
-
 #include "tux3.h"      /* include user/tux3.h, not user/kernel/tux3.h */
 #include "kernel/filemap.c"
 
diff -puN user/kernel/dleaf.c~init-btree user/kernel/dleaf.c
--- tux3/user/kernel/dleaf.c~init-btree 2008-12-25 02:19:53.000000000 +0900
+++ tux3-hirofumi/user/kernel/dleaf.c   2008-12-25 03:17:05.000000000 +0900
@@ -68,6 +68,11 @@ static inline struct dleaf *to_dleaf(vle
        return leaf;
 }
 
+static void dleaf_btree_init(struct btree *btree)
+{
+       btree->entries_per_leaf = 64; /* FIXME: should depend on blocksize */
+}
+
 int dleaf_init(struct btree *btree, vleaf *leaf)
 {
        if (!leaf)
@@ -745,6 +750,7 @@ static int dleaf_chop(struct btree *btre
 }
 
 struct btree_ops dtree_ops = {
+       .btree_init = dleaf_btree_init,
        .leaf_sniff = dleaf_sniff,
        .leaf_init = dleaf_init,
        .leaf_dump = dleaf_dump,
diff -puN user/kernel/ileaf.c~init-btree user/kernel/ileaf.c
--- tux3/user/kernel/ileaf.c~init-btree 2008-12-25 02:33:21.000000000 +0900
+++ tux3-hirofumi/user/kernel/ileaf.c   2008-12-25 02:35:14.000000000 +0900
@@ -47,6 +47,11 @@ static inline tuxkey_t ibase(struct ilea
        return from_be_u64(leaf->ibase);
 }
 
+static void ileaf_btree_init(struct btree *btree)
+{
+       btree->entries_per_leaf = 1 << (btree->sb->blockbits - 6);
+}
+
 static int ileaf_init(struct btree *btree, vleaf *leaf)
 {
        printf("initialize inode leaf %p\n", leaf);
@@ -286,6 +291,7 @@ int ileaf_purge(struct btree *btree, inu
 }
 
 struct btree_ops itable_ops = {
+       .btree_init = ileaf_btree_init,
        .leaf_dump = ileaf_dump,
        .leaf_sniff = ileaf_sniff,
        .leaf_init = ileaf_init,
diff -puN user/super.c~init-btree user/super.c
--- tux3/user/super.c~init-btree        2008-12-25 02:37:02.000000000 +0900
+++ tux3-hirofumi/user/super.c  2008-12-25 02:37:45.000000000 +0900
@@ -95,10 +95,9 @@ int make_tux3(struct sb *sb)
        }
 
        trace("create inode table");
-       assert(!new_btree(&sb->itable, sb, &itable_ops));
-       if (!sb->itable.ops)
+       err = new_btree(&sb->itable, sb, &itable_ops);
+       if (err)
                goto eek;
-       sb->itable.entries_per_leaf = 64; // !!! should depend on blocksize
        sb->bitmap->i_size = (sb->volblocks + 7) >> 3;
        trace("create bitmap inode");
        if (make_inode(sb->bitmap, TUX_BITMAP_INO))
diff -puN user/inode.c~init-btree user/inode.c
--- tux3/user/inode.c~init-btree        2008-12-25 03:12:09.000000000 +0900
+++ tux3-hirofumi/user/inode.c  2008-12-25 03:12:50.000000000 +0900
@@ -27,6 +27,7 @@ struct inode *new_inode(struct sb *sb)
        if (!inode)
                goto eek;
        *inode = (struct inode){ .i_sb = sb, .map = map, .i_version = 1, 
.i_nlink = 1, };
+       init_btree(&tux_inode(inode)->btree, NULL, (struct root){}, NULL);
        return inode->map->inode = inode;
 eek:
        if (map)
_

_______________________________________________
Tux3 mailing list
[email protected]
http://mailman.tux3.org/cgi-bin/mailman/listinfo/tux3

Reply via email to