mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-26 04:20:23 +09:00
btrfs: do not BUG_ON() on tree mod log failure at balance_level()
[ Upstream commit 39020d8abc ]
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: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
e15eb4ec86
commit
5bf90e5e79
@@ -912,7 +912,12 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
add_root_to_dirty_list(root);
|
||||
@@ -994,7 +999,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
|
||||
btrfs_node_key(right, &right_key, 0);
|
||||
ret = btrfs_tree_mod_log_insert_key(parent, pslot + 1,
|
||||
BTRFS_MOD_LOG_KEY_REPLACE, GFP_NOFS);
|
||||
BUG_ON(ret < 0);
|
||||
if (ret < 0) {
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
goto enospc;
|
||||
}
|
||||
btrfs_set_node_key(parent, &right_key, pslot + 1);
|
||||
btrfs_mark_buffer_dirty(parent);
|
||||
}
|
||||
@@ -1040,7 +1048,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
|
||||
btrfs_node_key(mid, &mid_key, 0);
|
||||
ret = btrfs_tree_mod_log_insert_key(parent, pslot,
|
||||
BTRFS_MOD_LOG_KEY_REPLACE, GFP_NOFS);
|
||||
BUG_ON(ret < 0);
|
||||
if (ret < 0) {
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
goto enospc;
|
||||
}
|
||||
btrfs_set_node_key(parent, &mid_key, pslot);
|
||||
btrfs_mark_buffer_dirty(parent);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user