imsm: Allow multiple spares to be collected.

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>
This commit is contained in:
Adam Kwolek 2010-11-26 08:08:01 +01:00 committed by NeilBrown
parent 36988a3dda
commit 8ba77d3281
1 changed files with 17 additions and 4 deletions

View 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;