Message ID | 7d9be8388f0a32f5ae8bcaf73c215997e76253ed.1686164820.git.fdmanana@suse.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | btrfs: some fixes and updates around handling errors for tree mod log operations | expand |
On 2023/6/8 03:24, fdmanana@kernel.org wrote: > From: Filipe Manana <fdmanana@suse.com> > > At insert_new_root(), instead of doing a BUG_ON() in case we fail to > record the tree mod log operation, just return the error to the callers > after releasing the allocated tree block. At this point we haven't made > any changes to the b+tree, so we haven't left it in an inconsistent state > and therefore have no need to abort the transaction. All we need to do is > to unlock and free the extent buffer we just allocated with the purpose > of making it the new root. > > Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: Qu Wenruo <wqu@suse.com> Thanks, Qu > --- > fs/btrfs/ctree.c | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c > index e3c949fa136f..6e59343034d6 100644 > --- a/fs/btrfs/ctree.c > +++ b/fs/btrfs/ctree.c > @@ -2956,7 +2956,12 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans, > > old = root->node; > ret = btrfs_tree_mod_log_insert_root(root->node, c, false); > - BUG_ON(ret < 0); > + if (ret < 0) { > + btrfs_free_tree_block(trans, btrfs_root_id(root), c, 0, 1); > + btrfs_tree_unlock(c); > + free_extent_buffer(c); > + return ret; > + } > rcu_assign_pointer(root->node, c); > > /* the super has an extra ref to root->node */
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index e3c949fa136f..6e59343034d6 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -2956,7 +2956,12 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans, old = root->node; ret = btrfs_tree_mod_log_insert_root(root->node, c, false); - BUG_ON(ret < 0); + if (ret < 0) { + btrfs_free_tree_block(trans, btrfs_root_id(root), c, 0, 1); + btrfs_tree_unlock(c); + free_extent_buffer(c); + return ret; + } rcu_assign_pointer(root->node, c); /* the super has an extra ref to root->node */