[Tux3] Patch: Improve new_btree interface, fix lock init

Daniel Phillips phillips at phunq.net
Wed Dec 24 02:02:11 PST 2008


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.

Regards,

Daniel

diff -r bf900c9a443e user/btree.c
--- a/user/btree.c	Wed Dec 24 00:07:45 2008 -0800
+++ b/user/btree.c	Wed Dec 24 01:35:56 2008 -0800
@@ -150,7 +150,8 @@ int main(int argc, char *argv[])
 	init_buffers(dev, 1 << 20);
 	sb->entries_per_node = (sb->blocksize - offsetof(struct bnode, entries)) / sizeof(struct index_entry);
 	printf("entries_per_node = %i\n", sb->entries_per_node);
-	struct btree btree = new_btree(sb, &ops);
+	struct btree btree = { };
+	assert(!new_btree(&btree, sb, &ops));
 	btree.entries_per_leaf = (sb->blocksize - offsetof(struct uleaf, entries)) / sizeof(struct entry);
 
 	if (0) {
diff -r bf900c9a443e user/filemap.c
--- a/user/filemap.c	Wed Dec 24 00:07:45 2008 -0800
+++ b/user/filemap.c	Wed Dec 24 01:35:56 2008 -0800
@@ -76,7 +76,7 @@ int main(int argc, char *argv[])
 	sb->bitmap->map->inode = sb->bitmap;
 	init_buffers(dev, 1 << 20);
 	struct inode *inode = &(struct inode){ .i_sb = sb, .map = new_map(dev, &filemap_ops) };
-	inode->btree = new_btree(sb, &dtree_ops); // error???
+	assert(!new_btree(&inode->btree, sb, &dtree_ops));
 	inode->map->inode = inode;
 	inode = inode;
 
diff -r bf900c9a443e user/kernel/btree.c
--- a/user/kernel/btree.c	Wed Dec 24 00:07:45 2008 -0800
+++ b/user/kernel/btree.c	Wed Dec 24 01:35:56 2008 -0800
@@ -586,29 +586,29 @@ void *tree_expand(struct btree *btree, t
 	return NULL;
 }
 
-struct btree new_btree(struct sb *sb, struct btree_ops *ops)
+int new_btree(struct btree *btree, struct sb *sb, struct btree_ops *ops)
 {
-	struct btree btree = { .sb = sb, .ops = ops };
-	struct buffer_head *rootbuf = new_node(&btree);
-	struct buffer_head *leafbuf = new_leaf(&btree);
+	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 };
+	btree->root = (struct root){ .block = bufindex(rootbuf), .depth = 1 };
 	printf("root at %Lx\n", (L)bufindex(rootbuf));
 	printf("leaf at %Lx\n", (L)bufindex(leafbuf));
 	brelse_dirty(rootbuf);
 	brelse_dirty(leafbuf);
-	init_rwsem(&btree.lock);
-	return btree;
+	btree->ops = ops;
+	btree->sb = sb;
+	return 0;
 eek:
 	if (rootbuf)
 		brelse(rootbuf);
 	if (leafbuf)
 		brelse(leafbuf);
-	return (struct btree){ };
+	return -ENOMEM;
 }
 
 /* userland only */
diff -r bf900c9a443e user/kernel/inode.c
--- a/user/kernel/inode.c	Wed Dec 24 00:07:45 2008 -0800
+++ b/user/kernel/inode.c	Wed Dec 24 01:35:56 2008 -0800
@@ -203,9 +203,9 @@ static int make_inode(struct inode *inod
 	}
 
 	tux_set_inum(inode, goal);
-	/* FIXME: is this right strategy? */
 	if (tux_inode(inode)->present & DATA_BTREE_BIT)
-		tux_inode(inode)->btree = new_btree(sb, &dtree_ops); // error???
+		if ((err = new_btree(&tux_inode(inode)->btree, sb, &dtree_ops)))
+			goto errout;
 	if ((err = store_attrs(inode, cursor)))
 		goto errout;
 	release_cursor(cursor);
diff -r bf900c9a443e user/kernel/super.c
--- a/user/kernel/super.c	Wed Dec 24 00:07:45 2008 -0800
+++ b/user/kernel/super.c	Wed Dec 24 01:35:56 2008 -0800
@@ -69,6 +69,7 @@ static void tux3_inode_init_once(struct 
 static void tux3_inode_init_once(struct kmem_cache *cachep, void *mem)
 {
 	inode_init_once(&((tuxnode_t *)mem)->vfs_inode);
+	init_rwsem(&((tuxnode_t *)mem)->btree.lock);
 }
 
 static int __init tux3_init_inodecache(void)
@@ -95,6 +96,7 @@ static struct inode *tux3_alloc_inode(st
 	tuxi->btree = (struct btree){};
 	tuxi->present = 0;
 	tuxi->xcache = NULL;
+
 	/* uninitialized stuff by alloc_inode() */
 	tuxi->vfs_inode.i_version = 1;
 	tuxi->vfs_inode.i_uid = 0;
diff -r bf900c9a443e user/kernel/tux3.h
--- a/user/kernel/tux3.h	Wed Dec 24 00:07:45 2008 -0800
+++ b/user/kernel/tux3.h	Wed Dec 24 01:35:56 2008 -0800
@@ -607,7 +607,7 @@ void level_pop_brelse_dirty(struct curso
 void level_pop_brelse_dirty(struct cursor *cursor);
 void level_push(struct cursor *cursor, struct buffer_head *buffer, struct index_entry *next);
 
-struct btree new_btree(struct sb *sb, 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);
 int advance(struct btree *btree, struct cursor *cursor);
diff -r bf900c9a443e user/super.c
--- a/user/super.c	Wed Dec 24 00:07:45 2008 -0800
+++ b/user/super.c	Wed Dec 24 01:35:56 2008 -0800
@@ -95,7 +95,7 @@ int make_tux3(struct sb *sb)
 	}
 
 	trace("create inode table");
-	sb->itable = new_btree(sb, &itable_ops);
+	assert(!new_btree(&sb->itable, sb, &itable_ops));
 	if (!sb->itable.ops)
 		goto eek;
 	sb->itable.entries_per_leaf = 64; // !!! should depend on blocksize

_______________________________________________
Tux3 mailing list
Tux3 at tux3.org
http://mailman.tux3.org/cgi-bin/mailman/listinfo/tux3



More information about the Tux3 mailing list