--- evms-2.5.5a/plugins/md/raid5_mgr.c 2006-02-22 10:05:17.000000000 -0600 +++ evms-2.5.5b/plugins/md/raid5_mgr.c 2006-05-05 12:48:46.492961984 -0500 @@ -102,6 +102,7 @@ md_super_info_t info; mdu_disk_info_t d; int i, count, length = 0; + int conf_disks; int rc = 0; LOG_ENTRY(); @@ -117,9 +118,27 @@ conf->failed_disk_index = -1; LOG_DEBUG("%s: info.raid_disks: %d, info.nr_disks: %d.\n", vol->name, info.raid_disks, info.nr_disks); - conf->stripe.nr_disks = (info.raid_disks > info.nr_disks) ? info.raid_disks : info.nr_disks; - conf->disks = EngFncs->engine_alloc(sizeof(disk_info_t) * conf->stripe.nr_disks); - conf->stripe.chunks = EngFncs->engine_alloc(sizeof(chunk_t) * conf->stripe.nr_disks); + conf_disks = (info.raid_disks > info.nr_disks) ? info.raid_disks : info.nr_disks; + + /* + * If a spare is added to fix a degrade array and recovery is running, + * its index could be greater than nr_disks. + * We should take this into account when allocating memory for disks. + * + * Check disk index of each member and adjust conf_disks if necessary. + */ + LIST_FOR_EACH(vol->members, iter, member) { + if (member->dev_number >= conf_disks) { + LOG_WARNING("%s: Changing number of disk entries:" + " current value %d, new value %d.\n", + vol->name, conf_disks, member->dev_number+1); + conf_disks = member->dev_number + 1; + } + } + + conf->disks = EngFncs->engine_alloc(sizeof(disk_info_t) * conf_disks); + conf->stripe.nr_disks = conf_disks; + conf->stripe.chunks = EngFncs->engine_alloc(sizeof(chunk_t) * conf_disks); /* Set the volume to which the stripe belongs. */ conf->stripe.volume = vol;