[Tux3] Basic SMP locking for inode table
Daniel Phillips
phillips at phunq.net
Fri Dec 26 15:49:13 PST 2008
Serialize operations on the inode table btree using the per-btree rwsem,
please have a look. Also regularizes error handling here and does some
minor cleanup.
diff -r c24c2e4b5693 user/kernel/inode.c
--- a/user/kernel/inode.c Fri Dec 26 04:19:29 2008 -0800
+++ b/user/kernel/inode.c Fri Dec 26 15:45:34 2008 -0800
@@ -98,16 +98,14 @@ static int open_inode(struct inode *inod
struct cursor *cursor = alloc_cursor(&sb->itable, 0);
if (!cursor)
return -ENOMEM;
-
- if ((err = probe(&sb->itable, tux_inode(inode)->inum, cursor))) {
- free_cursor(cursor);
- return err;
- }
+ down_read(&cursor->btree->lock);
+ if ((err = probe(&sb->itable, tux_inode(inode)->inum, cursor)))
+ goto out;
unsigned size;
void *attrs = ileaf_lookup(&sb->itable, tux_inode(inode)->inum, bufdata(cursor_leafbuf(cursor)), &size);
if (!attrs) {
err = -ENOENT;
- goto eek;
+ goto release;
}
trace("found inode 0x%Lx", (L)tux_inode(inode)->inum);
//ileaf_dump(&sb->itable, bufdata(cursor[depth].buffer));
@@ -115,7 +113,7 @@ static int open_inode(struct inode *inod
unsigned xsize = decode_xsize(inode, attrs, size);
err = -ENOMEM;
if (xsize && !(tux_inode(inode)->xcache = new_xcache(xsize)))
- goto eek;
+ goto release;
decode_attrs(inode, attrs, size); // error???
dump_attrs(inode);
if (tux_inode(inode)->xcache)
@@ -123,8 +121,10 @@ static int open_inode(struct inode *inod
check_present(inode);
tux_setup_inode(inode, inode->i_rdev);
err = 0;
-eek:
+release:
release_cursor(cursor);
+out:
+ up_read(&cursor->btree->lock);
free_cursor(cursor);
return err;
}
@@ -134,7 +134,7 @@ static int store_attrs(struct inode *ino
unsigned size = encode_asize(tux_inode(inode)->present) + encode_xsize(inode);
void *base = tree_expand(&tux_sb(inode->i_sb)->itable, tux_inode(inode)->inum, size, cursor);
if (!base)
- return -ENOMEM; // what was the actual error???
+ return -ENOMEM; // ERR_PTR me!!!
void *attr = encode_attrs(inode, base, size);
attr = encode_xattrs(inode, attr, base + size - attr);
assert(attr == base + size);
@@ -172,50 +172,44 @@ static int make_inode(struct inode *inod
struct cursor *cursor = alloc_cursor(&sb->itable, 1); /* +1 for now depth */
if (!cursor)
return -ENOMEM;
-
- if ((err = probe(&sb->itable, goal, cursor))) {
- free_cursor(cursor);
- return err;
- }
+ down_write(&cursor->btree->lock);
+ if ((err = probe(&sb->itable, goal, cursor)))
+ goto out;
struct buffer_head *leafbuf = cursor_leafbuf(cursor);
-// struct ileaf *leaf = to_ileaf(bufdata(leafbuf));
/* FIXME: inum allocation should check min and max */
trace("create inode 0x%Lx", (L)goal);
assert(!tux_inode(inode)->btree.root.depth);
assert(goal < next_key(cursor, depth));
while (1) {
-// printf("find empty inode in [%Lx] base %Lx\n", (L)bufindex(leafbuf), (L)ibase(leaf));
+ trace_off("find empty inode in [%Lx] base %Lx", (L)bufindex(leafbuf), (L)ibase(leaf));
goal = find_empty_inode(&sb->itable, bufdata(leafbuf), goal);
- printf("result inum is %Lx, limit is %Lx\n", (L)goal, (L)next_key(cursor, depth));
+ trace("result inum is %Lx, limit is %Lx", (L)goal, (L)next_key(cursor, depth));
if (goal < next_key(cursor, depth))
break;
int more = advance(&sb->itable, cursor);
if (more < 0) {
err = more;
- goto errout;
+ goto out;
}
- printf("no more inode space here, advance %i\n", more);
+ trace("no more inode space here, advance %i", more);
if (!more) {
err = -ENOSPC;
- goto errout;
+ goto release;
}
}
tux_set_inum(inode, goal);
if (tux_inode(inode)->present & DATA_BTREE_BIT)
if ((err = new_btree(&tux_inode(inode)->btree, sb, &dtree_ops)))
- goto errout;
+ goto release;
if ((err = store_attrs(inode, cursor)))
- goto errout;
+ goto out;
+release:
release_cursor(cursor);
+out:
+ up_write(&cursor->btree->lock);
free_cursor(cursor);
- return 0;
-
-errout:
- /* release_cursor() was already called at error point */
- free_cursor(cursor);
- warn("make_inode 0x%Lx failed (%d)", (L)goal, err);
return err;
}
@@ -228,20 +222,21 @@ static int save_inode(struct inode *inod
struct cursor *cursor = alloc_cursor(&sb->itable, 1); /* +1 for new depth */
if (!cursor)
return -ENOMEM;
-
- if ((err = probe(&sb->itable, tux_inode(inode)->inum, cursor))) {
- free_cursor(cursor);
- return err;
+ down_write(&cursor->btree->lock);
+ if ((err = probe(&sb->itable, tux_inode(inode)->inum, cursor)))
+ goto out;
+ /* paranoia check */
+ unsigned size;
+ if (!(ileaf_lookup(&sb->itable, tux_inode(inode)->inum, bufdata(cursor_leafbuf(cursor)), &size))) {
+ err = -EINVAL;
+ goto release;
}
- unsigned size;
- if (!(ileaf_lookup(&sb->itable, tux_inode(inode)->inum, bufdata(cursor_leafbuf(cursor)), &size)))
- return -EINVAL;
- err = store_attrs(inode, cursor);
- if (err)
- goto error;
- /* release_cursor() was already called at error point */
+ if ((err = store_attrs(inode, cursor)))
+ goto out;
+release:
release_cursor(cursor);
-error:
+out:
+ up_write(&cursor->btree->lock);
free_cursor(cursor);
return err;
}
_______________________________________________
Tux3 mailing list
Tux3 at tux3.org
http://mailman.tux3.org/cgi-bin/mailman/listinfo/tux3
More information about the Tux3
mailing list