]> pilppa.com Git - linux-2.6-omap-h63xx.git/commitdiff
Allow faulty devices to be removed from a readonly array.
authorNeilBrown <neilb@suse.de>
Tue, 5 Aug 2008 05:54:13 +0000 (15:54 +1000)
committerNeilBrown <neilb@suse.de>
Tue, 5 Aug 2008 05:56:32 +0000 (15:56 +1000)
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>
drivers/md/md.c

index 6eb95451f1616f925320b8d702eb4d3a5aca8ce1..25b893ec562eac27f339548ba767664f77dc8e44 100644 (file)
@@ -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);