| From ca2a5edf6951d491cb9e419a485733ad5498040c Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 27 Sep 2023 12:09:22 +0100 |
| Subject: btrfs: error when COWing block from a root that is being deleted |
| |
| From: Filipe Manana <fdmanana@suse.com> |
| |
| [ Upstream commit a2caab29884397e583d09be6546259a83ebfbdb1 ] |
| |
| At btrfs_cow_block() we check if the block being COWed belongs to a root |
| that is being deleted and if so we log an error message. However this is |
| an unexpected case and it indicates a bug somewhere, so we should return |
| an error and abort the transaction. So change this in the following ways: |
| |
| 1) Abort the transaction with -EUCLEAN, so that if the issue ever happens |
| it can easily be noticed; |
| |
| 2) Change the logged message level from error to critical, and change the |
| message itself to print the block's logical address and the ID of the |
| root; |
| |
| 3) Return -EUCLEAN to the caller; |
| |
| 4) As this is an unexpected scenario, that should never happen, mark the |
| check as unlikely, allowing the compiler to potentially generate better |
| code. |
| |
| Signed-off-by: Filipe Manana <fdmanana@suse.com> |
| Reviewed-by: David Sterba <dsterba@suse.com> |
| Signed-off-by: David Sterba <dsterba@suse.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| fs/btrfs/ctree.c | 10 +++++++--- |
| 1 file changed, 7 insertions(+), 3 deletions(-) |
| |
| diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c |
| index 7afd0a6495f37..db1f3bc7f3284 100644 |
| --- a/fs/btrfs/ctree.c |
| +++ b/fs/btrfs/ctree.c |
| @@ -682,9 +682,13 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans, |
| u64 search_start; |
| int ret; |
| |
| - if (test_bit(BTRFS_ROOT_DELETING, &root->state)) |
| - btrfs_err(fs_info, |
| - "COW'ing blocks on a fs root that's being dropped"); |
| + if (unlikely(test_bit(BTRFS_ROOT_DELETING, &root->state))) { |
| + btrfs_abort_transaction(trans, -EUCLEAN); |
| + btrfs_crit(fs_info, |
| + "attempt to COW block %llu on root %llu that is being deleted", |
| + buf->start, btrfs_root_id(root)); |
| + return -EUCLEAN; |
| + } |
| |
| /* |
| * COWing must happen through a running transaction, which always |
| -- |
| 2.40.1 |
| |