From 9535fc478c4ce977f83add0dfeab767751745c92 Mon Sep 17 00:00:00 2001 From: Adam Kwolek Date: Tue, 6 Dec 2011 11:17:26 +1100 Subject: [PATCH] imsm: FIX: Return longer map for failure setting When 2 maps are present, IMSM can use shorter map for setting disk in to degraded state. It can happen that degraded disk can be not present in shorter map. We should use longer map for setting disk in to degraded state. Signed-off-by: Adam Kwolek Signed-off-by: NeilBrown --- super-intel.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/super-intel.c b/super-intel.c index a0672bf3..2ee46e39 100644 --- a/super-intel.c +++ b/super-intel.c @@ -665,18 +665,34 @@ struct imsm_map *get_imsm_map(struct imsm_dev *dev, int second_map) * 0 - we return the first map * 1 - we return the second map if it exists, else NULL * -1 - we return the second map if it exists, else the first + * -2 - we return longer map /excluding uninitialized state/ */ struct imsm_map *map = &dev->vol.map[0]; + struct imsm_map *map2 = NULL; - if (second_map == 1 && !dev->vol.migr_state) - return NULL; - else if (second_map == 1 || - (second_map < 0 && dev->vol.migr_state)) { - void *ptr = map; + if (dev->vol.migr_state) + map2 = (void *)map + sizeof_imsm_map(map); - return ptr + sizeof_imsm_map(map); - } else - return map; + switch (second_map) { + case 0: + break; + case 1: + map = map2; + break; + case -1: + if (map2) + map = map2; + break; + case -2: + if (map2 + && map2->map_state != IMSM_T_STATE_UNINITIALIZED + && map2->num_members > map->num_members) + map = map2; + break; + default: + map = NULL; + } + return map; } @@ -6343,7 +6359,7 @@ static void imsm_set_disk(struct active_array *a, int n, int state) dprintf("imsm: set_disk %d:%x\n", n, state); - ord = get_imsm_ord_tbl_ent(dev, n, -1); + ord = get_imsm_ord_tbl_ent(dev, n, -2); disk = get_imsm_disk(super, ord_to_idx(ord)); /* check for new failures */ -- 2.47.2