Skip to content

Commit 21b38f3

Browse files
Zheng Qixinggregkh
authored andcommitted
md: fix sync_action incorrect display during resync
[ Upstream commit b7ee30f ] During raid resync, if a disk becomes faulty, the operation is briefly interrupted. The MD_RECOVERY_RECOVER flag triggered by the disk failure causes sync_action to incorrectly show "recover" instead of "resync". The same issue affects reshape operations. Reproduction steps: mdadm -Cv /dev/md1 -l1 -n4 -e1.2 /dev/sd{a..d} // -> resync happened mdadm -f /dev/md1 /dev/sda // -> resync interrupted cat sync_action -> recover Add progress checks in md_sync_action() for resync/recover/reshape to ensure the interface correctly reports the actual operation type. Fixes: 4b10a3b ("md: ensure resync is prioritized over recovery") Signed-off-by: Zheng Qixing <zhengqixing@huawei.com> Link: https://lore.kernel.org/linux-raid/20250816002534.1754356-3-zhengqixing@huaweicloud.com Signed-off-by: Yu Kuai <yukuai3@huawei.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 62f06ac commit 21b38f3

File tree

1 file changed

+35
-2
lines changed

1 file changed

+35
-2
lines changed

drivers/md/md.c

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4831,9 +4831,33 @@ static bool rdev_needs_recovery(struct md_rdev *rdev, sector_t sectors)
48314831
rdev->recovery_offset < sectors;
48324832
}
48334833

4834+
static enum sync_action md_get_active_sync_action(struct mddev *mddev)
4835+
{
4836+
struct md_rdev *rdev;
4837+
bool is_recover = false;
4838+
4839+
if (mddev->resync_offset < MaxSector)
4840+
return ACTION_RESYNC;
4841+
4842+
if (mddev->reshape_position != MaxSector)
4843+
return ACTION_RESHAPE;
4844+
4845+
rcu_read_lock();
4846+
rdev_for_each_rcu(rdev, mddev) {
4847+
if (rdev_needs_recovery(rdev, MaxSector)) {
4848+
is_recover = true;
4849+
break;
4850+
}
4851+
}
4852+
rcu_read_unlock();
4853+
4854+
return is_recover ? ACTION_RECOVER : ACTION_IDLE;
4855+
}
4856+
48344857
enum sync_action md_sync_action(struct mddev *mddev)
48354858
{
48364859
unsigned long recovery = mddev->recovery;
4860+
enum sync_action active_action;
48374861

48384862
/*
48394863
* frozen has the highest priority, means running sync_thread will be
@@ -4857,8 +4881,17 @@ enum sync_action md_sync_action(struct mddev *mddev)
48574881
!test_bit(MD_RECOVERY_NEEDED, &recovery))
48584882
return ACTION_IDLE;
48594883

4860-
if (test_bit(MD_RECOVERY_RESHAPE, &recovery) ||
4861-
mddev->reshape_position != MaxSector)
4884+
/*
4885+
* Check if any sync operation (resync/recover/reshape) is
4886+
* currently active. This ensures that only one sync operation
4887+
* can run at a time. Returns the type of active operation, or
4888+
* ACTION_IDLE if none are active.
4889+
*/
4890+
active_action = md_get_active_sync_action(mddev);
4891+
if (active_action != ACTION_IDLE)
4892+
return active_action;
4893+
4894+
if (test_bit(MD_RECOVERY_RESHAPE, &recovery))
48624895
return ACTION_RESHAPE;
48634896

48644897
if (test_bit(MD_RECOVERY_RECOVER, &recovery))

0 commit comments

Comments
 (0)