Commit d12765dc authored by Filipe Manana's avatar Filipe Manana Committed by David Sterba

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: default avatarFilipe Manana <fdmanana@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent bb386803
...@@ -588,19 +588,15 @@ int btrfs_force_cow_block(struct btrfs_trans_handle *trans, ...@@ -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); ret = update_ref_for_cow(trans, root, buf, cow, &last_ref);
if (ret) { if (ret) {
btrfs_tree_unlock(cow);
free_extent_buffer(cow);
btrfs_abort_transaction(trans, ret); btrfs_abort_transaction(trans, ret);
return ret; goto error_unlock_cow;
} }
if (test_bit(BTRFS_ROOT_SHAREABLE, &root->state)) { if (test_bit(BTRFS_ROOT_SHAREABLE, &root->state)) {
ret = btrfs_reloc_cow_block(trans, root, buf, cow); ret = btrfs_reloc_cow_block(trans, root, buf, cow);
if (ret) { if (ret) {
btrfs_tree_unlock(cow);
free_extent_buffer(cow);
btrfs_abort_transaction(trans, ret); 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, ...@@ -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); ret = btrfs_tree_mod_log_insert_root(root->node, cow, true);
if (ret < 0) { if (ret < 0) {
btrfs_tree_unlock(cow);
free_extent_buffer(cow);
btrfs_abort_transaction(trans, ret); btrfs_abort_transaction(trans, ret);
return ret; goto error_unlock_cow;
} }
atomic_inc(&cow->refs); atomic_inc(&cow->refs);
rcu_assign_pointer(root->node, cow); rcu_assign_pointer(root->node, cow);
...@@ -625,20 +619,16 @@ int btrfs_force_cow_block(struct btrfs_trans_handle *trans, ...@@ -625,20 +619,16 @@ int btrfs_force_cow_block(struct btrfs_trans_handle *trans,
free_extent_buffer(buf); free_extent_buffer(buf);
add_root_to_dirty_list(root); add_root_to_dirty_list(root);
if (ret < 0) { if (ret < 0) {
btrfs_tree_unlock(cow);
free_extent_buffer(cow);
btrfs_abort_transaction(trans, ret); btrfs_abort_transaction(trans, ret);
return ret; goto error_unlock_cow;
} }
} else { } else {
WARN_ON(trans->transid != btrfs_header_generation(parent)); WARN_ON(trans->transid != btrfs_header_generation(parent));
ret = btrfs_tree_mod_log_insert_key(parent, parent_slot, ret = btrfs_tree_mod_log_insert_key(parent, parent_slot,
BTRFS_MOD_LOG_KEY_REPLACE); BTRFS_MOD_LOG_KEY_REPLACE);
if (ret) { if (ret) {
btrfs_tree_unlock(cow);
free_extent_buffer(cow);
btrfs_abort_transaction(trans, ret); btrfs_abort_transaction(trans, ret);
return ret; goto error_unlock_cow;
} }
btrfs_set_node_blockptr(parent, parent_slot, btrfs_set_node_blockptr(parent, parent_slot,
cow->start); cow->start);
...@@ -648,19 +638,15 @@ int btrfs_force_cow_block(struct btrfs_trans_handle *trans, ...@@ -648,19 +638,15 @@ int btrfs_force_cow_block(struct btrfs_trans_handle *trans,
if (last_ref) { if (last_ref) {
ret = btrfs_tree_mod_log_free_eb(buf); ret = btrfs_tree_mod_log_free_eb(buf);
if (ret) { if (ret) {
btrfs_tree_unlock(cow);
free_extent_buffer(cow);
btrfs_abort_transaction(trans, ret); btrfs_abort_transaction(trans, ret);
return ret; goto error_unlock_cow;
} }
} }
ret = btrfs_free_tree_block(trans, btrfs_root_id(root), buf, ret = btrfs_free_tree_block(trans, btrfs_root_id(root), buf,
parent_start, last_ref); parent_start, last_ref);
if (ret < 0) { if (ret < 0) {
btrfs_tree_unlock(cow);
free_extent_buffer(cow);
btrfs_abort_transaction(trans, ret); btrfs_abort_transaction(trans, ret);
return ret; goto error_unlock_cow;
} }
} }
if (unlock_orig) if (unlock_orig)
...@@ -669,6 +655,11 @@ int btrfs_force_cow_block(struct btrfs_trans_handle *trans, ...@@ -669,6 +655,11 @@ int btrfs_force_cow_block(struct btrfs_trans_handle *trans,
btrfs_mark_buffer_dirty(trans, cow); btrfs_mark_buffer_dirty(trans, cow);
*cow_ret = cow; *cow_ret = cow;
return 0; 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, static inline int should_cow_block(struct btrfs_trans_handle *trans,
......
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