btrfs: use label to deduplicate error path at btrfs_force_cow_block()
authorFilipe Manana <fdmanana@suse.com>
Mon, 17 Jun 2024 11:09:59 +0000 (12:09 +0100)
committerDavid Sterba <dsterba@suse.com>
Thu, 11 Jul 2024 13:33:26 +0000 (15:33 +0200)
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>
fs/btrfs/ctree.c

index a155dbc..763b9a1 100644 (file)
@@ -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,