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
