Commit 39020d8a authored by Filipe Manana's avatar Filipe Manana Committed by David Sterba

btrfs: do not BUG_ON() on tree mod log failure at balance_level()

At balance_level(), instead of doing a BUG_ON() in case we fail to record
tree mod log operations, do a transaction abort and return the error to
the callers. There's really no need for the BUG_ON() as we can release
all resources in this context, and we have to abort because other future
tree searches that use the tree mod log (btrfs_search_old_slot()) may get
inconsistent results if other operations modify the tree after that
failure and before the tree mod log based search.

CC: stable@vger.kernel.org # 5.4+
Reviewed-by: default avatarQu Wenruo <wqu@suse.com>
Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 40b0a749
...@@ -1054,7 +1054,12 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, ...@@ -1054,7 +1054,12 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
} }
ret = btrfs_tree_mod_log_insert_root(root->node, child, true); ret = btrfs_tree_mod_log_insert_root(root->node, child, true);
BUG_ON(ret < 0); if (ret < 0) {
btrfs_tree_unlock(child);
free_extent_buffer(child);
btrfs_abort_transaction(trans, ret);
goto enospc;
}
rcu_assign_pointer(root->node, child); rcu_assign_pointer(root->node, child);
add_root_to_dirty_list(root); add_root_to_dirty_list(root);
...@@ -1142,7 +1147,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, ...@@ -1142,7 +1147,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
btrfs_node_key(right, &right_key, 0); btrfs_node_key(right, &right_key, 0);
ret = btrfs_tree_mod_log_insert_key(parent, pslot + 1, ret = btrfs_tree_mod_log_insert_key(parent, pslot + 1,
BTRFS_MOD_LOG_KEY_REPLACE); BTRFS_MOD_LOG_KEY_REPLACE);
BUG_ON(ret < 0); if (ret < 0) {
btrfs_abort_transaction(trans, ret);
goto enospc;
}
btrfs_set_node_key(parent, &right_key, pslot + 1); btrfs_set_node_key(parent, &right_key, pslot + 1);
btrfs_mark_buffer_dirty(parent); btrfs_mark_buffer_dirty(parent);
} }
...@@ -1188,7 +1196,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, ...@@ -1188,7 +1196,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
btrfs_node_key(mid, &mid_key, 0); btrfs_node_key(mid, &mid_key, 0);
ret = btrfs_tree_mod_log_insert_key(parent, pslot, ret = btrfs_tree_mod_log_insert_key(parent, pslot,
BTRFS_MOD_LOG_KEY_REPLACE); BTRFS_MOD_LOG_KEY_REPLACE);
BUG_ON(ret < 0); if (ret < 0) {
btrfs_abort_transaction(trans, ret);
goto enospc;
}
btrfs_set_node_key(parent, &mid_key, pslot); btrfs_set_node_key(parent, &mid_key, pslot);
btrfs_mark_buffer_dirty(parent); btrfs_mark_buffer_dirty(parent);
} }
......
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