diff mbox series

[v3,40/54] btrfs: handle errors in reference count manipulation in replace_path

Message ID 25314fe734d56e1a4fc924e7a5f923ce01fed88d.1606938211.git.josef@toxicpanda.com (mailing list archive)
State New, archived
Headers show
Series Cleanup error handling in relocation | expand

Commit Message

Josef Bacik Dec. 2, 2020, 7:50 p.m. UTC
If any of the reference count manipulation stuff fails in replace_path
we need to abort the transaction, as we've modified the blocks already.
We can simply break at this point and everything will be cleaned up.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/relocation.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

Comments

Qu Wenruo Dec. 3, 2020, 5:14 a.m. UTC | #1
On 2020/12/3 上午3:50, Josef Bacik wrote:
> If any of the reference count manipulation stuff fails in replace_path
> we need to abort the transaction, as we've modified the blocks already.
> We can simply break at this point and everything will be cleaned up.
> 
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>

Reviewed-by: Qu Wenruo <wqu@suse.com>

Thanks,
Qu
> ---
>  fs/btrfs/relocation.c | 20 ++++++++++++++++----
>  1 file changed, 16 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
> index 8c407ebc5500..ef33b89e352e 100644
> --- a/fs/btrfs/relocation.c
> +++ b/fs/btrfs/relocation.c
> @@ -1355,27 +1355,39 @@ int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc,
>  		ref.skip_qgroup = true;
>  		btrfs_init_tree_ref(&ref, level - 1, src->root_key.objectid);
>  		ret = btrfs_inc_extent_ref(trans, &ref);
> -		BUG_ON(ret);
> +		if (ret) {
> +			btrfs_abort_transaction(trans, ret);
> +			break;
> +		}
>  		btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, new_bytenr,
>  				       blocksize, 0);
>  		ref.skip_qgroup = true;
>  		btrfs_init_tree_ref(&ref, level - 1, dest->root_key.objectid);
>  		ret = btrfs_inc_extent_ref(trans, &ref);
> -		BUG_ON(ret);
> +		if (ret) {
> +			btrfs_abort_transaction(trans, ret);
> +			break;
> +		}
>  
>  		btrfs_init_generic_ref(&ref, BTRFS_DROP_DELAYED_REF, new_bytenr,
>  				       blocksize, path->nodes[level]->start);
>  		btrfs_init_tree_ref(&ref, level - 1, src->root_key.objectid);
>  		ref.skip_qgroup = true;
>  		ret = btrfs_free_extent(trans, &ref);
> -		BUG_ON(ret);
> +		if (ret) {
> +			btrfs_abort_transaction(trans, ret);
> +			break;
> +		}
>  
>  		btrfs_init_generic_ref(&ref, BTRFS_DROP_DELAYED_REF, old_bytenr,
>  				       blocksize, 0);
>  		btrfs_init_tree_ref(&ref, level - 1, dest->root_key.objectid);
>  		ref.skip_qgroup = true;
>  		ret = btrfs_free_extent(trans, &ref);
> -		BUG_ON(ret);
> +		if (ret) {
> +			btrfs_abort_transaction(trans, ret);
> +			break;
> +		}
>  
>  		btrfs_unlock_up_safe(path, 0);
>  
>
diff mbox series

Patch

diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 8c407ebc5500..ef33b89e352e 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -1355,27 +1355,39 @@  int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc,
 		ref.skip_qgroup = true;
 		btrfs_init_tree_ref(&ref, level - 1, src->root_key.objectid);
 		ret = btrfs_inc_extent_ref(trans, &ref);
-		BUG_ON(ret);
+		if (ret) {
+			btrfs_abort_transaction(trans, ret);
+			break;
+		}
 		btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, new_bytenr,
 				       blocksize, 0);
 		ref.skip_qgroup = true;
 		btrfs_init_tree_ref(&ref, level - 1, dest->root_key.objectid);
 		ret = btrfs_inc_extent_ref(trans, &ref);
-		BUG_ON(ret);
+		if (ret) {
+			btrfs_abort_transaction(trans, ret);
+			break;
+		}
 
 		btrfs_init_generic_ref(&ref, BTRFS_DROP_DELAYED_REF, new_bytenr,
 				       blocksize, path->nodes[level]->start);
 		btrfs_init_tree_ref(&ref, level - 1, src->root_key.objectid);
 		ref.skip_qgroup = true;
 		ret = btrfs_free_extent(trans, &ref);
-		BUG_ON(ret);
+		if (ret) {
+			btrfs_abort_transaction(trans, ret);
+			break;
+		}
 
 		btrfs_init_generic_ref(&ref, BTRFS_DROP_DELAYED_REF, old_bytenr,
 				       blocksize, 0);
 		btrfs_init_tree_ref(&ref, level - 1, dest->root_key.objectid);
 		ref.skip_qgroup = true;
 		ret = btrfs_free_extent(trans, &ref);
-		BUG_ON(ret);
+		if (ret) {
+			btrfs_abort_transaction(trans, ret);
+			break;
+		}
 
 		btrfs_unlock_up_safe(path, 0);