imsm: FIX: Correct ords merging in end_migration()
Ord's merging should occur when rebuild finishes and final state is other than expected only /additional failures occur during rebuild/. Exclude array initialization. Merging ords on migration finish should never happen. Any failure during migration should be immediately placed in first /current/ map, so no merge is necessary. Signed-off-by: Adam Kwolek <adam.kwolek@intel.com> Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
04ed49b3cf
commit
809da78e60
|
@ -3128,7 +3128,8 @@ static void migrate(struct imsm_dev *dev, struct intel_super *super,
|
|||
src->map_state = to_state;
|
||||
}
|
||||
|
||||
static void end_migration(struct imsm_dev *dev, __u8 map_state)
|
||||
static void end_migration(struct imsm_dev *dev, struct intel_super *super,
|
||||
__u8 map_state)
|
||||
{
|
||||
struct imsm_map *map = get_imsm_map(dev, 0);
|
||||
struct imsm_map *prev = get_imsm_map(dev, dev->vol.migr_state);
|
||||
|
@ -3139,16 +3140,28 @@ static void end_migration(struct imsm_dev *dev, __u8 map_state)
|
|||
*
|
||||
* FIXME add support for raid-level-migration
|
||||
*/
|
||||
for (i = 0; i < prev->num_members; i++)
|
||||
for (j = 0; j < map->num_members; j++)
|
||||
/* during online capacity expansion
|
||||
* disks position can be changed if takeover is used
|
||||
*/
|
||||
if (ord_to_idx(map->disk_ord_tbl[j]) ==
|
||||
ord_to_idx(prev->disk_ord_tbl[i])) {
|
||||
map->disk_ord_tbl[j] |= prev->disk_ord_tbl[i];
|
||||
break;
|
||||
}
|
||||
if ((map_state != map->map_state) && (is_gen_migration(dev) == 0) &&
|
||||
(prev->map_state != IMSM_T_STATE_UNINITIALIZED)) {
|
||||
/* when final map state is other than expected
|
||||
* merge maps (not for migration)
|
||||
*/
|
||||
int failed;
|
||||
|
||||
for (i = 0; i < prev->num_members; i++)
|
||||
for (j = 0; j < map->num_members; j++)
|
||||
/* during online capacity expansion
|
||||
* disks position can be changed
|
||||
* if takeover is used
|
||||
*/
|
||||
if (ord_to_idx(map->disk_ord_tbl[j]) ==
|
||||
ord_to_idx(prev->disk_ord_tbl[i])) {
|
||||
map->disk_ord_tbl[j] |=
|
||||
prev->disk_ord_tbl[i];
|
||||
break;
|
||||
}
|
||||
failed = imsm_count_failed(super, dev, MAP_0);
|
||||
map_state = imsm_check_degraded(super, dev, failed, MAP_0);
|
||||
}
|
||||
|
||||
dev->vol.migr_state = 0;
|
||||
set_migr_type(dev, 0);
|
||||
|
@ -6335,7 +6348,7 @@ static int imsm_set_array_state(struct active_array *a, int consistent)
|
|||
*/
|
||||
if (is_resyncing(dev)) {
|
||||
dprintf("imsm: mark resync done\n");
|
||||
end_migration(dev, map_state);
|
||||
end_migration(dev, super, map_state);
|
||||
super->updates_pending++;
|
||||
a->last_checkpoint = 0;
|
||||
}
|
||||
|
@ -6434,7 +6447,7 @@ static void imsm_set_disk(struct active_array *a, int n, int state)
|
|||
|
||||
/* check if recovery complete, newly degraded, or failed */
|
||||
if (map_state == IMSM_T_STATE_NORMAL && is_rebuilding(dev)) {
|
||||
end_migration(dev, map_state);
|
||||
end_migration(dev, super, map_state);
|
||||
map = get_imsm_map(dev, 0);
|
||||
map->failed_disk_num = ~0;
|
||||
super->updates_pending++;
|
||||
|
@ -6449,7 +6462,7 @@ static void imsm_set_disk(struct active_array *a, int n, int state)
|
|||
} else if (map_state == IMSM_T_STATE_FAILED &&
|
||||
map->map_state != map_state) {
|
||||
dprintf("imsm: mark failed\n");
|
||||
end_migration(dev, map_state);
|
||||
end_migration(dev, super, map_state);
|
||||
super->updates_pending++;
|
||||
a->last_checkpoint = 0;
|
||||
} else if (is_gen_migration(dev)) {
|
||||
|
@ -6459,14 +6472,14 @@ static void imsm_set_disk(struct active_array *a, int n, int state)
|
|||
case IMSM_T_STATE_NORMAL:
|
||||
dprintf("normal\n");
|
||||
if (a->last_checkpoint >= a->info.component_size)
|
||||
end_migration(dev, map_state);
|
||||
end_migration(dev, super, map_state);
|
||||
map = get_imsm_map(dev, 0);
|
||||
map->failed_disk_num = ~0;
|
||||
break;
|
||||
case IMSM_T_STATE_DEGRADED:
|
||||
dprintf("degraded\n");
|
||||
if (a->last_checkpoint >= a->info.component_size)
|
||||
end_migration(dev, map_state);
|
||||
end_migration(dev, super, map_state);
|
||||
else
|
||||
manage_second_map(super, dev);
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue