From patchwork Wed Jun 7 19:24:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13271163 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4B006C7EE23 for ; Wed, 7 Jun 2023 19:24:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231384AbjFGTYp (ORCPT ); Wed, 7 Jun 2023 15:24:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45516 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229900AbjFGTYn (ORCPT ); Wed, 7 Jun 2023 15:24:43 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DBFDA1FDA for ; Wed, 7 Jun 2023 12:24:42 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 7736C63C4E for ; Wed, 7 Jun 2023 19:24:42 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 60FFEC4339B for ; Wed, 7 Jun 2023 19:24:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1686165881; bh=YHNbVFkwKYnyewFiOqNTvq9LerY5z38n7rvU6SvY23o=; h=From:To:Subject:Date:In-Reply-To:References:From; b=akWnLc3cnUderQ91GHjIdiW3TDMEYGOIWUbVg5HiXM8s7MkuYqSOvUPFl8rLzbaZ6 foknS2D7g7bhtEQDkqXUh5mqr2fynArhWASxplFFVn4PWIIthRzLHdNGshlBwz9yIj lUVBev38TSPS31GrARRYrzxHq5qPUU/rY8azfkZdE4o7DtPBmxwQ6sxbRqelu5pGTu zrXu3OX2tV4Be1oBSxpBHRTxEdb+D02gvEWOEMipLAPVNS7Vw3K6vOURhVYO8t1eKm uGwd5nYxtASasZlXnqQdJ7UTyMi2P0eZGl5fK5mnT9mcVoePg1QNw+4lKjGgVimNtZ kL7lELhNgrhGg== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH 01/13] btrfs: add missing error handling when logging operation while COWing extent buffer Date: Wed, 7 Jun 2023 20:24:25 +0100 Message-Id: <8cb7f172ba4c37685955b891ba91f57aa3daea76.1686164800.git.fdmanana@suse.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Filipe Manana When COWing an extent buffer that is not the root node, we need to log in the tree mod log that we replaced a pointer in the parent node, otherwise a tree mod log user doing a search on the b+tree can return incorrect results (that miss something). We are doing the call to btrfs_tree_mod_log_insert_key() but we totally ignore its return value. So fix this by adding the missing error handling, resulting in a transaction abort and freeing the COWed extent buffer. Fixes: f230475e62f7 ("Btrfs: put all block modifications into the tree mod log") Signed-off-by: Filipe Manana Reviewed-by: Qu Wenruo --- fs/btrfs/ctree.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 385524224037..7f7f13965fe9 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -595,8 +595,14 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, add_root_to_dirty_list(root); } else { WARN_ON(trans->transid != btrfs_header_generation(parent)); - btrfs_tree_mod_log_insert_key(parent, parent_slot, - BTRFS_MOD_LOG_KEY_REPLACE); + 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; + } btrfs_set_node_blockptr(parent, parent_slot, cow->start); btrfs_set_node_ptr_generation(parent, parent_slot, From patchwork Wed Jun 7 19:24:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13271164 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 424E2C7EE25 for ; Wed, 7 Jun 2023 19:24:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229900AbjFGTYq (ORCPT ); Wed, 7 Jun 2023 15:24:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45522 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231360AbjFGTYo (ORCPT ); Wed, 7 Jun 2023 15:24:44 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DCA241FD5 for ; Wed, 7 Jun 2023 12:24:43 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 6EDFD639BC for ; Wed, 7 Jun 2023 19:24:43 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 557AFC433EF for ; Wed, 7 Jun 2023 19:24:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1686165882; bh=nvwOE9cHo/ym8MpkZ21ZxYslS3u6sH3E00tXCkh9KY8=; h=From:To:Subject:Date:In-Reply-To:References:From; b=tKi92EyC9+s8lS2pM72RkNs56Vo8nssWVGr3C84Fw7wPswfOYhhGcpHE3GKLzKe4d YXq/76ecmDWqQFbrXBAGIQlu9z62bpVKTTcd2ZwKXdmMnns2onThEc+qIuhMaUOql3 nACKRLCvxplSqM/IH5D+jtdQSMqMrc+6ZJIhi10ALnPAqpJrJ7PTkerizEkWO3NjAY VI+d9Mv2BgHVstR/6V5Xf+VjceMGpF9+Y+Tix8OVc9gNaJotCBNDZAuoKInkRynXWK 3RFT0kcJYm0sthR1zKN4bL7fFsdireLfAJV0ybgUZuAMslBBZBbrIA9Mug8pmHkInN 9rmWiYkAuArUw== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH 02/13] btrfs: fix extent buffer leak after failure tree mod log failure at split_node() Date: Wed, 7 Jun 2023 20:24:26 +0100 Message-Id: <33c0bac2c25c330f773ba765c98efa3992cdc166.1686164803.git.fdmanana@suse.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Filipe Manana At split_node(), if we fail to log the tree mod log copy operation, we return without unlocking the split extent buffer we just allocated and without decrementing the reference we own on it. Fix this by unlocking it and decrementing the ref count before returning. Fixes: 5de865eebb83 ("Btrfs: fix tree mod logging") Signed-off-by: Filipe Manana Reviewed-by: Qu Wenruo --- fs/btrfs/ctree.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 7f7f13965fe9..8496535828de 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -3053,6 +3053,8 @@ static noinline int split_node(struct btrfs_trans_handle *trans, ret = btrfs_tree_mod_log_eb_copy(split, c, 0, mid, c_nritems - mid); if (ret) { + btrfs_tree_unlock(split); + free_extent_buffer(split); btrfs_abort_transaction(trans, ret); return ret; } From patchwork Wed Jun 7 19:24:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13271166 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AE5B9C7EE23 for ; Wed, 7 Jun 2023 19:24:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231660AbjFGTY5 (ORCPT ); Wed, 7 Jun 2023 15:24:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45534 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232147AbjFGTYq (ORCPT ); Wed, 7 Jun 2023 15:24:46 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DB4881FD5 for ; Wed, 7 Jun 2023 12:24:44 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 646B663C4E for ; Wed, 7 Jun 2023 19:24:44 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4AE77C433D2 for ; Wed, 7 Jun 2023 19:24:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1686165883; bh=TQkwbf/t/gDCAkVEbdrtP0rI/xJNhPmssnvJfri110k=; h=From:To:Subject:Date:In-Reply-To:References:From; b=UYETg72KODl7VPRClrEE+P+Cxam2029GFXwuq3UtWi58LUIbDcmD9nFmFzjtWe5kI 5RR9i8ott5SIpGER+KFDhap734s39fWvC/lKwsGmCkhf124MXd0zHOGTUXqlKouYdN FeNV641FK1FGN5jXgDLXilOf8mVG8n60L64Msk/feO5BbziezgpuDBqxVl32+QFdTZ oLi5PV9xIeN0tqRNfY8zHwC8XzsPnk3N4BnCb6JdREt2xmfG8WOSaic5UsboLIQodI kp76HFgIs/Hvytn40yJhJY4BXmYdRgnEgzajQV2I/tba0RQdEMxhK5x6kPSJheqwR9 mPDXhgA45ZrEQ== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH 03/13] btrfs: avoid tree mod log ENOMEM failures when we don't need to log Date: Wed, 7 Jun 2023 20:24:27 +0100 Message-Id: <84ca710f9c1b81c3fce3c4df28b6e66cb56efb99.1686164804.git.fdmanana@suse.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Filipe Manana When logging tree mod log operations we start by checking, in a lockless manner, if we need to log - if we don't, we just return and do nothing, otherwise we will allocate one or more tree mod log operations and then check again if we need to log. This second check will take the tree mod log lock in write mode if we need to log, otherwise it will do nothing and we just free the allocated memory and return success. We can improve on this by not returning an error in case the memory allocations fail, unless the second check tells us that we actually need to log. That is, if we fail to allocate memory and the second check tells use that we don't need to log, we can just return success and avoid returning -ENOMEM to the caller. Currently tree mod log failures are dealt with either a BUG_ON() or a transaction abort, as tree mod log operations are logged in code paths that modify a b+tree. So just avoid failing with -ENOMEM if we fail to allocate a tree mod log operation unless we actually need to log the operations, that is, if tree_mod_dont_log() returns true. Signed-off-by: Filipe Manana --- fs/btrfs/tree-mod-log.c | 148 +++++++++++++++++++++++++++++++--------- 1 file changed, 114 insertions(+), 34 deletions(-) diff --git a/fs/btrfs/tree-mod-log.c b/fs/btrfs/tree-mod-log.c index 07c086f9e35e..3df6153d5d5a 100644 --- a/fs/btrfs/tree-mod-log.c +++ b/fs/btrfs/tree-mod-log.c @@ -226,21 +226,32 @@ int btrfs_tree_mod_log_insert_key(struct extent_buffer *eb, int slot, enum btrfs_mod_log_op op) { struct tree_mod_elem *tm; - int ret; + int ret = 0; if (!tree_mod_need_log(eb->fs_info, eb)) return 0; tm = alloc_tree_mod_elem(eb, slot, op); if (!tm) - return -ENOMEM; + ret = -ENOMEM; if (tree_mod_dont_log(eb->fs_info, eb)) { kfree(tm); + /* + * Don't error if we failed to allocate memory because we don't + * need to log. + */ return 0; + } else if (ret != 0) { + /* + * We previously failed to allocate memory and we need to log, + * so we have to fail. + */ + goto out_unlock; } ret = tree_mod_log_insert(eb->fs_info, tm); +out_unlock: write_unlock(&eb->fs_info->tree_mod_log_lock); if (ret) kfree(tm); @@ -282,14 +293,16 @@ int btrfs_tree_mod_log_insert_move(struct extent_buffer *eb, return 0; tm_list = kcalloc(nr_items, sizeof(struct tree_mod_elem *), GFP_NOFS); - if (!tm_list) - return -ENOMEM; + if (!tm_list) { + ret = -ENOMEM; + goto lock; + } tm = tree_mod_log_alloc_move(eb, dst_slot, src_slot, nr_items); if (IS_ERR(tm)) { ret = PTR_ERR(tm); tm = NULL; - goto free_tms; + goto lock; } for (i = 0; i + dst_slot < src_slot && i < nr_items; i++) { @@ -297,14 +310,28 @@ int btrfs_tree_mod_log_insert_move(struct extent_buffer *eb, BTRFS_MOD_LOG_KEY_REMOVE_WHILE_MOVING); if (!tm_list[i]) { ret = -ENOMEM; - goto free_tms; + goto lock; } } - if (tree_mod_dont_log(eb->fs_info, eb)) +lock: + if (tree_mod_dont_log(eb->fs_info, eb)) { + /* + * Don't error if we failed to allocate memory because we don't + * need to log. + */ + ret = 0; goto free_tms; + } locked = true; + /* + * We previously failed to allocate memory and we need to log, so we + * have to fail. + */ + if (ret != 0) + goto free_tms; + /* * When we override something during the move, we log these removals. * This can only happen when we move towards the beginning of the @@ -325,10 +352,12 @@ int btrfs_tree_mod_log_insert_move(struct extent_buffer *eb, return 0; free_tms: - for (i = 0; i < nr_items; i++) { - if (tm_list[i] && !RB_EMPTY_NODE(&tm_list[i]->node)) - rb_erase(&tm_list[i]->node, &eb->fs_info->tree_mod_log); - kfree(tm_list[i]); + if (tm_list) { + for (i = 0; i < nr_items; i++) { + if (tm_list[i] && !RB_EMPTY_NODE(&tm_list[i]->node)) + rb_erase(&tm_list[i]->node, &eb->fs_info->tree_mod_log); + kfree(tm_list[i]); + } } if (locked) write_unlock(&eb->fs_info->tree_mod_log_lock); @@ -378,14 +407,14 @@ int btrfs_tree_mod_log_insert_root(struct extent_buffer *old_root, GFP_NOFS); if (!tm_list) { ret = -ENOMEM; - goto free_tms; + goto lock; } for (i = 0; i < nritems; i++) { tm_list[i] = alloc_tree_mod_elem(old_root, i, BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING); if (!tm_list[i]) { ret = -ENOMEM; - goto free_tms; + goto lock; } } } @@ -393,7 +422,7 @@ int btrfs_tree_mod_log_insert_root(struct extent_buffer *old_root, tm = kzalloc(sizeof(*tm), GFP_NOFS); if (!tm) { ret = -ENOMEM; - goto free_tms; + goto lock; } tm->logical = new_root->start; @@ -402,14 +431,28 @@ int btrfs_tree_mod_log_insert_root(struct extent_buffer *old_root, tm->generation = btrfs_header_generation(old_root); tm->op = BTRFS_MOD_LOG_ROOT_REPLACE; - if (tree_mod_dont_log(fs_info, NULL)) +lock: + if (tree_mod_dont_log(fs_info, NULL)) { + /* + * Don't error if we failed to allocate memory because we don't + * need to log. + */ + ret = 0; goto free_tms; + } else if (ret != 0) { + /* + * We previously failed to allocate memory and we need to log, + * so we have to fail. + */ + goto out_unlock; + } if (tm_list) ret = tree_mod_log_free_eb(fs_info, tm_list, nritems); if (!ret) ret = tree_mod_log_insert(fs_info, tm); +out_unlock: write_unlock(&fs_info->tree_mod_log_lock); if (ret) goto free_tms; @@ -501,7 +544,8 @@ int btrfs_tree_mod_log_eb_copy(struct extent_buffer *dst, struct btrfs_fs_info *fs_info = dst->fs_info; int ret = 0; struct tree_mod_elem **tm_list = NULL; - struct tree_mod_elem **tm_list_add, **tm_list_rem; + struct tree_mod_elem **tm_list_add = NULL; + struct tree_mod_elem **tm_list_rem = NULL; int i; bool locked = false; struct tree_mod_elem *dst_move_tm = NULL; @@ -517,8 +561,10 @@ int btrfs_tree_mod_log_eb_copy(struct extent_buffer *dst, tm_list = kcalloc(nr_items * 2, sizeof(struct tree_mod_elem *), GFP_NOFS); - if (!tm_list) - return -ENOMEM; + if (!tm_list) { + ret = -ENOMEM; + goto lock; + } if (dst_move_nr_items) { dst_move_tm = tree_mod_log_alloc_move(dst, dst_offset + nr_items, @@ -526,7 +572,7 @@ int btrfs_tree_mod_log_eb_copy(struct extent_buffer *dst, if (IS_ERR(dst_move_tm)) { ret = PTR_ERR(dst_move_tm); dst_move_tm = NULL; - goto free_tms; + goto lock; } } if (src_move_nr_items) { @@ -536,7 +582,7 @@ int btrfs_tree_mod_log_eb_copy(struct extent_buffer *dst, if (IS_ERR(src_move_tm)) { ret = PTR_ERR(src_move_tm); src_move_tm = NULL; - goto free_tms; + goto lock; } } @@ -547,21 +593,35 @@ int btrfs_tree_mod_log_eb_copy(struct extent_buffer *dst, BTRFS_MOD_LOG_KEY_REMOVE); if (!tm_list_rem[i]) { ret = -ENOMEM; - goto free_tms; + goto lock; } tm_list_add[i] = alloc_tree_mod_elem(dst, i + dst_offset, BTRFS_MOD_LOG_KEY_ADD); if (!tm_list_add[i]) { ret = -ENOMEM; - goto free_tms; + goto lock; } } - if (tree_mod_dont_log(fs_info, NULL)) +lock: + if (tree_mod_dont_log(fs_info, NULL)) { + /* + * Don't error if we failed to allocate memory because we don't + * need to log. + */ + ret = 0; goto free_tms; + } locked = true; + /* + * We previously failed to allocate memory and we need to log, so we + * have to fail. + */ + if (ret != 0) + goto free_tms; + if (dst_move_tm) { ret = tree_mod_log_insert(fs_info, dst_move_tm); if (ret) @@ -593,10 +653,12 @@ int btrfs_tree_mod_log_eb_copy(struct extent_buffer *dst, if (src_move_tm && !RB_EMPTY_NODE(&src_move_tm->node)) rb_erase(&src_move_tm->node, &fs_info->tree_mod_log); kfree(src_move_tm); - for (i = 0; i < nr_items * 2; i++) { - if (tm_list[i] && !RB_EMPTY_NODE(&tm_list[i]->node)) - rb_erase(&tm_list[i]->node, &fs_info->tree_mod_log); - kfree(tm_list[i]); + if (tm_list) { + for (i = 0; i < nr_items * 2; i++) { + if (tm_list[i] && !RB_EMPTY_NODE(&tm_list[i]->node)) + rb_erase(&tm_list[i]->node, &fs_info->tree_mod_log); + kfree(tm_list[i]); + } } if (locked) write_unlock(&fs_info->tree_mod_log_lock); @@ -617,22 +679,38 @@ int btrfs_tree_mod_log_free_eb(struct extent_buffer *eb) nritems = btrfs_header_nritems(eb); tm_list = kcalloc(nritems, sizeof(struct tree_mod_elem *), GFP_NOFS); - if (!tm_list) - return -ENOMEM; + if (!tm_list) { + ret = -ENOMEM; + goto lock; + } for (i = 0; i < nritems; i++) { tm_list[i] = alloc_tree_mod_elem(eb, i, BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING); if (!tm_list[i]) { ret = -ENOMEM; - goto free_tms; + goto lock; } } - if (tree_mod_dont_log(eb->fs_info, eb)) +lock: + if (tree_mod_dont_log(eb->fs_info, eb)) { + /* + * Don't error if we failed to allocate memory because we don't + * need to log. + */ + ret = 0; goto free_tms; + } else if (ret != 0) { + /* + * We previously failed to allocate memory and we need to log, + * so we have to fail. + */ + goto out_unlock; + } ret = tree_mod_log_free_eb(eb->fs_info, tm_list, nritems); +out_unlock: write_unlock(&eb->fs_info->tree_mod_log_lock); if (ret) goto free_tms; @@ -641,9 +719,11 @@ int btrfs_tree_mod_log_free_eb(struct extent_buffer *eb) return 0; free_tms: - for (i = 0; i < nritems; i++) - kfree(tm_list[i]); - kfree(tm_list); + if (tm_list) { + for (i = 0; i < nritems; i++) + kfree(tm_list[i]); + kfree(tm_list); + } return ret; } From patchwork Wed Jun 7 19:24:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13271165 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D7DB0C77B7A for ; Wed, 7 Jun 2023 19:24:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232262AbjFGTYr (ORCPT ); Wed, 7 Jun 2023 15:24:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45532 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231660AbjFGTYq (ORCPT ); Wed, 7 Jun 2023 15:24:46 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CB9BB1FDA for ; Wed, 7 Jun 2023 12:24:45 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 5EDC2639BC for ; Wed, 7 Jun 2023 19:24:45 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 41CBFC433EF for ; Wed, 7 Jun 2023 19:24:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1686165884; bh=jYKVurW1jejNCsQA0grZ4GuvimYWAQi2AtMolKOXeag=; h=From:To:Subject:Date:In-Reply-To:References:From; b=USDTJRaSGvfuCtp3MS6E9I8kkRrlkalDkrOS+66qTg2plUla0GdMYJiWmFWq+u1qp /s326vGQmrL4+Zy4+IA7mT37HlyifVkRD5CvzV1r7sbCvWIgkIq4y9ku2k+SWE+Ra+ 50E1uDQSZqy+iTQCmzaaGDJRuwpaZiNN1PzqK2JONNSDDiHm2pQUqZ6mKy8rMJRtN6 8KIG2/zXfbQaJbVcrsHkkE/oRKigVkLhLkMCW2sXsWjgwDkDOhXmDowvZx9sqgnLHK y+MbUXURO/A4oWXVi5sv33MaKSu3LMH1YDsUdMVszOlJU/bO4rv4qe3szh6gy960PQ oxWGdcDiMN/Tw== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH 04/13] btrfs: do not BUG_ON() on tree mod log failure at __btrfs_cow_block() Date: Wed, 7 Jun 2023 20:24:28 +0100 Message-Id: <33736c36355cd1d902b9f2ccc65d5f6fc13c5e56.1686164806.git.fdmanana@suse.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Filipe Manana At __btrfs_cow_block(), instead of doing a BUG_ON() in case we fail to record a tree mod log root insertion operation, do a transaction abort instead. There's really no need for the BUG_ON(), we can properly release all resources in this context and turn the filesystem to RO mode and in an error state instead. Signed-off-by: Filipe Manana Reviewed-by: Qu Wenruo --- fs/btrfs/ctree.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 8496535828de..d6c29564ce49 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -584,9 +584,14 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, btrfs_header_backref_rev(buf) < BTRFS_MIXED_BACKREF_REV) parent_start = buf->start; - atomic_inc(&cow->refs); ret = btrfs_tree_mod_log_insert_root(root->node, cow, true); - BUG_ON(ret < 0); + if (ret < 0) { + btrfs_tree_unlock(cow); + free_extent_buffer(cow); + btrfs_abort_transaction(trans, ret); + return ret; + } + atomic_inc(&cow->refs); rcu_assign_pointer(root->node, cow); btrfs_free_tree_block(trans, btrfs_root_id(root), buf, From patchwork Wed Jun 7 19:24:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13271168 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D38A8C7EE43 for ; Wed, 7 Jun 2023 19:25:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232037AbjFGTY7 (ORCPT ); Wed, 7 Jun 2023 15:24:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45540 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232322AbjFGTYr (ORCPT ); Wed, 7 Jun 2023 15:24:47 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BC96B1FDA for ; Wed, 7 Jun 2023 12:24:46 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 50FB464319 for ; Wed, 7 Jun 2023 19:24:46 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 36C5AC4339B for ; Wed, 7 Jun 2023 19:24:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1686165885; bh=FNcsxZs/Nu3S9UPO66qsu5qD30c9KgD8AegESC9oMvo=; h=From:To:Subject:Date:In-Reply-To:References:From; b=RrNGhoTHjzzaj269ZJS0O18KUf1wBXmKhOBnJe0hrH6sVsq5IQElrDuGickKk85UE BVDpvAB/agw/tupbQ/H6mg+jZjDguUmWPsQljmYHfflk9Hv3kMAD+kinSKSSNVr5tg ri1Y3OqHAxaT+AdJP0qIgxlTbCRpVGbkxZxIKopcRPJ9QbeVxrrRMESp5gmfaY6nR1 tbw1r73sj3XzbRJo8wROjGXsrN4e/R/mgJzTIsjJotAoQQ7JERSwbDc804Nqtsm21q wpC7hIyDXaKlDsGxRFZqN3zNpUUWAeIFmyvlAm7rdKN7ohStLr71WcogCWdlwRDXia Ix49XRd8+tvcA== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH 05/13] btrfs: do not BUG_ON() on tree mod log failure at balance_level() Date: Wed, 7 Jun 2023 20:24:29 +0100 Message-Id: <4d83a67f420c7e8f6ceb4535ab5431fde9ecc82f.1686164810.git.fdmanana@suse.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Filipe Manana At balance_level(), instead of doing a BUG_ON() in case we fail to record tree mod log operations, do a transaction abort and return the error to the callers. There's really no need for the BUG_ON() as we can release all resources in this context, and we have to abort because other future tree searches that use the tree mod log (btrfs_search_old_slot()) may get inconsistent results if other operations modify the tree after that failure and before the tree mod log based search. Signed-off-by: Filipe Manana Reviewed-by: Qu Wenruo --- fs/btrfs/ctree.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index d6c29564ce49..d60b28c6bd1b 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -1054,7 +1054,12 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, } ret = btrfs_tree_mod_log_insert_root(root->node, child, true); - BUG_ON(ret < 0); + if (ret < 0) { + btrfs_tree_unlock(child); + free_extent_buffer(child); + btrfs_abort_transaction(trans, ret); + goto enospc; + } rcu_assign_pointer(root->node, child); add_root_to_dirty_list(root); @@ -1142,7 +1147,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, btrfs_node_key(right, &right_key, 0); ret = btrfs_tree_mod_log_insert_key(parent, pslot + 1, BTRFS_MOD_LOG_KEY_REPLACE); - BUG_ON(ret < 0); + if (ret < 0) { + btrfs_abort_transaction(trans, ret); + goto enospc; + } btrfs_set_node_key(parent, &right_key, pslot + 1); btrfs_mark_buffer_dirty(parent); } @@ -1188,7 +1196,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, btrfs_node_key(mid, &mid_key, 0); ret = btrfs_tree_mod_log_insert_key(parent, pslot, BTRFS_MOD_LOG_KEY_REPLACE); - BUG_ON(ret < 0); + if (ret < 0) { + btrfs_abort_transaction(trans, ret); + goto enospc; + } btrfs_set_node_key(parent, &mid_key, pslot); btrfs_mark_buffer_dirty(parent); } From patchwork Wed Jun 7 19:24:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13271167 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9C40DC7EE25 for ; Wed, 7 Jun 2023 19:24:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233184AbjFGTY6 (ORCPT ); Wed, 7 Jun 2023 15:24:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45546 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232430AbjFGTYs (ORCPT ); Wed, 7 Jun 2023 15:24:48 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 633081FD5 for ; Wed, 7 Jun 2023 12:24:47 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 434D9636CF for ; Wed, 7 Jun 2023 19:24:47 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2CAFFC433EF for ; Wed, 7 Jun 2023 19:24:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1686165886; bh=YDFZ3h3wrfBYXl8pD7AAaf2SYaAHJV+vJYQQodIkngs=; h=From:To:Subject:Date:In-Reply-To:References:From; b=WxEQqs1j71QCCQt9BIposvR/NZUyHkFsOCFlmPN3rc4j3lYwNEhc4nuTpJE8hG7Aa xLayoRPzslI7T5rHeovbY840AuX40VEXTgZynkoIO+U6ZKFvtoX+/NFVo55vUg82Ap lV47UY9n9S0Y2mViXLOKzztU2N9FJ70JOqGCSsL7v5ELY2UnSlKtIKLFwxAn5xhYY0 0JREWLnTYYbRvX9NvgznUmeWSzO4QMbrw0XHsIOS3dOxY3iUACaJtXB+zZ1VhZd0kf tCRvM39vJH7an/bjnyRZwvnR9yKg/7Bw6n7jjiK8jYZsdjSzCWRp+C1fPOQ4l6DWCP AAY022PM0Mz7g== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH 06/13] btrfs: rename enospc label to out at balance_level() Date: Wed, 7 Jun 2023 20:24:30 +0100 Message-Id: <4da7393afeffff23420fb2eafa27db99f882c39c.1686164811.git.fdmanana@suse.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Filipe Manana At balance_level() we have this 'enospc' label where we jump to in case we get an error at several places. However that error is certainly not -ENOSPC in call cases, it can be -EIO or -ENOMEM when reading a child extent buffer for example, or -ENOMEM when trying to record tree mod log operations. So to make this less confusing, rename the label to 'out'. Signed-off-by: Filipe Manana Reviewed-by: Qu Wenruo Reviewed-by: Anand Jain --- fs/btrfs/ctree.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index d60b28c6bd1b..e98f9e205e25 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -1041,7 +1041,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, if (IS_ERR(child)) { ret = PTR_ERR(child); btrfs_handle_fs_error(fs_info, ret, NULL); - goto enospc; + goto out; } btrfs_tree_lock(child); @@ -1050,7 +1050,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, if (ret) { btrfs_tree_unlock(child); free_extent_buffer(child); - goto enospc; + goto out; } ret = btrfs_tree_mod_log_insert_root(root->node, child, true); @@ -1058,7 +1058,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, btrfs_tree_unlock(child); free_extent_buffer(child); btrfs_abort_transaction(trans, ret); - goto enospc; + goto out; } rcu_assign_pointer(root->node, child); @@ -1087,7 +1087,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, if (IS_ERR(left)) { ret = PTR_ERR(left); left = NULL; - goto enospc; + goto out; } __btrfs_tree_lock(left, BTRFS_NESTING_LEFT); @@ -1096,7 +1096,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, BTRFS_NESTING_LEFT_COW); if (wret) { ret = wret; - goto enospc; + goto out; } } @@ -1105,7 +1105,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, if (IS_ERR(right)) { ret = PTR_ERR(right); right = NULL; - goto enospc; + goto out; } __btrfs_tree_lock(right, BTRFS_NESTING_RIGHT); @@ -1114,7 +1114,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, BTRFS_NESTING_RIGHT_COW); if (wret) { ret = wret; - goto enospc; + goto out; } } @@ -1149,7 +1149,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, BTRFS_MOD_LOG_KEY_REPLACE); if (ret < 0) { btrfs_abort_transaction(trans, ret); - goto enospc; + goto out; } btrfs_set_node_key(parent, &right_key, pslot + 1); btrfs_mark_buffer_dirty(parent); @@ -1168,12 +1168,12 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, if (!left) { ret = -EROFS; btrfs_handle_fs_error(fs_info, ret, NULL); - goto enospc; + goto out; } wret = balance_node_right(trans, mid, left); if (wret < 0) { ret = wret; - goto enospc; + goto out; } if (wret == 1) { wret = push_node_left(trans, left, mid, 1); @@ -1198,7 +1198,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, BTRFS_MOD_LOG_KEY_REPLACE); if (ret < 0) { btrfs_abort_transaction(trans, ret); - goto enospc; + goto out; } btrfs_set_node_key(parent, &mid_key, pslot); btrfs_mark_buffer_dirty(parent); @@ -1225,7 +1225,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, if (orig_ptr != btrfs_node_blockptr(path->nodes[level], path->slots[level])) BUG(); -enospc: +out: if (right) { btrfs_tree_unlock(right); free_extent_buffer(right); From patchwork Wed Jun 7 19:24:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13271169 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9FE65C77B7A for ; Wed, 7 Jun 2023 19:25:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229498AbjFGTZA (ORCPT ); Wed, 7 Jun 2023 15:25:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45552 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232568AbjFGTYs (ORCPT ); Wed, 7 Jun 2023 15:24:48 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 560FE1FDA for ; Wed, 7 Jun 2023 12:24:48 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 363C063C4E for ; Wed, 7 Jun 2023 19:24:48 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 216B4C433D2 for ; Wed, 7 Jun 2023 19:24:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1686165887; bh=3DidI0i/RwWQuUG2o1GFYdZnklwi7zqjo1MjYCu98mA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Yn7FP7+n2WVf/NxwyAu0JA9cpcnhj6DfkADKMw1BQi7zcKWImhYoLmEyOq878dYgN cN7u+8hOEPFvEUCHnMQ9EV0VGqBWzM34oHUV3E6fQiI0DQSlacoADED5WvMO98ITJ6 Gg0EwED7Mhp/ijooXjMRFnCTc8cMlFia6TXGucPAV1DC9l/FllVcsekPc80haXpSzC Lyk9CUHTCQmDNblu50D8hJRnwz393t3YG67CX3d+zP34RV2DxRw02+D/3Qk2Ox55QF 62waQPmjzSE1PVGmyWrKD0tfHL1d96m7SqVKfWul2/QMTO1JD+KVBNe9Ykk/uTLQxc CctiB3J+zDiOw== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH 07/13] btrfs: avoid unnecessarily setting the fs to RO and error state at balance_level() Date: Wed, 7 Jun 2023 20:24:31 +0100 Message-Id: X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Filipe Manana At balance_level(), when trying to promote a child node to a root node, if we fail to read the child we call btrfs_handle_fs_error(), which turns the fs to RO mode and sets it to error state as well, causing any ongoing transaction to abort. This however is not necessary because at that point we have not made any change yet at balance_level(), so any error reading the child node does not leaves us in any inconsistent state. Therefore we can just return the error to the caller. Signed-off-by: Filipe Manana --- fs/btrfs/ctree.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index e98f9e205e25..4dcdcf25c3fe 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -1040,7 +1040,6 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, child = btrfs_read_node_slot(mid, 0); if (IS_ERR(child)) { ret = PTR_ERR(child); - btrfs_handle_fs_error(fs_info, ret, NULL); goto out; } From patchwork Wed Jun 7 19:24:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13271171 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 31B82C7EE23 for ; Wed, 7 Jun 2023 19:25:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231408AbjFGTZD (ORCPT ); Wed, 7 Jun 2023 15:25:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45558 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232723AbjFGTYu (ORCPT ); Wed, 7 Jun 2023 15:24:50 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8EFC91FD5 for ; Wed, 7 Jun 2023 12:24:49 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 2C1B7639BC for ; Wed, 7 Jun 2023 19:24:49 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 159C9C433EF for ; Wed, 7 Jun 2023 19:24:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1686165888; bh=gLvOi2Ppog4OeBikgV9x82wsSwVkvqPznbAcObJfA+M=; h=From:To:Subject:Date:In-Reply-To:References:From; b=VbytxNccxxuqcaa2DTPnCoMaRunWOP2eAEu4MzTZMm3bpPbz2jTeyj6bYm54AjlxR 0SjE+BldGLSezVs+NC4RCkVVHIeh5T3A2xShfNkZV987kQ7VS/z1Uoo0WRRq8JaDMK 4DFhjZMVxDM1QvOhHicyN5QBbcLWA1Yk26zeqww6HBXs6WaPvvohDt6QguZ42xdg7+ N2WeF6JuyjgSU5GKx2peyaJgBN+PMI01NFoYID9XCwjLyayf3385WxnrnkX0GDz8bx UPuAT8wD0YHX9ERD77uTzwiv/WwGD2WCq+jFzgVRDhXheyoz2M/ZSCtfCp+Yem/aFH q5z/72wwWSWyg== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH 08/13] btrfs: abort transaction at balance_level() when left child is missing Date: Wed, 7 Jun 2023 20:24:32 +0100 Message-Id: <91e588216500d2aaa7e119e5ac4be927c71bf066.1686164817.git.fdmanana@suse.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Filipe Manana At balance_level() we are calling btrfs_handle_fs_error() when the middle child only has 1 item and the left child is missing, however we can simply use btrfs_abort_transaction(), which achieves the same purposes: to turn the fs to error state, abort the current transaction and turn the fs to RO mode. Besides that, btrfs_abort_transaction() also prints a stack trace which makes it more useful. Also, as this is an highly unexpected case and it's about a b+tree inconsistency, change the error code from -EROFS to -EUCLEAN and tag the if branch as 'unlikely'. Signed-off-by: Filipe Manana --- fs/btrfs/ctree.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 4dcdcf25c3fe..e2943047b01d 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -1164,9 +1164,9 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, * otherwise we would have pulled some pointers from the * right */ - if (!left) { - ret = -EROFS; - btrfs_handle_fs_error(fs_info, ret, NULL); + if (unlikely(!left)) { + ret = -EUCLEAN; + btrfs_abort_transaction(trans, ret); goto out; } wret = balance_node_right(trans, mid, left); From patchwork Wed Jun 7 19:24:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13271170 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B5FA2C7EE25 for ; Wed, 7 Jun 2023 19:25:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229904AbjFGTZB (ORCPT ); Wed, 7 Jun 2023 15:25:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45568 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233048AbjFGTYv (ORCPT ); Wed, 7 Jun 2023 15:24:51 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8E5871FDA for ; Wed, 7 Jun 2023 12:24:50 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 200EE63C4E for ; Wed, 7 Jun 2023 19:24:50 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0A4F1C4339B for ; Wed, 7 Jun 2023 19:24:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1686165889; bh=SUX0xi3Bxb13WgJ2qds2/g7ZP3SOdwfnTyUQd2pJtyM=; h=From:To:Subject:Date:In-Reply-To:References:From; b=JzJXz+2nJfZo7bs9RcjPK2MpT1pYzEAEj5UIHKGqYTaKACi6XdItw6wHQIZsXs/n8 K+1+NqMr3xOuRMMx2oof7G4uI0Gsij9/TxJuVEn1/tFJD1Sxc5tKAC+f0G9GAL+wu8 V11w0KBraf1W+pu63dgh40V7bJJneLRwtcfrvcm8lPFTvAOMtNwyFLPlgF4keR21ah vPpDlzcsV013MZ+ixIQTrz2oOxDnxKSJ3fqWRvNiaS8WPN3fc1XCFVQwgRpdYa/HP3 8lCAGJo6ljhqp60hVMig/UnWvTOe2z3oudB5eutJNKJHcsVLwhmGK3V+aOCoLhp3xa H2lfo/WoFNjhw== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH 09/13] btrfs: abort transaction at update_ref_for_cow() when ref count is zero Date: Wed, 7 Jun 2023 20:24:33 +0100 Message-Id: X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Filipe Manana At update_ref_for_cow() we are calling btrfs_handle_fs_error() if we find that the extent buffer has an unexpected ref count of zero, however we can simply use btrfs_abort_transaction(), which achieves the same purposes: to turn the fs to error state, abort the current transaction and turn the fs to RO mode as well. Besides that, btrfs_abort_transaction() also prints a stack trace which makes it more useful. Also, as this is a very unexpected situation, indicating a serious corruption/inconsistency, tag the if branch as 'unlikely' and set the error code to -EUCLEAN instead of -EROFS. Signed-off-by: Filipe Manana --- fs/btrfs/ctree.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index e2943047b01d..2971e7d70d04 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -421,9 +421,9 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, &refs, &flags); if (ret) return ret; - if (refs == 0) { - ret = -EROFS; - btrfs_handle_fs_error(fs_info, ret, NULL); + if (unlikely(refs == 0)) { + ret = -EUCLEAN; + btrfs_abort_transaction(trans, ret); return ret; } } else { From patchwork Wed Jun 7 19:24:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13271172 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 03AE0C7EE43 for ; Wed, 7 Jun 2023 19:25:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231420AbjFGTZD (ORCPT ); Wed, 7 Jun 2023 15:25:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45578 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233176AbjFGTYw (ORCPT ); Wed, 7 Jun 2023 15:24:52 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7BEED1FD5 for ; Wed, 7 Jun 2023 12:24:51 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 10C59639BC for ; Wed, 7 Jun 2023 19:24:51 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id F392AC433EF for ; Wed, 7 Jun 2023 19:24:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1686165890; bh=Vgcvw+1J0gJ4ISmqjEBgkY4hK3nil+z9oZA3FU5CMFE=; h=From:To:Subject:Date:In-Reply-To:References:From; b=OaB58xWdFiEbc8yhkUuTlTHwhKTDDpJKPuxB6pXYhX3lbRB7LfOseRFCbAiqqgOg8 C/j1QFVpYzqtR7GdZsIUSa3jSOSTCrmOixFia1XIF8rQI/b/GlVCNoo/Gw5C/4nhoV A34Oi7ct5R7+tgr/RWAr9GYiSU6rgsxhRimUP9kPXZYHra8WjvlzxWy7CBrjTxQDjc VRTNXk14iXP1pWABxtqhyxD7p9fsPQWqIK40nBCecqFyeJCkTMinRc/m7MsFSFWDhP D2LLhlhoBNydNNI3JkJP9DvW3V8WZE47N+ZrWRSitreNBDYVZlnIqUptmODal1a4W2 34TIW4ThDjSgA== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH 10/13] btrfs: do not BUG_ON() on tree mod log failures at push_nodes_for_insert() Date: Wed, 7 Jun 2023 20:24:34 +0100 Message-Id: <3dfd1a4c01795433444b45268da1ae75563642c1.1686164820.git.fdmanana@suse.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Filipe Manana At push_nodes_for_insert(), instead of doing a BUG_ON() in case we fail to record tree mod log operations, do a transaction abort and return the error to the caller. There's really no need for the BUG_ON() as we can release all resources in this context, and we have to abort because other future tree searches that use the tree mod log (btrfs_search_old_slot()) may get inconsistent results if other operations modify the tree after that failure and before the tree mod log based search. Signed-off-by: Filipe Manana Reviewed-by: Qu Wenruo --- fs/btrfs/ctree.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 2971e7d70d04..e3c949fa136f 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -1300,7 +1300,12 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, btrfs_node_key(mid, &disk_key, 0); ret = btrfs_tree_mod_log_insert_key(parent, pslot, BTRFS_MOD_LOG_KEY_REPLACE); - BUG_ON(ret < 0); + if (ret < 0) { + btrfs_tree_unlock(left); + free_extent_buffer(left); + btrfs_abort_transaction(trans, ret); + return ret; + } btrfs_set_node_key(parent, &disk_key, pslot); btrfs_mark_buffer_dirty(parent); if (btrfs_header_nritems(left) > orig_slot) { @@ -1355,7 +1360,12 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, btrfs_node_key(right, &disk_key, 0); ret = btrfs_tree_mod_log_insert_key(parent, pslot + 1, BTRFS_MOD_LOG_KEY_REPLACE); - BUG_ON(ret < 0); + if (ret < 0) { + btrfs_tree_unlock(right); + free_extent_buffer(right); + btrfs_abort_transaction(trans, ret); + return ret; + } btrfs_set_node_key(parent, &disk_key, pslot + 1); btrfs_mark_buffer_dirty(parent); From patchwork Wed Jun 7 19:24:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13271173 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EF0D1C7EE25 for ; Wed, 7 Jun 2023 19:25:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231494AbjFGTZE (ORCPT ); Wed, 7 Jun 2023 15:25:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45586 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233196AbjFGTYx (ORCPT ); Wed, 7 Jun 2023 15:24:53 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 753821FD5 for ; Wed, 7 Jun 2023 12:24:52 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 0A212636CF for ; Wed, 7 Jun 2023 19:24:52 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E8443C433D2 for ; Wed, 7 Jun 2023 19:24:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1686165891; bh=cLNnx81VDwC6n0N1/CBF5gYd5ZObE+tHvJouD2Vb2jY=; h=From:To:Subject:Date:In-Reply-To:References:From; b=ZKoCq6KqrOAxT3iFKCOWIPY9X9ht4u5i/ePB8saJkm3mxGMUC0FS3O5x92oy1B6BB bo+oPV2xP8gjZf9OfvgQqY4VmvhrGMKBJxPIYgOSHPTd+/ZjCt9z9GGjIi5COSsBGl ZSzdPYEQehjbJ+vL3v/oHJNhanjuIGDUECJCKCV2Dttf3F6JEQ5qQNEBuBPLCMvKz/ lVHseml4EzBhzXtcf7D0VkUGUuKHJtsNj4R760XjREyZbQQ7jKKHisyzt8OYTqq52m JziKqP4RZxCyByfgiKdbXyHYvSGWXpCmi3QgBDvkxn5toWgWI5EFuuHPDsQTbY7pX7 fGx3Q6WCn+ldw== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH 11/13] btrfs: do not BUG_ON() on tree mod log failure at insert_new_root() Date: Wed, 7 Jun 2023 20:24:35 +0100 Message-Id: <7d9be8388f0a32f5ae8bcaf73c215997e76253ed.1686164820.git.fdmanana@suse.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Filipe Manana 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 Reviewed-by: Qu Wenruo --- 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 */ From patchwork Wed Jun 7 19:24:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13271174 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 230A9C77B7A for ; Wed, 7 Jun 2023 19:25:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230113AbjFGTZF (ORCPT ); Wed, 7 Jun 2023 15:25:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45592 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233203AbjFGTYy (ORCPT ); Wed, 7 Jun 2023 15:24:54 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1F84D1FDA for ; Wed, 7 Jun 2023 12:24:53 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id F3CC7639BC for ; Wed, 7 Jun 2023 19:24:52 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id DCF55C433EF for ; Wed, 7 Jun 2023 19:24:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1686165892; bh=1vGMwudYE5TbOgY4R2qIJRhrh5xmYyOVn2lF2VdmbO4=; h=From:To:Subject:Date:In-Reply-To:References:From; b=U4WAgtEraxn1HYfER5lth5u0c/hVb5IbLSzuRh+vjyF5QGIzUYB43iHpbiPbnQjjL qUiTfeICTsDLx7cSN5VRh4k6+rG3BcZ2HWgmr0mfVDWF78XvKM3jeqMnFzVrmQ63Ov 4bUMo7JSqEUzzkuL6e6TVKv3EhueAXFKL+FE2RItVnyvlSRhNe1HaHlzqYMywAfTXQ 8jVXEX0bhDxg/E8+BXZfBANxEC/6hFAqNuCK7erN9a5NlzR9bNsmI2PEQL+LozXegF 66N8cjSqYTooS7IhCnLkvfyJC72HFTsAWdln60StH/du9UPLFhcxFVx9JKgnLRDL6l K5EcRGyptrmsQ== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH 12/13] btrfs: do not BUG_ON() on tree mod log failures at insert_ptr() Date: Wed, 7 Jun 2023 20:24:36 +0100 Message-Id: X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Filipe Manana At insert_ptr(), instead of doing a BUG_ON() in case we fail to record tree mod log operations, do a transaction abort and return the error to the callers. There's really no need for the BUG_ON() as we can release all resources in the context of all callers, and we have to abort because other future tree searches that use the tree mod log (btrfs_search_old_slot()) may get inconsistent results if other operations modify the tree after that failure and before the tree mod log based search. This implies making insert_ptr() return an int instead of void, and making all callers check for returned errors. Signed-off-by: Filipe Manana --- fs/btrfs/ctree.c | 68 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 19 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 6e59343034d6..f1fa89ae1184 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -2982,10 +2982,10 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans, * slot and level indicate where you want the key to go, and * blocknr is the block the key points to. */ -static void insert_ptr(struct btrfs_trans_handle *trans, - struct btrfs_path *path, - struct btrfs_disk_key *key, u64 bytenr, - int slot, int level) +static int insert_ptr(struct btrfs_trans_handle *trans, + struct btrfs_path *path, + struct btrfs_disk_key *key, u64 bytenr, + int slot, int level) { struct extent_buffer *lower; int nritems; @@ -3001,7 +3001,10 @@ static void insert_ptr(struct btrfs_trans_handle *trans, if (level) { ret = btrfs_tree_mod_log_insert_move(lower, slot + 1, slot, nritems - slot); - BUG_ON(ret < 0); + if (ret < 0) { + btrfs_abort_transaction(trans, ret); + return ret; + } } memmove_extent_buffer(lower, btrfs_node_key_ptr_offset(lower, slot + 1), @@ -3011,7 +3014,10 @@ static void insert_ptr(struct btrfs_trans_handle *trans, if (level) { ret = btrfs_tree_mod_log_insert_key(lower, slot, BTRFS_MOD_LOG_KEY_ADD); - BUG_ON(ret < 0); + if (ret < 0) { + btrfs_abort_transaction(trans, ret); + return ret; + } } btrfs_set_node_key(lower, key, slot); btrfs_set_node_blockptr(lower, slot, bytenr); @@ -3019,6 +3025,8 @@ static void insert_ptr(struct btrfs_trans_handle *trans, btrfs_set_node_ptr_generation(lower, slot, trans->transid); btrfs_set_header_nritems(lower, nritems + 1); btrfs_mark_buffer_dirty(lower); + + return 0; } /* @@ -3098,8 +3106,13 @@ static noinline int split_node(struct btrfs_trans_handle *trans, btrfs_mark_buffer_dirty(c); btrfs_mark_buffer_dirty(split); - insert_ptr(trans, path, &disk_key, split->start, - path->slots[level + 1] + 1, level + 1); + ret = insert_ptr(trans, path, &disk_key, split->start, + path->slots[level + 1] + 1, level + 1); + if (ret < 0) { + btrfs_tree_unlock(split); + free_extent_buffer(split); + return ret; + } if (path->slots[level] >= mid) { path->slots[level] -= mid; @@ -3576,16 +3589,17 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root * split the path's leaf in two, making sure there is at least data_size * available for the resulting leaf level of the path. */ -static noinline void copy_for_split(struct btrfs_trans_handle *trans, - struct btrfs_path *path, - struct extent_buffer *l, - struct extent_buffer *right, - int slot, int mid, int nritems) +static noinline int copy_for_split(struct btrfs_trans_handle *trans, + struct btrfs_path *path, + struct extent_buffer *l, + struct extent_buffer *right, + int slot, int mid, int nritems) { struct btrfs_fs_info *fs_info = trans->fs_info; int data_copy_size; int rt_data_off; int i; + int ret; struct btrfs_disk_key disk_key; struct btrfs_map_token token; @@ -3610,7 +3624,9 @@ static noinline void copy_for_split(struct btrfs_trans_handle *trans, btrfs_set_header_nritems(l, mid); btrfs_item_key(right, &disk_key, 0); - insert_ptr(trans, path, &disk_key, right->start, path->slots[1] + 1, 1); + ret = insert_ptr(trans, path, &disk_key, right->start, path->slots[1] + 1, 1); + if (ret < 0) + return ret; btrfs_mark_buffer_dirty(right); btrfs_mark_buffer_dirty(l); @@ -3628,6 +3644,8 @@ static noinline void copy_for_split(struct btrfs_trans_handle *trans, } BUG_ON(path->slots[0] < 0); + + return 0; } /* @@ -3826,8 +3844,13 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans, if (split == 0) { if (mid <= slot) { btrfs_set_header_nritems(right, 0); - insert_ptr(trans, path, &disk_key, - right->start, path->slots[1] + 1, 1); + ret = insert_ptr(trans, path, &disk_key, + right->start, path->slots[1] + 1, 1); + if (ret < 0) { + btrfs_tree_unlock(right); + free_extent_buffer(right); + return ret; + } btrfs_tree_unlock(path->nodes[0]); free_extent_buffer(path->nodes[0]); path->nodes[0] = right; @@ -3835,8 +3858,13 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans, path->slots[1] += 1; } else { btrfs_set_header_nritems(right, 0); - insert_ptr(trans, path, &disk_key, - right->start, path->slots[1], 1); + ret = insert_ptr(trans, path, &disk_key, + right->start, path->slots[1], 1); + if (ret < 0) { + btrfs_tree_unlock(right); + free_extent_buffer(right); + return ret; + } btrfs_tree_unlock(path->nodes[0]); free_extent_buffer(path->nodes[0]); path->nodes[0] = right; @@ -3852,7 +3880,9 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans, return ret; } - copy_for_split(trans, path, l, right, slot, mid, nritems); + ret = copy_for_split(trans, path, l, right, slot, mid, nritems); + if (ret < 0) + return ret; if (split == 2) { BUG_ON(num_doubles != 0); From patchwork Wed Jun 7 19:24:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 13271175 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 741CDC7EE23 for ; Wed, 7 Jun 2023 19:25:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231844AbjFGTZG (ORCPT ); Wed, 7 Jun 2023 15:25:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45598 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233205AbjFGTYz (ORCPT ); Wed, 7 Jun 2023 15:24:55 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 136671FD5 for ; Wed, 7 Jun 2023 12:24:54 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id E7B2D636CF for ; Wed, 7 Jun 2023 19:24:53 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D18DEC4339B for ; Wed, 7 Jun 2023 19:24:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1686165893; bh=rjUCCV1HaWN7sBC6U0UU4EZ6j/mOoXuFkg4EabJzqEs=; h=From:To:Subject:Date:In-Reply-To:References:From; b=XmEG3QFS+w2W5hxZO8y0nLhrXqJwevJ54McR7GLq51hvphmuNTJWv5qkRWOsPvh8e xA4ft9TniYE/ByM6hW5oZsEX6jnAwfUH9OysQQCKetM6F2JjiRLwPbpenUql7sHNOx 5gmfArdrOFRBhEdISAqPLvsIOA+ImrHS/Nn9wTWesCqIug0fw3OgBDz0wFkaPgw7L2 R4yxBfcdp/Pf9FM8/serh2d01yKrAIVnSAPs2DQWjFFXMp9TNdw1pUnwAT77Kc9EqI Xll+TgUIN6Ti4HyqJfchtTh/p6XRceFPJ99G3X1/vgzL01GKOGUurAmo6nQo/1zjJZ PeSHOBRMaNQjA== From: fdmanana@kernel.org To: linux-btrfs@vger.kernel.org Subject: [PATCH 13/13] btrfs: do not BUG_ON() on tree mod log failures at btrfs_del_ptr() Date: Wed, 7 Jun 2023 20:24:37 +0100 Message-Id: <7890b37a787a3dd59a6eadf0ae78092c46a7f9ca.1686164823.git.fdmanana@suse.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Filipe Manana At btrfs_del_ptr(), instead of doing a BUG_ON() in case we fail to record tree mod log operations, do a transaction abort and return the error to the callers. There's really no need for the BUG_ON() as we can release all resources in the context of all callers, and we have to abort because other future tree searches that use the tree mod log (btrfs_search_old_slot()) may get inconsistent results if other operations modify the tree after that failure and before the tree mod log based search. This implies btrfs_del_ptr() return an int instead of void, and making all callers check for returned errors. Signed-off-by: Filipe Manana Reviewed-by: Qu Wenruo --- fs/btrfs/ctree.c | 46 +++++++++++++++++++++++++++++++++------------- fs/btrfs/ctree.h | 4 ++-- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index f1fa89ae1184..7220c8736218 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -1135,7 +1135,9 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, if (btrfs_header_nritems(right) == 0) { btrfs_clear_buffer_dirty(trans, right); btrfs_tree_unlock(right); - btrfs_del_ptr(root, path, level + 1, pslot + 1); + ret = btrfs_del_ptr(trans, root, path, level + 1, pslot + 1); + if (ret < 0) + goto out; root_sub_used(root, right->len); btrfs_free_tree_block(trans, btrfs_root_id(root), right, 0, 1); @@ -1184,7 +1186,9 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, if (btrfs_header_nritems(mid) == 0) { btrfs_clear_buffer_dirty(trans, mid); btrfs_tree_unlock(mid); - btrfs_del_ptr(root, path, level + 1, pslot); + ret = btrfs_del_ptr(trans, root, path, level + 1, pslot); + if (ret < 0) + goto out; root_sub_used(root, mid->len); btrfs_free_tree_block(trans, btrfs_root_id(root), mid, 0, 1); free_extent_buffer_stale(mid); @@ -4429,8 +4433,8 @@ int btrfs_duplicate_item(struct btrfs_trans_handle *trans, * * This is exported for use inside btrfs-progs, don't un-export it. */ -void btrfs_del_ptr(struct btrfs_root *root, struct btrfs_path *path, int level, - int slot) +int btrfs_del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, + struct btrfs_path *path, int level, int slot) { struct extent_buffer *parent = path->nodes[level]; u32 nritems; @@ -4441,7 +4445,10 @@ void btrfs_del_ptr(struct btrfs_root *root, struct btrfs_path *path, int level, if (level) { ret = btrfs_tree_mod_log_insert_move(parent, slot, slot + 1, nritems - slot - 1); - BUG_ON(ret < 0); + if (ret < 0) { + btrfs_abort_transaction(trans, ret); + return ret; + } } memmove_extent_buffer(parent, btrfs_node_key_ptr_offset(parent, slot), @@ -4451,7 +4458,10 @@ void btrfs_del_ptr(struct btrfs_root *root, struct btrfs_path *path, int level, } else if (level) { ret = btrfs_tree_mod_log_insert_key(parent, slot, BTRFS_MOD_LOG_KEY_REMOVE); - BUG_ON(ret < 0); + if (ret < 0) { + btrfs_abort_transaction(trans, ret); + return ret; + } } nritems--; @@ -4467,6 +4477,7 @@ void btrfs_del_ptr(struct btrfs_root *root, struct btrfs_path *path, int level, fixup_low_keys(path, &disk_key, level + 1); } btrfs_mark_buffer_dirty(parent); + return 0; } /* @@ -4479,13 +4490,17 @@ void btrfs_del_ptr(struct btrfs_root *root, struct btrfs_path *path, int level, * The path must have already been setup for deleting the leaf, including * all the proper balancing. path->nodes[1] must be locked. */ -static noinline void btrfs_del_leaf(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, - struct extent_buffer *leaf) +static noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, + struct extent_buffer *leaf) { + int ret; + WARN_ON(btrfs_header_generation(leaf) != trans->transid); - btrfs_del_ptr(root, path, 1, path->slots[1]); + ret = btrfs_del_ptr(trans, root, path, 1, path->slots[1]); + if (ret < 0) + return ret; /* * btrfs_free_extent is expensive, we want to make sure we @@ -4498,6 +4513,7 @@ static noinline void btrfs_del_leaf(struct btrfs_trans_handle *trans, atomic_inc(&leaf->refs); btrfs_free_tree_block(trans, btrfs_root_id(root), leaf, 0, 1); free_extent_buffer_stale(leaf); + return 0; } /* * delete the item at the leaf level in path. If that empties @@ -4547,7 +4563,9 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, btrfs_set_header_level(leaf, 0); } else { btrfs_clear_buffer_dirty(trans, leaf); - btrfs_del_leaf(trans, root, path, leaf); + ret = btrfs_del_leaf(trans, root, path, leaf); + if (ret < 0) + return ret; } } else { int used = leaf_space_used(leaf, 0, nritems); @@ -4608,7 +4626,9 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, if (btrfs_header_nritems(leaf) == 0) { path->slots[1] = slot; - btrfs_del_leaf(trans, root, path, leaf); + ret = btrfs_del_leaf(trans, root, path, leaf); + if (ret < 0) + return ret; free_extent_buffer(leaf); ret = 0; } else { diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 5af61480dde6..f2d2b313bde5 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -541,8 +541,8 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, struct extent_buffer **cow_ret, u64 new_root_objectid); int btrfs_block_can_be_shared(struct btrfs_root *root, struct extent_buffer *buf); -void btrfs_del_ptr(struct btrfs_root *root, struct btrfs_path *path, int level, - int slot); +int btrfs_del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, + struct btrfs_path *path, int level, int slot); void btrfs_extend_item(struct btrfs_path *path, u32 data_size); void btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end); int btrfs_split_item(struct btrfs_trans_handle *trans,