aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2014-10-28 17:49:50 -0400
committerNeilBrown <neilb@suse.de>2014-11-16 17:17:46 -0500
commit45eaf45dfa4850df16bc2e8e7903d89021137f40 (patch)
tree623ac0e21c0f21c851c4dcffe8b317d41aafdb98
parent206c5f60a3d902bc4b56dab2de3e88de5eb06108 (diff)
md: Always set RECOVERY_NEEDED when clearing RECOVERY_FROZEN
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. Cc: stable@vger.kernel.org (3.13+) Reported-and-tested-by: Joe Lawrence <joe.lawrence@stratus.com> Fixes: 30b8feb730f9b9b3c5de02580897da03f59b6b16 Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--drivers/md/md.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 4dfa15da9cb8..9233c71138f1 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -5121,6 +5121,7 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
5121 printk("md: %s still in use.\n",mdname(mddev)); 5121 printk("md: %s still in use.\n",mdname(mddev));
5122 if (did_freeze) { 5122 if (did_freeze) {
5123 clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); 5123 clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
5124 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
5124 md_wakeup_thread(mddev->thread); 5125 md_wakeup_thread(mddev->thread);
5125 } 5126 }
5126 err = -EBUSY; 5127 err = -EBUSY;
@@ -5135,6 +5136,8 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
5135 mddev->ro = 1; 5136 mddev->ro = 1;
5136 set_disk_ro(mddev->gendisk, 1); 5137 set_disk_ro(mddev->gendisk, 1);
5137 clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); 5138 clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
5139 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
5140 md_wakeup_thread(mddev->thread);
5138 sysfs_notify_dirent_safe(mddev->sysfs_state); 5141 sysfs_notify_dirent_safe(mddev->sysfs_state);
5139 err = 0; 5142 err = 0;
5140 } 5143 }
@@ -5178,6 +5181,7 @@ static int do_md_stop(struct mddev *mddev, int mode,
5178 mutex_unlock(&mddev->open_mutex); 5181 mutex_unlock(&mddev->open_mutex);
5179 if (did_freeze) { 5182 if (did_freeze) {
5180 clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); 5183 clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
5184 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
5181 md_wakeup_thread(mddev->thread); 5185 md_wakeup_thread(mddev->thread);
5182 } 5186 }
5183 return -EBUSY; 5187 return -EBUSY;