From: Filipe Manana fdmanana@suse.com
[ Upstream commit 28cb13f29faf6290597b24b728dc3100c019356f ]
Instead of doing a BUG_ON() handle the error by returning -EUCLEAN, aborting the transaction and logging an error message.
Reviewed-by: Qu Wenruo wqu@suse.com Signed-off-by: Filipe Manana fdmanana@suse.com Signed-off-by: David Sterba dsterba@suse.com [Minor conflict resolved due to code context change.] Signed-off-by: Jianqi Ren jianqi.ren.cn@windriver.com Signed-off-by: He Zhe zhe.he@windriver.com --- Verified the build test --- fs/btrfs/extent-tree.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index cf2b65be04b5..d652d4091b2b 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -174,6 +174,14 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); num_refs = btrfs_extent_refs(leaf, ei); + if (unlikely(num_refs == 0)) { + ret = -EUCLEAN; + btrfs_err(fs_info, + "unexpected zero reference count for extent item (%llu %u %llu)", + key.objectid, key.type, key.offset); + btrfs_abort_transaction(trans, ret); + goto out_free; + } extent_flags = btrfs_extent_flags(leaf, ei); } else { ret = -EINVAL; @@ -185,8 +193,6 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans,
goto out_free; } - - BUG_ON(num_refs == 0); } else { num_refs = 0; extent_flags = 0; @@ -216,10 +222,19 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, goto search_again; } spin_lock(&head->lock); - if (head->extent_op && head->extent_op->update_flags) + if (head->extent_op && head->extent_op->update_flags) { extent_flags |= head->extent_op->flags_to_set; - else - BUG_ON(num_refs == 0); + } else if (unlikely(num_refs == 0)) { + spin_unlock(&head->lock); + mutex_unlock(&head->mutex); + spin_unlock(&delayed_refs->lock); + ret = -EUCLEAN; + btrfs_err(fs_info, + "unexpected zero reference count for extent %llu (%s)", + bytenr, metadata ? "metadata" : "data"); + btrfs_abort_transaction(trans, ret); + goto out_free; + }
num_refs += head->ref_mod; spin_unlock(&head->lock);
[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected. No action required from the submitter.
The upstream commit SHA1 provided is correct: 28cb13f29faf6290597b24b728dc3100c019356f
WARNING: Author mismatch between patch and upstream commit: Backport author: jianqi.ren.cn@windriver.com Commit author: Filipe Mananafdmanana@suse.com
Status in newer kernel trees: 6.14.y | Present (exact SHA1) 6.12.y | Present (exact SHA1) 6.6.y | Not found 6.1.y | Not found 5.15.y | Not found
Note: The patch differs from the upstream commit: --- 1: 28cb13f29faf6 ! 1: 05ffdab55c95b btrfs: don't BUG_ON() when 0 reference count at btrfs_lookup_extent_info() @@ Metadata ## Commit message ## btrfs: don't BUG_ON() when 0 reference count at btrfs_lookup_extent_info()
+ [ Upstream commit 28cb13f29faf6290597b24b728dc3100c019356f ] + Instead of doing a BUG_ON() handle the error by returning -EUCLEAN, aborting the transaction and logging an error message.
Reviewed-by: Qu Wenruo wqu@suse.com Signed-off-by: Filipe Manana fdmanana@suse.com Signed-off-by: David Sterba dsterba@suse.com + [Minor conflict resolved due to code context change.] + Signed-off-by: Jianqi Ren jianqi.ren.cn@windriver.com + Signed-off-by: He Zhe zhe.he@windriver.com
## fs/btrfs/extent-tree.c ## @@ fs/btrfs/extent-tree.c: int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, + ei = btrfs_item_ptr(leaf, path->slots[0], + struct btrfs_extent_item); + num_refs = btrfs_extent_refs(leaf, ei); ++ if (unlikely(num_refs == 0)) { ++ ret = -EUCLEAN; ++ btrfs_err(fs_info, ++ "unexpected zero reference count for extent item (%llu %u %llu)", ++ key.objectid, key.type, key.offset); ++ btrfs_abort_transaction(trans, ret); ++ goto out_free; ++ } + extent_flags = btrfs_extent_flags(leaf, ei); + } else { + ret = -EINVAL; +@@ fs/btrfs/extent-tree.c: int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans,
- ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); - num_refs = btrfs_extent_refs(leaf, ei); -+ if (unlikely(num_refs == 0)) { -+ ret = -EUCLEAN; -+ btrfs_err(fs_info, -+ "unexpected zero reference count for extent item (%llu %u %llu)", -+ key.objectid, key.type, key.offset); -+ btrfs_abort_transaction(trans, ret); -+ goto out_free; -+ } - extent_flags = btrfs_extent_flags(leaf, ei); - owner = btrfs_get_extent_owner_root(fs_info, leaf, path->slots[0]); + goto out_free; + } +- - BUG_ON(num_refs == 0); } else { num_refs = 0; ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-5.10.y | Success | Success |
linux-stable-mirror@lists.linaro.org