Btrfs: hold the commit_root_sem when getting the commit root during send
PATCH 1/1 Btrfs: hold the commit_root_sem when getting the commit root during send
We currently rely too heavily on roots being read-only to save us from just accessing root->commit_root. We can easily balance blocks out from underneath a read only root, so to save us from getting screwed make sure we only access root->commit_root under the commit root sem. Thanks,
Signed-off-by Josef Bacik <[email protected]>
--- fs/btrfs/ctree.c | 6 ++++++ fs/btrfs/ctree.h | 1 + fs/btrfs/send.c | 1 + 3 files changed, 8 insertions(+)
fs/btrfs/ctree.c +6 -0
@@ -2769,9 +2769,13 @@ again:* the commit roots are read only * so we always do read locks */ +if (p->need_commit_sem) +down_read (&root->fs_info->commit_root_sem); b = root->commit_root;extent_buffer_get (b); level =btrfs_header_level (b); +if (p->need_commit_sem) +up_read (&root->fs_info->commit_root_sem);if (!p->skip_locking)btrfs_tree_read_lock (b); }else {
@@ -5436,6 +5440,7 @@ int btrfs_compare_trees(struct btrfs_root *left_root,* the right if possible or go up and right. */ +down_read (&left_root->fs_info->commit_root_sem); left_level =btrfs_header_level (left_root->commit_root); left_root_level = left_level; left_path->nodes[left_level] = left_root->commit_root;
@@ -5445,6 +5450,7 @@ int btrfs_compare_trees(struct btrfs_root *left_root, right_root_level = right_level; right_path->nodes[right_level] = right_root->commit_root;extent_buffer_get (right_path->nodes[right_level]); +up_read (&left_root->fs_info->commit_root_sem);if (left_level ==0 ) btrfs_item_key_to_cpu(left_path->nodes[left_level],
fs/btrfs/ctree.h +1 -0
@@ -609,6 +609,7 @@ struct btrfs_path { unsigned int skip_locking:1; unsigned int leave_spinning:1; unsigned int search_commit_root:1; + unsigned int need_commit_sem:1; };/*
fs/btrfs/send.c +1 -0
@@ -493,6 +493,7 @@ static struct btrfs_path *alloc_path_for_send(void)return NULL ; path->search_commit_root =1 ; path->skip_locking =1 ; + path->need_commit_sem =1 ;return path; }
Signature · 1 line
1.8.3.1