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

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