]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Assemble: fix --force assembly of v1.x arrays which are recovering.
authorNeilBrown <neilb@suse.de>
Thu, 4 Feb 2010 01:02:09 +0000 (12:02 +1100)
committerNeilBrown <neilb@suse.de>
Thu, 4 Feb 2010 01:02:09 +0000 (12:02 +1100)
1.x metadata allows a device to be a member of the array while it
is still recoverying.  So it is a working member, but is not
completely in-sync.

mdadm/assemble does not understand this distinction and assumes that a
work member is fully in-sync for the purpose of determining if there
are enough in-sync devices for the array to be functional.

So collect the 'recovery_start' value from the metadata and use it in
assemble when determining how useful a given device is.

Reported-by: Mikael Abrahamsson <swmike@swm.pp.se>
Signed-off-by: NeilBrown <neilb@suse.de>
Assemble.c
super-ddf.c
super-intel.c
super0.c
super1.c

index 7f900489bb19483bacf9fa15bb8cc97d5b0c083f..e4d61816369c2c0a0174e5c3da6eeda364d13925 100644 (file)
@@ -800,7 +800,8 @@ int Assemble(struct supertype *st, char *mddev,
                if (devices[j].i.events+event_margin >=
                    devices[most_recent].i.events) {
                        devices[j].uptodate = 1;
-                       if (i < content->array.raid_disks) {
+                       if (i < content->array.raid_disks &&
+                           devices[j].i.recovery_start == MaxSector) {
                                okcnt++;
                                avail[i]=1;
                        } else
@@ -822,6 +823,7 @@ int Assemble(struct supertype *st, char *mddev,
                        int j = best[i];
                        if (j>=0 &&
                            !devices[j].uptodate &&
+                           devices[j].i.recovery_start == MaxSector &&
                            (chosen_drive < 0 ||
                             devices[j].i.events
                             > devices[chosen_drive].i.events))
index 3e30229536845ae2dd469af0157fa9b36403cf74..870efd8296063633253214c82974d83af09829c8 100644 (file)
@@ -1369,6 +1369,7 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info)
        info->disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE);
 
 
+       info->recovery_start = MaxSector;
        info->reshape_active = 0;
        info->name[0] = 0;
 
@@ -1427,6 +1428,7 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info)
 
        info->container_member = ddf->currentconf->vcnum;
 
+       info->recovery_start = MaxSector;
        info->resync_start = 0;
        if (!(ddf->virt->entries[info->container_member].state
              & DDF_state_inconsistent)  &&
index 91479a23b0ecf21c33da8d90c1715467f5ce9c8d..bbdcb511a43e0ecab7ad0987fd64d9585ad14656 100644 (file)
@@ -1452,6 +1452,7 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info)
        info->data_offset         = __le32_to_cpu(map->pba_of_lba0);
        info->component_size      = __le32_to_cpu(map->blocks_per_member);
        memset(info->uuid, 0, sizeof(info->uuid));
+       info->recovery_start = MaxSector;
 
        if (map->map_state == IMSM_T_STATE_UNINITIALIZED || dev->vol.dirty) {
                info->resync_start = 0;
@@ -1559,6 +1560,7 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info)
        info->disk.number = -1;
        info->disk.state = 0;
        info->name[0] = 0;
+       info->recovery_start = MaxSector;
 
        if (super->disks) {
                __u32 reserved = imsm_reserved_sectors(super, super->disks);
index 0485a3a103df69ecc90f5479de0c37fdf1441ee6..5c6b7d71984e831ba0b9640e04b0f6093aa85022 100644 (file)
--- a/super0.c
+++ b/super0.c
@@ -372,6 +372,7 @@ static void getinfo_super0(struct supertype *st, struct mdinfo *info)
 
        uuid_from_super0(st, info->uuid);
 
+       info->recovery_start = MaxSector;
        if (sb->minor_version > 90 && (sb->reshape_position+1) != 0) {
                info->reshape_active = 1;
                info->reshape_progress = sb->reshape_position;
index 85bb598ad811d1a248354ca84e56cb682e19b406..40fbb81accb30a904f1f5fd20a5fb7306e720270 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -612,6 +612,11 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info)
        strncpy(info->name, sb->set_name, 32);
        info->name[32] = 0;
 
+       if (sb->feature_map & __le32_to_cpu(MD_FEATURE_RECOVERY_OFFSET))
+               info->recovery_start = __le32_to_cpu(sb->recovery_offset);
+       else
+               info->recovery_start = MaxSector;
+
        if (sb->feature_map & __le32_to_cpu(MD_FEATURE_RESHAPE_ACTIVE)) {
                info->reshape_active = 1;
                info->reshape_progress = __le64_to_cpu(sb->reshape_position);