Skip to content

Commit

Permalink
Btrfs: use RCU instead of a spinlock to protect the root node
Browse files Browse the repository at this point in the history
The pointer to the extent buffer for the root of each tree
is protected by a spinlock so that we can safely read the pointer
and take a reference on the extent buffer.

But now that the extent buffers are freed via RCU, we can safely
use rcu_read_lock instead.

Signed-off-by: Chris Mason <[email protected]>
  • Loading branch information
chrismason-xx authored and root committed Mar 28, 2011
1 parent c0da7aa commit 240f62c
Showing 1 changed file with 8 additions and 19 deletions.
27 changes: 8 additions & 19 deletions fs/btrfs/ctree.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,11 @@ noinline void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p)
struct extent_buffer *btrfs_root_node(struct btrfs_root *root)
{
struct extent_buffer *eb;
spin_lock(&root->node_lock);
eb = root->node;

rcu_read_lock();
eb = rcu_dereference(root->node);
extent_buffer_get(eb);
spin_unlock(&root->node_lock);
rcu_read_unlock();
return eb;
}

Expand All @@ -165,14 +166,8 @@ struct extent_buffer *btrfs_lock_root_node(struct btrfs_root *root)
while (1) {
eb = btrfs_root_node(root);
btrfs_tree_lock(eb);

spin_lock(&root->node_lock);
if (eb == root->node) {
spin_unlock(&root->node_lock);
if (eb == root->node)
break;
}
spin_unlock(&root->node_lock);

btrfs_tree_unlock(eb);
free_extent_buffer(eb);
}
Expand Down Expand Up @@ -458,10 +453,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
else
parent_start = 0;

spin_lock(&root->node_lock);
root->node = cow;
extent_buffer_get(cow);
spin_unlock(&root->node_lock);
rcu_assign_pointer(root->node, cow);

btrfs_free_tree_block(trans, root, buf, parent_start,
last_ref);
Expand Down Expand Up @@ -930,9 +923,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
goto enospc;
}

spin_lock(&root->node_lock);
root->node = child;
spin_unlock(&root->node_lock);
rcu_assign_pointer(root->node, child);

add_root_to_dirty_list(root);
btrfs_tree_unlock(child);
Expand Down Expand Up @@ -2007,10 +1998,8 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans,

btrfs_mark_buffer_dirty(c);

spin_lock(&root->node_lock);
old = root->node;
root->node = c;
spin_unlock(&root->node_lock);
rcu_assign_pointer(root->node, c);

/* the super has an extra ref to root->node */
free_extent_buffer(old);
Expand Down

0 comments on commit 240f62c

Please sign in to comment.