diff options
author | NeilBrown <neilb@suse.de> | 2008-08-05 07:54:13 +0200 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2008-08-05 07:56:32 +0200 |
commit | c89a8eee61540df04fc83f32f51ef0f46ec018b1 (patch) | |
tree | 7bffba40357f654de8ed31bc6a0e7468daa61234 /drivers/md/md.c | |
parent | Don't let a blocked_rdev interfere with read request in raid5/6 (diff) | |
download | linux-c89a8eee61540df04fc83f32f51ef0f46ec018b1.tar.xz linux-c89a8eee61540df04fc83f32f51ef0f46ec018b1.zip |
Allow faulty devices to be removed from a readonly array.
Removing faulty devices from an array is a two stage process.
First the device is moved from being a part of the active array
to being similar to a spare device. Then it can be removed
by a request from user space.
The first step is currently not performed for read-only arrays,
so the second step can never succeed.
So allow readonly arrays to remove failed devices (which aren't
blocked).
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r-- | drivers/md/md.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 6eb95451f161..25b893ec562e 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -6003,7 +6003,7 @@ static int remove_and_add_spares(mddev_t *mddev) } } - if (mddev->degraded) { + if (mddev->degraded && ! mddev->ro) { rdev_for_each(rdev, rtmp, mddev) { if (rdev->raid_disk >= 0 && !test_bit(In_sync, &rdev->flags) && @@ -6077,6 +6077,8 @@ void md_check_recovery(mddev_t *mddev) flush_signals(current); } + if (mddev->ro && !test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) + return; if ( ! ( (mddev->flags && !mddev->external) || test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || @@ -6090,6 +6092,15 @@ void md_check_recovery(mddev_t *mddev) if (mddev_trylock(mddev)) { int spares = 0; + if (mddev->ro) { + /* Only thing we do on a ro array is remove + * failed devices. + */ + remove_and_add_spares(mddev); + clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery); + goto unlock; + } + if (!mddev->external) { int did_change = 0; spin_lock_irq(&mddev->write_lock); |