md: Fix some bugs in recovery_disabled handling.
authorNeilBrown <neilb@suse.de>
Wed, 26 Oct 2011 00:54:39 +0000 (11:54 +1100)
committerNeilBrown <neilb@suse.de>
Wed, 26 Oct 2011 00:54:39 +0000 (11:54 +1100)
In 3.0 we changed the way recovery_disabled was handle so that instead
of testing against zero, we test an mddev-> value against a conf->
value.
Two problems:
  1/ one place in raid1 was missed and still sets to '1'.
  2/ We didn't explicitly set the conf-> value at array creation
     time.
     It defaulted to '0' just like the mddev value does so they
     could appear equal and thus disable recovery.
     This did not affect normal 'md' as it calls bind_rdev_to_array
     which changes the mddev value.  However the dmraid interface
     doesn't call this and so doesn't change ->recovery_disabled; so at
     array start all recovery is incorrectly disabled.

So initialise the 'conf' value to one less that the mddev value, so
the will only be the same when explicitly set that way.

Reported-by: Jonathan Brassow <jbrassow@redhat.com>
Signed-off-by: NeilBrown <neilb@suse.de>
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5.c

index d8957d74fd252374e7289830e59699fe3d4484d2..4602fc57c961fd16edc5d558a050493a878fd50e 100644 (file)
@@ -1519,7 +1519,8 @@ static int fix_sync_read_error(struct r1bio *r1_bio)
                                        abort = 1;
                        }
                        if (abort) {
-                               mddev->recovery_disabled = 1;
+                               conf->recovery_disabled =
+                                       mddev->recovery_disabled;
                                set_bit(MD_RECOVERY_INTR, &mddev->recovery);
                                md_done_sync(mddev, r1_bio->sectors, 0);
                                put_buf(r1_bio);
@@ -2436,6 +2437,7 @@ static struct r1conf *setup_conf(struct mddev *mddev)
 
        bio_list_init(&conf->pending_bio_list);
        conf->pending_count = 0;
+       conf->recovery_disabled = mddev->recovery_disabled - 1;
 
        conf->last_used = -1;
        for (i = 0; i < conf->raid_disks; i++) {
index 9496463ca5dfb3521f1fce71653f4b593b410bdd..132c18ef86658ce29bafdaa82773eacf52534bc5 100644 (file)
@@ -1373,6 +1373,7 @@ static int raid10_add_disk(struct mddev *mddev, struct md_rdev *rdev)
                }
 
                p->head_position = 0;
+               p->recovery_disabled = mddev->recovery_disabled - 1;
                rdev->raid_disk = mirror;
                err = 0;
                if (rdev->saved_raid_disk != mirror)
@@ -2931,6 +2932,7 @@ static int run(struct mddev *mddev)
                        if (disk->rdev)
                                conf->fullsync = 1;
                }
+               disk->recovery_disabled = mddev->recovery_disabled - 1;
        }
 
        if (mddev->recovery_cp != MaxSector)
index 521bf2605f82e332aab6a5daac1206300f0a3d3f..f6fe053a5bed305c7de1744a6ace0af15e1e78ae 100644 (file)
@@ -4591,6 +4591,7 @@ static struct r5conf *setup_conf(struct mddev *mddev)
        atomic_set(&conf->preread_active_stripes, 0);
        atomic_set(&conf->active_aligned_reads, 0);
        conf->bypass_threshold = BYPASS_THRESHOLD;
+       conf->recovery_disabled = mddev->recovery_disabled - 1;
 
        conf->raid_disks = mddev->raid_disks;
        if (mddev->reshape_position == MaxSector)