Message ID | 25314fe734d56e1a4fc924e7a5f923ce01fed88d.1606938211.git.josef@toxicpanda.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Cleanup error handling in relocation | expand |
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 --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);
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(-)