]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
btrfs: abort transaction during log replay if walk_log_tree() failed
authorFilipe Manana <fdmanana@suse.com>
Wed, 21 May 2025 16:41:18 +0000 (17:41 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 20 Aug 2025 16:41:38 +0000 (18:41 +0200)
commit 2a5898c4aac67494c2f0f7fe38373c95c371c930 upstream.

If we failed walking a log tree during replay, we have a missing
transaction abort to prevent committing a transaction where we didn't
fully replay all the changes from a log tree and therefore can leave the
respective subvolume tree in some inconsistent state. So add the missing
transaction abort.

CC: stable@vger.kernel.org # 6.1+
Reviewed-by: Qu Wenruo <wqu@suse.com>
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: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/btrfs/tree-log.c

index cea8a7e9d6d3b1162611db557b72b67c06b6b4e6..a6694a6434041983ed0cf6b60531b403498390cf 100644 (file)
@@ -7279,11 +7279,14 @@ again:
 
                wc.replay_dest->log_root = log;
                ret = btrfs_record_root_in_trans(trans, wc.replay_dest);
-               if (ret)
+               if (ret) {
                        /* The loop needs to continue due to the root refs */
                        btrfs_abort_transaction(trans, ret);
-               else
+               } else {
                        ret = walk_log_tree(trans, log, &wc);
+                       if (ret)
+                               btrfs_abort_transaction(trans, ret);
+               }
 
                if (!ret && wc.stage == LOG_WALK_REPLAY_ALL) {
                        ret = fixup_inode_link_counts(trans, wc.replay_dest,