Skip to content

Commit cefcb92

Browse files
mauelshahailan94
authored andcommitted
md raid: fix hang when stopping arrays with metadata through dm-raid
When using device-mapper's dm-raid target, stopping a RAID array can cause the system to hang under specific conditions. This occurs when: - A dm-raid managed device tree is suspended from top to bottom (the top-level RAID device is suspended first, followed by its underlying metadata and data devices) - The top-level RAID device is then removed Removing the top-level device triggers a hang in the following sequence: the dm-raid destructor calls md_stop(), which tries to flush the write-intent bitmap by writing to the metadata sub-devices. However, these devices are already suspended, making them unable to complete the write-intent operations and causing an indefinite block. Fix: - Prevent bitmap flushing when md_stop() is called from dm-raid destructor context and avoid a quiescing/unquescing cycle which could also cause I/O - Still allow write-intent bitmap flushing when called from dm-raid suspend context This ensures that RAID array teardown can complete successfully even when the underlying devices are in a suspended state. This second patch uses md_is_rdwr() to distinguish between suspend and destructor paths as elaborated on above. Link: https://lore.kernel.org/linux-raid/CAM23VxqYrwkhKEBeQrZeZwQudbiNey2_8B_SEOLqug=pXxaFrA@mail.gmail.com Signed-off-by: Heinz Mauelshagen <[email protected]> Signed-off-by: Yu Kuai <[email protected]>
1 parent f150e75 commit cefcb92

1 file changed

Lines changed: 8 additions & 6 deletions

File tree

drivers/md/md.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6851,13 +6851,15 @@ static void __md_stop_writes(struct mddev *mddev)
68516851
{
68526852
timer_delete_sync(&mddev->safemode_timer);
68536853

6854-
if (mddev->pers && mddev->pers->quiesce) {
6855-
mddev->pers->quiesce(mddev, 1);
6856-
mddev->pers->quiesce(mddev, 0);
6857-
}
6854+
if (md_is_rdwr(mddev) || !mddev_is_dm(mddev)) {
6855+
if (mddev->pers && mddev->pers->quiesce) {
6856+
mddev->pers->quiesce(mddev, 1);
6857+
mddev->pers->quiesce(mddev, 0);
6858+
}
68586859

6859-
if (md_bitmap_enabled(mddev, true))
6860-
mddev->bitmap_ops->flush(mddev);
6860+
if (md_bitmap_enabled(mddev, true))
6861+
mddev->bitmap_ops->flush(mddev);
6862+
}
68616863

68626864
if (md_is_rdwr(mddev) &&
68636865
((!mddev->in_sync && !mddev_is_clustered(mddev)) ||

0 commit comments

Comments
 (0)