mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-04-29 12:28:27 +02:00
btrfs: do not abort transaction on failure to write log tree when syncing log
commit 16199ad9eb upstream.
When syncing the log, if we fail to write log tree extent buffers, we mark
the log for a full commit and abort the transaction. However we don't need
to abort the transaction, all we really need to do is to make sure no one
can commit a superblock pointing to new log tree roots. Just because we
got a failure writing extent buffers for a log tree, it does not mean we
will also fail to do a transaction commit.
One particular case is if due to a bug somewhere, when writing log tree
extent buffers, the tree checker detects some corruption and the writeout
fails because of that. Aborting the transaction can be very disruptive for
a user, specially if the issue happened on a root filesystem. One example
is the scenario in the Link tag below, where an isolated corruption on log
tree leaves was causing transaction aborts when syncing the log.
Link: https://lore.kernel.org/linux-btrfs/ae169fc6-f504-28f0-a098-6fa6a4dfb612@leemhuis.info/
CC: stable@vger.kernel.org # 5.15+
Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
f653abe619
commit
f2e0e1615d
+8
-1
@@ -380,7 +380,14 @@ error:
|
||||
btrfs_print_tree(eb, 0);
|
||||
btrfs_err(fs_info, "block=%llu write time tree block corruption detected",
|
||||
eb->start);
|
||||
WARN_ON(IS_ENABLED(CONFIG_BTRFS_DEBUG));
|
||||
/*
|
||||
* Be noisy if this is an extent buffer from a log tree. We don't abort
|
||||
* a transaction in case there's a bad log tree extent buffer, we just
|
||||
* fallback to a transaction commit. Still we want to know when there is
|
||||
* a bad log tree extent buffer, as that may signal a bug somewhere.
|
||||
*/
|
||||
WARN_ON(IS_ENABLED(CONFIG_BTRFS_DEBUG) ||
|
||||
btrfs_header_owner(eb) == BTRFS_TREE_LOG_OBJECTID);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -3141,7 +3141,6 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
|
||||
ret = 0;
|
||||
if (ret) {
|
||||
blk_finish_plug(&plug);
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
btrfs_set_log_full_commit(trans);
|
||||
mutex_unlock(&root->log_mutex);
|
||||
goto out;
|
||||
@@ -3273,7 +3272,6 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
|
||||
goto out_wake_log_root;
|
||||
} else if (ret) {
|
||||
btrfs_set_log_full_commit(trans);
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
mutex_unlock(&log_root_tree->log_mutex);
|
||||
goto out_wake_log_root;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user