mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-04 20:53:07 -04:00
btrfs: use label to deduplicate error path at btrfs_force_cow_block()
At btrfs_force_cow_block() we have several error paths that need to unlock the "cow" extent buffer, drop the reference on it and then return an error. This is a bit verbose so add a label where we perform these tasks and make the error paths jump to that label. Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
committed by
David Sterba
parent
bb3868033a
commit
d12765dc02
@@ -588,19 +588,15 @@ int btrfs_force_cow_block(struct btrfs_trans_handle *trans,
|
||||
|
||||
ret = update_ref_for_cow(trans, root, buf, cow, &last_ref);
|
||||
if (ret) {
|
||||
btrfs_tree_unlock(cow);
|
||||
free_extent_buffer(cow);
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
return ret;
|
||||
goto error_unlock_cow;
|
||||
}
|
||||
|
||||
if (test_bit(BTRFS_ROOT_SHAREABLE, &root->state)) {
|
||||
ret = btrfs_reloc_cow_block(trans, root, buf, cow);
|
||||
if (ret) {
|
||||
btrfs_tree_unlock(cow);
|
||||
free_extent_buffer(cow);
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
return ret;
|
||||
goto error_unlock_cow;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -612,10 +608,8 @@ int btrfs_force_cow_block(struct btrfs_trans_handle *trans,
|
||||
|
||||
ret = btrfs_tree_mod_log_insert_root(root->node, cow, true);
|
||||
if (ret < 0) {
|
||||
btrfs_tree_unlock(cow);
|
||||
free_extent_buffer(cow);
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
return ret;
|
||||
goto error_unlock_cow;
|
||||
}
|
||||
atomic_inc(&cow->refs);
|
||||
rcu_assign_pointer(root->node, cow);
|
||||
@@ -625,20 +619,16 @@ int btrfs_force_cow_block(struct btrfs_trans_handle *trans,
|
||||
free_extent_buffer(buf);
|
||||
add_root_to_dirty_list(root);
|
||||
if (ret < 0) {
|
||||
btrfs_tree_unlock(cow);
|
||||
free_extent_buffer(cow);
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
return ret;
|
||||
goto error_unlock_cow;
|
||||
}
|
||||
} else {
|
||||
WARN_ON(trans->transid != btrfs_header_generation(parent));
|
||||
ret = btrfs_tree_mod_log_insert_key(parent, parent_slot,
|
||||
BTRFS_MOD_LOG_KEY_REPLACE);
|
||||
if (ret) {
|
||||
btrfs_tree_unlock(cow);
|
||||
free_extent_buffer(cow);
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
return ret;
|
||||
goto error_unlock_cow;
|
||||
}
|
||||
btrfs_set_node_blockptr(parent, parent_slot,
|
||||
cow->start);
|
||||
@@ -648,19 +638,15 @@ int btrfs_force_cow_block(struct btrfs_trans_handle *trans,
|
||||
if (last_ref) {
|
||||
ret = btrfs_tree_mod_log_free_eb(buf);
|
||||
if (ret) {
|
||||
btrfs_tree_unlock(cow);
|
||||
free_extent_buffer(cow);
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
return ret;
|
||||
goto error_unlock_cow;
|
||||
}
|
||||
}
|
||||
ret = btrfs_free_tree_block(trans, btrfs_root_id(root), buf,
|
||||
parent_start, last_ref);
|
||||
if (ret < 0) {
|
||||
btrfs_tree_unlock(cow);
|
||||
free_extent_buffer(cow);
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
return ret;
|
||||
goto error_unlock_cow;
|
||||
}
|
||||
}
|
||||
if (unlock_orig)
|
||||
@@ -669,6 +655,11 @@ int btrfs_force_cow_block(struct btrfs_trans_handle *trans,
|
||||
btrfs_mark_buffer_dirty(trans, cow);
|
||||
*cow_ret = cow;
|
||||
return 0;
|
||||
|
||||
error_unlock_cow:
|
||||
btrfs_tree_unlock(cow);
|
||||
free_extent_buffer(cow);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int should_cow_block(struct btrfs_trans_handle *trans,
|
||||
|
||||
Reference in New Issue
Block a user