Commit 240f62c8 authored by Chris Mason's avatar Chris Mason Committed by root

Btrfs: use RCU instead of a spinlock to protect the root node

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: default avatarChris Mason <chris.mason@oracle.com>
parent c0da7aa1
...@@ -147,10 +147,11 @@ noinline void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p) ...@@ -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 *btrfs_root_node(struct btrfs_root *root)
{ {
struct extent_buffer *eb; struct extent_buffer *eb;
spin_lock(&root->node_lock);
eb = root->node; rcu_read_lock();
eb = rcu_dereference(root->node);
extent_buffer_get(eb); extent_buffer_get(eb);
spin_unlock(&root->node_lock); rcu_read_unlock();
return eb; return eb;
} }
...@@ -165,14 +166,8 @@ struct extent_buffer *btrfs_lock_root_node(struct btrfs_root *root) ...@@ -165,14 +166,8 @@ struct extent_buffer *btrfs_lock_root_node(struct btrfs_root *root)
while (1) { while (1) {
eb = btrfs_root_node(root); eb = btrfs_root_node(root);
btrfs_tree_lock(eb); btrfs_tree_lock(eb);
if (eb == root->node)
spin_lock(&root->node_lock);
if (eb == root->node) {
spin_unlock(&root->node_lock);
break; break;
}
spin_unlock(&root->node_lock);
btrfs_tree_unlock(eb); btrfs_tree_unlock(eb);
free_extent_buffer(eb); free_extent_buffer(eb);
} }
...@@ -458,10 +453,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, ...@@ -458,10 +453,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
else else
parent_start = 0; parent_start = 0;
spin_lock(&root->node_lock);
root->node = cow;
extent_buffer_get(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, btrfs_free_tree_block(trans, root, buf, parent_start,
last_ref); last_ref);
...@@ -930,9 +923,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, ...@@ -930,9 +923,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
goto enospc; goto enospc;
} }
spin_lock(&root->node_lock); rcu_assign_pointer(root->node, child);
root->node = child;
spin_unlock(&root->node_lock);
add_root_to_dirty_list(root); add_root_to_dirty_list(root);
btrfs_tree_unlock(child); btrfs_tree_unlock(child);
...@@ -2007,10 +1998,8 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans, ...@@ -2007,10 +1998,8 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans,
btrfs_mark_buffer_dirty(c); btrfs_mark_buffer_dirty(c);
spin_lock(&root->node_lock);
old = root->node; old = root->node;
root->node = c; rcu_assign_pointer(root->node, c);
spin_unlock(&root->node_lock);
/* the super has an extra ref to root->node */ /* the super has an extra ref to root->node */
free_extent_buffer(old); free_extent_buffer(old);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment