From 3f83228aa83f00e83c15c1331d9e27c50c7a9fdc Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 8 Mar 2011 15:59:09 +1100 Subject: [PATCH] imsm: improve getinfo_super when reshape is in progress. If a reshape (migration) is happening, we might need to modify the information with provide to md so that it can cope with the reshape. For example, if a migration from 4-device RAID0 to 5-device RAID0 is happening, we need to tell md that it is reshape from degraded 5-device RAID4 to degraded 6-device RAID4 so md doesn't handle direct reshape of RAID0. There may be other migrations supported by IMSM that need special treatment here. Signed-off-by: NeilBrown --- super-intel.c | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/super-intel.c b/super-intel.c index 86e6bd4f..0091b271 100644 --- a/super-intel.c +++ b/super-intel.c @@ -1756,14 +1756,47 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info, info->custom_array_size = __le32_to_cpu(dev->size_high); info->custom_array_size <<= 32; info->custom_array_size |= __le32_to_cpu(dev->size_low); - if (prev_map) { + if (prev_map && map->map_state == prev_map->map_state) { + info->reshape_active = 1; info->new_level = get_imsm_raid_level(map); info->new_layout = imsm_level_to_layout(info->new_level); info->new_chunk = __le16_to_cpu(map->blocks_per_strip) << 9; + info->delta_disks = map->num_members - prev_map->num_members; + /* We shape information that we give to md might have to be + * modify to cope with md's requirement for reshaping arrays. + * For example, when reshaping a RAID0, md requires it to be + * presented as a degraded RAID4. + * Also if a RAID0 is migrating to a RAID5 we need to specify + * the array as already being RAID5, but the 'before' layout + * is a RAID4-like layout. + */ + switch (info->array.level) { + case 0: + switch(info->new_level) { + case 0: + /* conversion is happening as RAID4 */ + info->array.level = 4; + info->array.raid_disks += 1; + break; + case 5: + /* conversion is happening as RAID5 */ + info->array.level = 5; + info->array.layout = ALGORITHM_PARITY_N; + info->array.raid_disks += 1; + info->delta_disks -= 1; + break; + default: + /* FIXME error message */ + info->array.level = UnSet; + break; + } + break; + } } else { info->new_level = UnSet; info->new_layout = UnSet; info->new_chunk = info->array.chunk_size; + info->delta_disks = 0; } info->disk.major = 0; info->disk.minor = 0; @@ -1777,12 +1810,6 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info, __le32_to_cpu(map_to_analyse->blocks_per_member); memset(info->uuid, 0, sizeof(info->uuid)); info->recovery_start = MaxSector; - info->reshape_active = (prev_map != NULL) && - (map->map_state == prev_map->map_state); - if (info->reshape_active) - info->delta_disks = map->num_members - prev_map->num_members; - else - info->delta_disks = 0; info->reshape_progress = 0; if (map_to_analyse->map_state == IMSM_T_STATE_UNINITIALIZED || -- 2.39.2