blob: 7ed3498182c2dcd8e2394b5a2a819572368d730f [file]
From a9b385c5689b7b0cdb14b6b7a63aa99aa38fe28e Mon Sep 17 00:00:00 2001
From: Sasha Levin <sashal@kernel.org>
Date: Tue, 22 Sep 2026 11:41:52 -0400
Subject: btrfs: take commit root semaphore when iterating in
mark_block_group_to_copy()
From: Hongling Zeng <zenghongling@kylinos.cn>
[ Upstream commit 0594e3423f4ba3137c734371169491f9a98e9af4 ]
mark_block_group_to_copy() iterates over the commit root with
skip_locking=true. A concurrent transaction commit can swap and free
the commit root during iteration, causing use-after-free when
accessing extent buffers.
Fix it by using path->need_commit_sem to protect the commit root search.
Fixes: 78ce9fc269af ("btrfs: zoned: mark block groups to copy for device-replace")
CC: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.5
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
[ changed path->need_commit_sem assignment from true to 1 to match the older unsigned bitfield representation. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/dev-replace.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index aa03f2bbcc11c..d19260ccb1c34 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -516,6 +516,7 @@ static int mark_block_group_to_copy(struct btrfs_fs_info *fs_info,
path->reada = READA_FORWARD;
path->search_commit_root = 1;
path->skip_locking = 1;
+ path->need_commit_sem = 1;
key.objectid = src_dev->devid;
key.type = BTRFS_DEV_EXTENT_KEY;
--
2.53.0