Commit 9ac298cb authored by NeilBrown's avatar NeilBrown Committed by Luis Henriques

md: Always set RECOVERY_NEEDED when clearing RECOVERY_FROZEN

commit 45eaf45d upstream.

md_check_recovery will skip any recovery and also clear
MD_RECOVERY_NEEDED if MD_RECOVERY_FROZEN is set.
So when we clear _FROZEN, we must set _NEEDED and ensure that
md_check_recovery gets run.
Otherwise we could miss out on something that is needed.

In particular, this can make it impossible to remove a
failed device from an array is the  'recovery-needed' processing
didn't happen.
Suitable for stable kernels since 3.13.
Reported-and-tested-by: default avatarJoe Lawrence <joe.lawrence@stratus.com>
Fixes: 30b8feb7Signed-off-by: default avatarNeilBrown <neilb@suse.de>
Signed-off-by: default avatarLuis Henriques <luis.henriques@canonical.com>
parent cec4c7e4
...@@ -5313,6 +5313,7 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) ...@@ -5313,6 +5313,7 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
printk("md: %s still in use.\n",mdname(mddev)); printk("md: %s still in use.\n",mdname(mddev));
if (did_freeze) { if (did_freeze) {
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
md_wakeup_thread(mddev->thread); md_wakeup_thread(mddev->thread);
} }
err = -EBUSY; err = -EBUSY;
...@@ -5327,6 +5328,8 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) ...@@ -5327,6 +5328,8 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
mddev->ro = 1; mddev->ro = 1;
set_disk_ro(mddev->gendisk, 1); set_disk_ro(mddev->gendisk, 1);
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
md_wakeup_thread(mddev->thread);
sysfs_notify_dirent_safe(mddev->sysfs_state); sysfs_notify_dirent_safe(mddev->sysfs_state);
err = 0; err = 0;
} }
...@@ -5370,6 +5373,7 @@ static int do_md_stop(struct mddev * mddev, int mode, ...@@ -5370,6 +5373,7 @@ static int do_md_stop(struct mddev * mddev, int mode,
mutex_unlock(&mddev->open_mutex); mutex_unlock(&mddev->open_mutex);
if (did_freeze) { if (did_freeze) {
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
md_wakeup_thread(mddev->thread); md_wakeup_thread(mddev->thread);
} }
return -EBUSY; return -EBUSY;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment