From: fdmanana@kernel.org
To: linux-btrfs@vger.kernel.org
Subject: [PATCH v2 3/8] btrfs: error out when reallocating block for defrag using a stale transaction
Date: Wed, 27 Sep 2023 12:09:23 +0100 [thread overview]
Message-ID: <1bdbd3ce36b1b6c0e6eca75ac02b2cde581eb72c.1695812791.git.fdmanana@suse.com> (raw)
In-Reply-To: <cover.1695812791.git.fdmanana@suse.com>
From: Filipe Manana <fdmanana@suse.com>
At btrfs_realloc_node() we have these checks to verify we are not using a
stale transaction (a past transaction with an unblocked state or higher),
and the only thing we do is to trigger two WARN_ON(). This however is a
critical problem, highly unexpected and if it happens it's most likely due
to a bug, so we should error out and turn the fs into error state so that
such issue is much more easily noticed if it's triggered.
The problem is critical because in btrfs_realloc_node() we COW tree blocks,
and using such stale transaction will lead to not persisting the extent
buffers used for the COW operations, as allocating tree block adds the
range of the respective extent buffers to the ->dirty_pages iotree of the
transaction, and a stale transaction, in the unlocked state or higher,
will not flush dirty extent buffers anymore, therefore resulting in not
persisting the tree block and resource leaks (not cleaning the dirty_pages
iotree for example).
So do the following changes:
1) Return -EUCLEAN if we find a stale transaction;
2) Turn the fs into error state, with error -EUCLEAN, so that no
transaction can be committed, and generate a stack trace;
3) Combine both conditions into a single if statement, as both are related
and have the same error message;
4) Mark the check as unlikely, since this is not expected to ever happen.
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
fs/btrfs/ctree.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index e3382542f642..2a51cac7f21d 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -817,8 +817,22 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
int progress_passed = 0;
struct btrfs_disk_key disk_key;
- WARN_ON(trans->transaction != fs_info->running_transaction);
- WARN_ON(trans->transid != fs_info->generation);
+ /*
+ * COWing must happen through a running transaction, which always
+ * matches the current fs generation (it's a transaction with a state
+ * less than TRANS_STATE_UNBLOCKED). If it doesn't, then turn the fs
+ * into error state to prevent the commit of any transaction.
+ */
+ if (unlikely(trans->transaction != fs_info->running_transaction ||
+ trans->transid != fs_info->generation)) {
+ btrfs_abort_transaction(trans, -EUCLEAN);
+ btrfs_crit(fs_info,
+"unexpected transaction when attempting to reallocate parent %llu for root %llu, transaction %llu running transaction %llu fs generation %llu",
+ parent->start, btrfs_root_id(root), trans->transid,
+ fs_info->running_transaction->transid,
+ fs_info->generation);
+ return -EUCLEAN;
+ }
parent_nritems = btrfs_header_nritems(parent);
blocksize = fs_info->nodesize;
--
2.40.1
next prev parent reply other threads:[~2023-09-27 11:09 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-26 12:45 [PATCH 0/8] btrfs: some fixes and cleanups around btrfs_cow_block() fdmanana
2023-09-26 12:45 ` [PATCH 1/8] btrfs: error out when COWing block using a stale transaction fdmanana
2023-09-26 17:31 ` David Sterba
2023-09-26 17:57 ` Filipe Manana
2023-09-26 18:18 ` Filipe Manana
2023-09-26 12:45 ` [PATCH 2/8] btrfs: error when COWing block from a root that is being deleted fdmanana
2023-09-26 12:45 ` [PATCH 3/8] btrfs: error out when reallocating block for defrag using a stale transaction fdmanana
2023-09-26 17:41 ` David Sterba
2023-09-26 12:45 ` [PATCH 4/8] btrfs: remove noinline attribute from btrfs_cow_block() fdmanana
2023-09-26 12:45 ` [PATCH 5/8] btrfs: use round_down() to align block offset at btrfs_cow_block() fdmanana
2023-09-26 12:45 ` [PATCH 6/8] btrfs: rename and export __btrfs_cow_block() fdmanana
2023-09-26 12:45 ` [PATCH 7/8] btrfs: export comp_keys() from ctree.c as btrfs_comp_keys() fdmanana
2023-09-26 12:45 ` [PATCH 8/8] btrfs: move btrfs_realloc_node() from ctree.c into defrag.h fdmanana
2023-09-27 11:09 ` [PATCH v2 0/8] btrfs: some fixes and cleanups around btrfs_cow_block() fdmanana
2023-09-27 11:09 ` [PATCH v2 1/8] btrfs: error out when COWing block using a stale transaction fdmanana
2023-09-27 11:09 ` [PATCH v2 2/8] btrfs: error when COWing block from a root that is being deleted fdmanana
2023-09-27 11:09 ` fdmanana [this message]
2023-09-27 11:09 ` [PATCH v2 4/8] btrfs: remove noinline attribute from btrfs_cow_block() fdmanana
2023-09-27 11:09 ` [PATCH v2 5/8] btrfs: use round_down() to align block offset at btrfs_cow_block() fdmanana
2023-09-27 11:09 ` [PATCH v2 6/8] btrfs: rename and export __btrfs_cow_block() fdmanana
2023-09-27 11:09 ` [PATCH v2 7/8] btrfs: export comp_keys() from ctree.c as btrfs_comp_keys() fdmanana
2023-09-27 11:09 ` [PATCH v2 8/8] btrfs: move btrfs_realloc_node() from ctree.c into defrag.c fdmanana
2023-09-29 14:35 ` David Sterba
2023-09-29 14:33 ` [PATCH v2 0/8] btrfs: some fixes and cleanups around btrfs_cow_block() David Sterba
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1bdbd3ce36b1b6c0e6eca75ac02b2cde581eb72c.1695812791.git.fdmanana@suse.com \
--to=fdmanana@kernel.org \
--cc=linux-btrfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).