Skip to content

Commit b7ee30f

Browse files
Zheng QixingYuKuai-huawei
authored andcommitted
md: fix sync_action incorrect display during resync
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>
1 parent cb0780a commit b7ee30f

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
@@ -4848,9 +4848,33 @@ static bool rdev_needs_recovery(struct md_rdev *rdev, sector_t sectors)
48484848
rdev->recovery_offset < sectors;
48494849
}
48504850

4851+
static enum sync_action md_get_active_sync_action(struct mddev *mddev)
4852+
{
4853+
struct md_rdev *rdev;
4854+
bool is_recover = false;
4855+
4856+
if (mddev->resync_offset < MaxSector)
4857+
return ACTION_RESYNC;
4858+
4859+
if (mddev->reshape_position != MaxSector)
4860+
return ACTION_RESHAPE;
4861+
4862+
rcu_read_lock();
4863+
rdev_for_each_rcu(rdev, mddev) {
4864+
if (rdev_needs_recovery(rdev, MaxSector)) {
4865+
is_recover = true;
4866+
break;
4867+
}
4868+
}
4869+
rcu_read_unlock();
4870+
4871+
return is_recover ? ACTION_RECOVER : ACTION_IDLE;
4872+
}
4873+
48514874
enum sync_action md_sync_action(struct mddev *mddev)
48524875
{
48534876
unsigned long recovery = mddev->recovery;
4877+
enum sync_action active_action;
48544878

48554879
/*
48564880
* frozen has the highest priority, means running sync_thread will be
@@ -4874,8 +4898,17 @@ enum sync_action md_sync_action(struct mddev *mddev)
48744898
!test_bit(MD_RECOVERY_NEEDED, &recovery))
48754899
return ACTION_IDLE;
48764900

4877-
if (test_bit(MD_RECOVERY_RESHAPE, &recovery) ||
4878-
mddev->reshape_position != MaxSector)
4901+
/*
4902+
* Check if any sync operation (resync/recover/reshape) is
4903+
* currently active. This ensures that only one sync operation
4904+
* can run at a time. Returns the type of active operation, or
4905+
* ACTION_IDLE if none are active.
4906+
*/
4907+
active_action = md_get_active_sync_action(mddev);
4908+
if (active_action != ACTION_IDLE)
4909+
return active_action;
4910+
4911+
if (test_bit(MD_RECOVERY_RESHAPE, &recovery))
48794912
return ACTION_RESHAPE;
48804913

48814914
if (test_bit(MD_RECOVERY_RECOVER, &recovery))

0 commit comments

Comments
 (0)