]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
imsm: Allow multiple spares to be collected.
authorAdam Kwolek <adam.kwolek@intel.com>
Fri, 26 Nov 2010 07:08:01 +0000 (08:08 +0100)
committerNeilBrown <neilb@suse.de>
Tue, 30 Nov 2010 02:14:24 +0000 (13:14 +1100)
Assumption for spares searching was that after picking new device, it
has to be added to array before next search.  This causes returning
different disk on each call.

When creating a spare list during Online Capacity Expansion, we will
first collect the devices list and then all devices are added to md.
Picked device from spares pool has to be checked against picked
devices so far. If not, the same disk will be returned all the time.
Already picked devices are stored in the list and this list is used
for new devices verification also.

So add an extra arg to imsm_add_spare to hold a list of known
spares to ignore.

Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
super-intel.c

index eca6e3f7b2c8c952232b2e12cbb9556baa142693..29438988a2a11b72556b80764f490f119c9689f7 100644 (file)
@@ -4959,7 +4959,8 @@ static struct dl *imsm_readd(struct intel_super *super, int idx, struct active_a
 }
 
 static struct dl *imsm_add_spare(struct intel_super *super, int slot,
-                                struct active_array *a, int activate_new)
+                                struct active_array *a, int activate_new,
+                                struct mdinfo *additional_test_list)
 {
        struct imsm_dev *dev = get_imsm_dev(super, a->info.container_member);
        int idx = get_imsm_disk_idx(dev, slot);
@@ -4980,11 +4981,23 @@ static struct dl *imsm_add_spare(struct intel_super *super, int slot,
                        if (d->state_fd >= 0 &&
                            d->disk.major == dl->major &&
                            d->disk.minor == dl->minor) {
-                               dprintf("%x:%x already in array\n", dl->major, dl->minor);
+                               dprintf("%x:%x already in array\n",
+                                       dl->major, dl->minor);
                                break;
                        }
                if (d)
                        continue;
+               while (additional_test_list) {
+                       if (additional_test_list->disk.major == dl->major &&
+                           additional_test_list->disk.minor == dl->minor) {
+                               dprintf("%x:%x already in additional test list\n",
+                                       dl->major, dl->minor);
+                               break;
+                       }
+                       additional_test_list = additional_test_list->next;
+               }
+               if (additional_test_list)
+                       continue;
 
                /* skip in use or failed drives */
                if (is_failed(&dl->disk) || idx == dl->index ||
@@ -5114,9 +5127,9 @@ static struct mdinfo *imsm_activate_spare(struct active_array *a,
                 */
                dl = imsm_readd(super, i, a);
                if (!dl)
-                       dl = imsm_add_spare(super, i, a, 0);
+                       dl = imsm_add_spare(super, i, a, 0, NULL);
                if (!dl)
-                       dl = imsm_add_spare(super, i, a, 1);
+                       dl = imsm_add_spare(super, i, a, 1, NULL);
                if (!dl)
                        continue;