diff --git a/0166-Revert-mdadm-remove-container_enough-logic.patch b/0166-Revert-mdadm-remove-container_enough-logic.patch new file mode 100644 index 0000000..943fd9d --- /dev/null +++ b/0166-Revert-mdadm-remove-container_enough-logic.patch @@ -0,0 +1,151 @@ +From 476b00bdeeb6c004b3a758bd842b0fa9e4164508 Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Mon, 5 Feb 2024 15:50:29 +0100 +Subject: [PATCH 1/1] Revert "mdadm: remove container_enough logic" + +Mentioned patch changes way of IMSM member arrays assembling, they are +updated by every new drive incremental processes. Previously, member +arrays were created and filled once, by last drive incremental process. + +We determined regressions with various impact. Unfortunately, initial +testing didn't show them. + +Regressions are connected to drive appearance order and may not be +reproducible on every configuration, there are at least two know +issues for now: + +- sysfs attributes are filled using old metadata if there is + outdated drive and it is enumerated first. + +- rebuild may be aborted and started from beginning after reboot, + if drive under rebuild is enumerated as the last one. + +This reverts commit 4dde420fc3e24077ab926f79674eaae1b71de10b. It fixes +checkpatch issues and reworks logic to remove empty "if" branch in +Incremental. + +Signed-off-by: Mariusz Tkaczyk +--- + Incremental.c | 9 +++++++++ + mdadm.h | 7 +++++++ + super-ddf.c | 1 + + super-intel.c | 32 +++++++++++++++++++++++++++++++- + 4 files changed, 48 insertions(+), 1 deletion(-) + +diff --git a/Incremental.c b/Incremental.c +index 6cbc164a27b9..30c07c037028 100644 +--- a/Incremental.c ++++ b/Incremental.c +@@ -1467,6 +1467,15 @@ static int Incremental_container(struct supertype *st, char *devname, + + st->ss->getinfo_super(st, &info, NULL); + ++ if (info.container_enough < 0 || (info.container_enough == 0 && c->runstop < 1)) { ++ if (c->export) ++ printf("MD_STARTED=no\n"); ++ else if (c->verbose) ++ pr_err("Not enough devices to start the container.\n"); ++ ++ return 0; ++ } ++ + match = conf_match(st, &info, devname, c->verbose, &rv); + if (match == NULL && rv == 2) + return rv; +diff --git a/mdadm.h b/mdadm.h +index 709b6104c401..1f28b3e754be 100644 +--- a/mdadm.h ++++ b/mdadm.h +@@ -377,6 +377,13 @@ struct mdinfo { + int container_member; /* for assembling external-metatdata arrays + * This is to be used internally by metadata + * handler only */ ++ /** ++ * flag external handlers can set to indicate that subarrays have: ++ * - not enough disks to start (-1), ++ * - enough disks to start (0), ++ * - all expected disks (1). ++ */ ++ int container_enough; + char sys_name[32]; + struct mdinfo *devs; + struct mdinfo *next; +diff --git a/super-ddf.c b/super-ddf.c +index a87e3169d325..7571e3b740c6 100644 +--- a/super-ddf.c ++++ b/super-ddf.c +@@ -1975,6 +1975,7 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *m + info->array.ctime = DECADE + __be32_to_cpu(*cptr); + + info->array.chunk_size = 0; ++ info->container_enough = 1; + + info->disk.major = 0; + info->disk.minor = 0; +diff --git a/super-intel.c b/super-intel.c +index 6a664a2e58d3..dbea235dd4bd 100644 +--- a/super-intel.c ++++ b/super-intel.c +@@ -3778,6 +3778,7 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char * + struct intel_super *super = st->sb; + struct imsm_disk *disk; + int map_disks = info->array.raid_disks; ++ int max_enough = -1; + int i; + struct imsm_super *mpb; + +@@ -3819,9 +3820,12 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char * + + for (i = 0; i < mpb->num_raid_devs; i++) { + struct imsm_dev *dev = get_imsm_dev(super, i); +- int j = 0; ++ int failed, enough, j, missing = 0; + struct imsm_map *map; ++ __u8 state; + ++ failed = imsm_count_failed(super, dev, MAP_0); ++ state = imsm_check_degraded(super, dev, failed, MAP_0); + map = get_imsm_map(dev, MAP_0); + + /* any newly missing disks? +@@ -3836,11 +3840,37 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char * + + if (!(ord & IMSM_ORD_REBUILD) && + get_imsm_missing(super, idx)) { ++ missing = 1; + break; + } + } ++ ++ if (state == IMSM_T_STATE_FAILED) ++ enough = -1; ++ else if (state == IMSM_T_STATE_DEGRADED && ++ (state != map->map_state || missing)) ++ enough = 0; ++ else /* we're normal, or already degraded */ ++ enough = 1; ++ if (is_gen_migration(dev) && missing) { ++ /* during general migration we need all disks ++ * that process is running on. ++ * No new missing disk is allowed. ++ */ ++ max_enough = -1; ++ enough = -1; ++ /* no more checks necessary ++ */ ++ break; ++ } ++ /* in the missing/failed disk case check to see ++ * if at least one array is runnable ++ */ ++ max_enough = max(max_enough, enough); + } + ++ info->container_enough = max_enough; ++ + if (super->disks) { + __u32 reserved = imsm_reserved_sectors(super, super->disks); + +-- +2.32.0 (Apple Git-132) +