You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
185 lines
6.4 KiB
185 lines
6.4 KiB
From 27550b13297adbdefe42fe4eb785b7fde1c0ed91 Mon Sep 17 00:00:00 2001
|
|
From: Mateusz Kusiak <mateusz.kusiak@intel.com>
|
|
Date: Mon, 29 Apr 2024 15:07:15 +0200
|
|
Subject: [PATCH 54/69] imsm: add support for literal RAID 10
|
|
|
|
As for now, IMSM supports only 4 drive RAID 1+0. This patch is first in
|
|
series to add support for literal RAID 10 (with more than 4 drives) to
|
|
imsm.
|
|
|
|
Allow setting RAID 10 as raid level for imsm arrays.
|
|
|
|
Add update_imsm_raid_level() to handle raid level updates. Set RAID10 as
|
|
default level for imsm R0 to R10 migrations. Replace magic numbers with
|
|
defined values for RAID level checks/assigns.
|
|
|
|
Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
|
|
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
|
|
---
|
|
super-intel.c | 67 ++++++++++++++++++++++++++++++++++++---------------
|
|
1 file changed, 48 insertions(+), 19 deletions(-)
|
|
|
|
diff --git a/super-intel.c b/super-intel.c
|
|
index 1a8a7b12..a7efc8df 100644
|
|
--- a/super-intel.c
|
|
+++ b/super-intel.c
|
|
@@ -166,7 +166,8 @@ struct imsm_map {
|
|
__u8 raid_level;
|
|
#define IMSM_T_RAID0 0
|
|
#define IMSM_T_RAID1 1
|
|
-#define IMSM_T_RAID5 5 /* since metadata version 1.2.02 ? */
|
|
+#define IMSM_T_RAID5 5
|
|
+#define IMSM_T_RAID10 10
|
|
__u8 num_members; /* number of member disks */
|
|
__u8 num_domains; /* number of parity domains */
|
|
__u8 failed_disk_num; /* valid only when state is degraded */
|
|
@@ -1259,14 +1260,42 @@ static int get_imsm_disk_slot(struct imsm_map *map, const unsigned int idx)
|
|
|
|
return IMSM_STATUS_ERROR;
|
|
}
|
|
+/**
|
|
+ * update_imsm_raid_level() - update raid level appropriately in &imsm_map.
|
|
+ * @map: &imsm_map pointer.
|
|
+ * @new_level: MD style level.
|
|
+ *
|
|
+ * For backward compatibility reasons we need to differentiate RAID10.
|
|
+ * In the past IMSM RAID10 was presented as RAID1.
|
|
+ * Keep compatibility unless it is not explicitly updated by UEFI driver.
|
|
+ *
|
|
+ * Routine needs num_members to be set and (optionally) raid_level.
|
|
+ */
|
|
+static void update_imsm_raid_level(struct imsm_map *map, int new_level)
|
|
+{
|
|
+ if (new_level != IMSM_T_RAID10) {
|
|
+ map->raid_level = new_level;
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (map->num_members == 4) {
|
|
+ if (map->raid_level == IMSM_T_RAID10 || map->raid_level == IMSM_T_RAID1)
|
|
+ return;
|
|
+
|
|
+ map->raid_level = IMSM_T_RAID1;
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ map->raid_level = IMSM_T_RAID10;
|
|
+}
|
|
|
|
static int get_imsm_raid_level(struct imsm_map *map)
|
|
{
|
|
- if (map->raid_level == 1) {
|
|
+ if (map->raid_level == IMSM_T_RAID1) {
|
|
if (map->num_members == 2)
|
|
- return 1;
|
|
+ return IMSM_T_RAID1;
|
|
else
|
|
- return 10;
|
|
+ return IMSM_T_RAID10;
|
|
}
|
|
|
|
return map->raid_level;
|
|
@@ -5678,7 +5707,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
|
|
set_pba_of_lba0(map, super->create_offset);
|
|
map->blocks_per_strip = __cpu_to_le16(info_to_blocks_per_strip(info));
|
|
map->failed_disk_num = ~0;
|
|
- if (info->level > 0)
|
|
+ if (info->level > IMSM_T_RAID0)
|
|
map->map_state = (info->state ? IMSM_T_STATE_NORMAL
|
|
: IMSM_T_STATE_UNINITIALIZED);
|
|
else
|
|
@@ -5686,16 +5715,15 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
|
|
IMSM_T_STATE_NORMAL;
|
|
map->ddf = 1;
|
|
|
|
- if (info->level == 1 && info->raid_disks > 2) {
|
|
+ if (info->level == IMSM_T_RAID1 && info->raid_disks > 2) {
|
|
free(dev);
|
|
free(dv);
|
|
- pr_err("imsm does not support more than 2 disksin a raid1 volume\n");
|
|
+ pr_err("imsm does not support more than 2 disks in a raid1 volume\n");
|
|
return 0;
|
|
}
|
|
+ map->num_members = info->raid_disks;
|
|
|
|
- map->raid_level = info->level;
|
|
- if (info->level == 10)
|
|
- map->raid_level = 1;
|
|
+ update_imsm_raid_level(map, info->level);
|
|
set_num_domains(map);
|
|
|
|
size_per_member += NUM_BLOCKS_DIRTY_STRIPE_REGION;
|
|
@@ -5703,7 +5731,6 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
|
|
size_per_member /
|
|
BLOCKS_PER_KB));
|
|
|
|
- map->num_members = info->raid_disks;
|
|
update_num_data_stripes(map, array_blocks);
|
|
for (i = 0; i < map->num_members; i++) {
|
|
/* initialized in add_to_super */
|
|
@@ -8275,7 +8302,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
|
|
info_d->data_offset = pba_of_lba0(map);
|
|
info_d->component_size = calc_component_size(map, dev);
|
|
|
|
- if (map->raid_level == 5) {
|
|
+ if (map->raid_level == IMSM_T_RAID5) {
|
|
info_d->ppl_sector = this->ppl_sector;
|
|
info_d->ppl_size = this->ppl_size;
|
|
if (this->consistency_policy == CONSISTENCY_POLICY_PPL &&
|
|
@@ -9533,7 +9560,7 @@ static int apply_reshape_migration_update(struct imsm_update_reshape_migration *
|
|
}
|
|
|
|
to_state = map->map_state;
|
|
- if ((u->new_level == 5) && (map->raid_level == 0)) {
|
|
+ if ((u->new_level == IMSM_T_RAID5) && (map->raid_level == IMSM_T_RAID0)) {
|
|
map->num_members++;
|
|
/* this should not happen */
|
|
if (u->new_disks[0] < 0) {
|
|
@@ -9544,11 +9571,13 @@ static int apply_reshape_migration_update(struct imsm_update_reshape_migration *
|
|
to_state = IMSM_T_STATE_NORMAL;
|
|
}
|
|
migrate(new_dev, super, to_state, MIGR_GEN_MIGR);
|
|
+
|
|
if (u->new_level > -1)
|
|
- map->raid_level = u->new_level;
|
|
+ update_imsm_raid_level(map, u->new_level);
|
|
+
|
|
migr_map = get_imsm_map(new_dev, MAP_1);
|
|
- if ((u->new_level == 5) &&
|
|
- (migr_map->raid_level == 0)) {
|
|
+ if ((u->new_level == IMSM_T_RAID5) &&
|
|
+ (migr_map->raid_level == IMSM_T_RAID0)) {
|
|
int ord = map->num_members - 1;
|
|
migr_map->num_members--;
|
|
if (u->new_disks[0] < 0)
|
|
@@ -9584,7 +9613,7 @@ static int apply_reshape_migration_update(struct imsm_update_reshape_migration *
|
|
|
|
/* add disk
|
|
*/
|
|
- if (u->new_level != 5 || migr_map->raid_level != 0 ||
|
|
+ if (u->new_level != IMSM_T_RAID5 || migr_map->raid_level != IMSM_T_RAID0 ||
|
|
migr_map->raid_level == map->raid_level)
|
|
goto skip_disk_add;
|
|
|
|
@@ -9963,7 +9992,7 @@ static int apply_takeover_update(struct imsm_update_takeover *u,
|
|
/* update map */
|
|
map->num_members /= map->num_domains;
|
|
map->map_state = IMSM_T_STATE_NORMAL;
|
|
- map->raid_level = 0;
|
|
+ update_imsm_raid_level(map, IMSM_T_RAID0);
|
|
set_num_domains(map);
|
|
update_num_data_stripes(map, imsm_dev_size(dev));
|
|
map->failed_disk_num = -1;
|
|
@@ -10007,7 +10036,7 @@ static int apply_takeover_update(struct imsm_update_takeover *u,
|
|
map = get_imsm_map(dev_new, MAP_0);
|
|
|
|
map->map_state = IMSM_T_STATE_DEGRADED;
|
|
- map->raid_level = 1;
|
|
+ update_imsm_raid_level(map, IMSM_T_RAID10);
|
|
set_num_domains(map);
|
|
map->num_members = map->num_members * map->num_domains;
|
|
update_num_data_stripes(map, imsm_dev_size(dev));
|
|
--
|
|
2.41.0
|
|
|