From: Blazej Kucman Date: Mon, 31 Mar 2025 10:46:52 +0000 (+0200) Subject: imsm: Fix RAID0 to RAID10 migration X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=127e38b59cbdf717d1569bcdc75b8d823d8485f3;p=thirdparty%2Fmdadm.git imsm: Fix RAID0 to RAID10 migration Support for RAID10 with +4 disks in IMSM introduced an inconsistency between the VROC UEFI driver and Linux IMSM. VROC UEFI does not support RAID10 with +4 disks, therefore appropriate protections were added to the mdadm IMSM code that results in skipping processing of such RAID in the UEFI phase. Unfortunately the case of migration RAID0 2 disks to RAID10 4 disks was omitted, this case requires maintaining compatibility with the VROC UEFI driver because it is supported. For RAID10 +4 disk the MPB_ATTRIB_RAID10_EXT attribute is set in the metadata, thanks to which the UEFI driver does not process such RAID. In the series adding support, a new metadata raid level value IMSM_T_RAID10 was also introduced. It is not recognized by VROC UEFI. The issue is caused by the fact that in the case of the mentioned migration, IMSM_T_RAID10 is entered into the metadata but attribute MPB_ATTRIB_RAID10_EXT is not entered, which causes an attempt to process such RAID in the UEFI phase. This situation results in the platform hang during booting in UEFI phase, this also results in data loss after failed and interrupted RAID processing in VROC UEFI. The above situation is result of the update_imsm_raid_level() function, for the mentioned migration function is executed on a map with a not yet updated number of disks. The fix is to explicitly handle migration in the function mentioned above to maintain compatibility with VROC UEFI driver. Steps to reproduce: mdadm -C /dev/md/imsm0 -e imsm -n 2 /dev/nvme[1,2]n1 -R mdadm -C /dev/md/vol -l 0 -n 2 /dev/nvme[1,2]n1 --assume-clean -R mdadm -a /dev/md127 /dev/nvme3n1 mdadm -a /dev/md127 /dev/nvme4n1 mdadm -G /dev/md126 -l 10 reboot Fixes: 27550b13297a ("imsm: add support for literal RAID 10") Signed-off-by: Blazej Kucman --- diff --git a/super-intel.c b/super-intel.c index 4988eef1..b7b030a2 100644 --- a/super-intel.c +++ b/super-intel.c @@ -1327,6 +1327,19 @@ static void update_imsm_raid_level(struct imsm_map *map, int new_level) return; } + /* + * RAID0 to RAID10 migration. + * Due to the compatibility with VROC UEFI must be maintained, this case must be handled + * separately, because the map does not have an updated number of disks. + */ + if (map->raid_level == IMSM_T_RAID0) { + if (map->num_members == 2) + map->raid_level = IMSM_T_RAID1; + else + map->raid_level = IMSM_T_RAID10; + return; + } + if (map->num_members == 4) { if (map->raid_level == IMSM_T_RAID10 || map->raid_level == IMSM_T_RAID1) return;