diff mbox series

[2/2] Revert "mdadm: remove container_enough logic"

Message ID 20240202163835.9652-3-mariusz.tkaczyk@linux.intel.com (mailing list archive)
State Superseded
Headers show
Series Revert bug prone commits | expand

Commit Message

Mariusz Tkaczyk Feb. 2, 2024, 4:38 p.m. UTC
This reverts commit 4dde420fc3e24077ab926f79674eaae1b71de10b.

Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
---
 Incremental.c | 11 +++++++++++
 mdadm.h       |  3 +++
 super-ddf.c   |  1 +
 super-intel.c | 32 +++++++++++++++++++++++++++++++-
 4 files changed, 46 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/Incremental.c b/Incremental.c
index 6cbc164a27b9..5477a5369c6f 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -1467,6 +1467,17 @@  static int Incremental_container(struct supertype *st, char *devname,
 
 	st->ss->getinfo_super(st, &info, NULL);
 
+	if ((c->runstop > 0 && info.container_enough >= 0) ||
+	    info.container_enough > 0)
+		/* pass */;
+	else {
+		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..0b647085fea1 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -377,6 +377,9 @@  struct mdinfo {
 	int container_member; /* for assembling external-metatdata arrays
 			       * This is to be used internally by metadata
 			       * handler only */
+	int container_enough; /* flag external handlers can set to
+			       * indicate that subarrays have not enough (-1),
+			       * enough to start (0), or all expected disks (1) */
 	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..697820b0d85e 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,10 +3840,36 @@  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);
 	}
+	dprintf("enough: %d\n", max_enough);
+	info->container_enough = max_enough;
 
 	if (super->disks) {
 		__u32 reserved = imsm_reserved_sectors(super, super->disks);