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

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
Loading
Loading
Loading
Loading
+12 −21
Original line number Diff line number Diff line
@@ -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,