Blame SOURCES/0076-Assemble.c-respect-force-flag.patch

2792dd
From 7b99edab2834d5d08ef774b4cff784caaa1a186f Mon Sep 17 00:00:00 2001
2792dd
From: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
2792dd
Date: Tue, 5 May 2020 12:17:17 +0200
2792dd
Subject: [RHEL7.9 PATCH 76/77] Assemble.c: respect force flag.
2792dd
2792dd
If the array is dirty handler will set resync_start to 0 to inform kernel
2792dd
that resync is needed. RWH affects only raid456 module, for other
2792dd
levels array will be started even array is degraded and resync cannot be
2792dd
performed.
2792dd
2792dd
Force is really meaningful for raid456. If array is degraded and resync
2792dd
is requested, kernel will reject an attempt to start the array. To
2792dd
respect force, it has to be marked as clean (this will be done for each
2792dd
array without PPL) and remove the resync request (only for raid 456).
2792dd
Data corruption may occur so proper warning is added.
2792dd
2792dd
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@intel.com>
2792dd
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
2792dd
---
2792dd
 Assemble.c | 51 ++++++++++++++++++++++++++++++++++++++-------------
2792dd
 1 file changed, 38 insertions(+), 13 deletions(-)
2792dd
2792dd
diff --git a/Assemble.c b/Assemble.c
2792dd
index 2ed5884..3e5d4e6 100644
2792dd
--- a/Assemble.c
2792dd
+++ b/Assemble.c
2792dd
@@ -2030,6 +2030,15 @@ int assemble_container_content(struct supertype *st, int mdfd,
2792dd
 			free(avail);
2792dd
 			return err;
2792dd
 		}
2792dd
+	} else if (c->force) {
2792dd
+		/* Set the array as 'clean' so that we can proceed with starting
2792dd
+		 * it even if we don't have all devices. Mdmon doesn't care
2792dd
+		 * if the dirty flag is set in metadata, it will start managing
2792dd
+		 * it anyway.
2792dd
+		 * This is really important for raid456 (RWH case), other levels
2792dd
+		 * are started anyway.
2792dd
+		 */
2792dd
+		content->array.state |= 1;
2792dd
 	}
2792dd
 
2792dd
 	if (enough(content->array.level, content->array.raid_disks,
2792dd
@@ -2049,20 +2058,36 @@ int assemble_container_content(struct supertype *st, int mdfd,
2792dd
 	}
2792dd
 	free(avail);
2792dd
 
2792dd
-	if (c->runstop <= 0 &&
2792dd
-	    (working + preexist + expansion) <
2792dd
-	    content->array.working_disks) {
2792dd
-		if (c->export && result)
2792dd
-			*result |= INCR_UNSAFE;
2792dd
-		else if (c->verbose >= 0) {
2792dd
-			pr_err("%s assembled with %d device%s",
2792dd
-			       chosen_name, preexist + working,
2792dd
-			       preexist + working == 1 ? "":"s");
2792dd
-			if (preexist)
2792dd
-				fprintf(stderr, " (%d new)", working);
2792dd
-			fprintf(stderr, " but not safe to start\n");
2792dd
+	if ((working + preexist + expansion) < content->array.working_disks) {
2792dd
+		if (c->runstop <= 0) {
2792dd
+			if (c->export && result)
2792dd
+				*result |= INCR_UNSAFE;
2792dd
+			else if (c->verbose >= 0) {
2792dd
+				pr_err("%s assembled with %d device%s",
2792dd
+					chosen_name, preexist + working,
2792dd
+					preexist + working == 1 ? "":"s");
2792dd
+				if (preexist)
2792dd
+					fprintf(stderr, " (%d new)", working);
2792dd
+				fprintf(stderr, " but not safe to start\n");
2792dd
+				if (c->force)
2792dd
+					pr_err("Consider --run to start array as degraded.\n");
2792dd
+			}
2792dd
+			return 1;
2792dd
+		} else if (content->array.level >= 4 &&
2792dd
+			   content->array.level <= 6 &&
2792dd
+			   content->resync_start != MaxSector &&
2792dd
+			   c->force) {
2792dd
+			/* Don't inform the kernel that the array is not
2792dd
+			 * clean and requires resync.
2792dd
+			 */
2792dd
+			content->resync_start = MaxSector;
2792dd
+			err = sysfs_set_num(content, NULL, "resync_start",
2792dd
+					    MaxSector);
2792dd
+			if (err)
2792dd
+				return 1;
2792dd
+			pr_err("%s array state forced to clean. It may cause data corruption.\n",
2792dd
+				chosen_name);
2792dd
 		}
2792dd
-		return 1;
2792dd
 	}
2792dd
 
2792dd
 
2792dd
-- 
2792dd
2.7.5
2792dd