summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2013-04-24 05:42:41 +0400
committerNeilBrown <neilb@suse.de>2013-04-24 05:42:41 +0400
commit3ea8929da3e61b54d4adcab1bf9a0034648d578e (patch)
tree5746cb05e180e46bb4a05d93ff55fbbdf0a0e078
parent746d3207ae2f9cf71fd87c9df884aa104fdaafa6 (diff)
downloadlinux-3ea8929da3e61b54d4adcab1bf9a0034648d578e.tar.xz
md: HOT_DISK_REMOVE shouldn't make a read-auto device active.
If a fail device or a spare is removed from an array, there is not need to make the array 'active'. If/when the array does become active for some other reason the metadata will be update to reflect the removal. If that never happens and the array is stopped while still read-auto, then there is no loss in forgetting the that the device had 'failed'. A read-only array will leave failed devices attached to the array personality, so we need to explicitly call remove_and_add_spares() to free it (clearing Blocked just like we do in store_slot()). Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--drivers/md/md.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 07f207e53ba9..802c2a379d8f 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -5883,6 +5883,9 @@ static int hot_remove_disk(struct mddev * mddev, dev_t dev)
if (!rdev)
return -ENXIO;
+ clear_bit(Blocked, &rdev->flags);
+ remove_and_add_spares(mddev, rdev);
+
if (rdev->raid_disk >= 0)
goto busy;
@@ -6496,6 +6499,10 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
err = md_set_readonly(mddev, bdev);
goto done_unlock;
+ case HOT_REMOVE_DISK:
+ err = hot_remove_disk(mddev, new_decode_dev(arg));
+ goto done_unlock;
+
case BLKROSET:
if (get_user(ro, (int __user *)(arg))) {
err = -EFAULT;
@@ -6566,10 +6573,6 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
goto done_unlock;
}
- case HOT_REMOVE_DISK:
- err = hot_remove_disk(mddev, new_decode_dev(arg));
- goto done_unlock;
-
case HOT_ADD_DISK:
err = hot_add_disk(mddev, new_decode_dev(arg));
goto done_unlock;