File 0158-super1-allow-reshape-that-hasn-t-really-started-to-b.patch of Package mdadm.5365

From d5ff855d477cea9c8f242721923982aeb81a6dbc Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.com>
Date: Thu, 28 Jan 2016 12:57:08 +1100
Subject: [PATCH 218/359] super1: allow reshape that hasn't really started to
 be reverted.
References: bsc#1081910

A simple revert doesn't work here because the reshape_position is
in the critical section.
The best approach is to let the reshape progress a bit and then
go backwards.
If that isn't possible, assembling with --update=revert-reshape and
--invalid-backup should work.

Reported-by-tested-by: George Rapp <george.rapp@gmail.com>
Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Coly Li <colyli@suse.de>

---
 Assemble.c |  9 ++++++++-
 super1.c   | 21 ++++++++++++++++++++-
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/Assemble.c b/Assemble.c
index a7cd163..25a14be 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -643,7 +643,14 @@ static int load_devices(struct devs *devices, char *devmap,
 			} else if (strcmp(c->update, "nodes") == 0) {
 				tst->nodes = c->nodes;
 				err = tst->ss->write_bitmap(tst, dfd, NodeNumUpdate);
-			} else
+			} else if (strcmp(c->update, "revert-reshape") == 0 &&
+				   c->invalid_backup)
+				err = tst->ss->update_super(tst, content,
+							    "revert-reshape-nobackup",
+							    devname, c->verbose,
+							    ident->uuid_set,
+							    c->homehost);
+			else
 				err = tst->ss->update_super(tst, content, c->update,
 							    devname, c->verbose,
 							    ident->uuid_set,
diff --git a/super1.c b/super1.c
index 5d08d4d..0f6797a 100644
--- a/super1.c
+++ b/super1.c
@@ -1307,7 +1307,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
 			(st->sb + MAX_SB_SIZE + BM_SUPER_SIZE);
 		sb->data_size = __cpu_to_le64(
 			misc->device_size - __le64_to_cpu(sb->data_offset));
-	} else if (strcmp(update, "revert-reshape") == 0) {
+	} else if (strncmp(update, "revert-reshape", 14) == 0) {
 		rv = -2;
 		if (!(sb->feature_map & __cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE)))
 			pr_err("No active reshape to revert on %s\n",
@@ -1317,6 +1317,24 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
 			unsigned long long reshape_sectors;
 			long reshape_chunk;
 			rv = 0;
+			/* If the reshape hasn't started, just stop it.
+			 * It is conceivable that a stripe was modified but
+			 * the metadata not updated.  In that case the backup
+			 * should have been used to get passed the critical stage.
+			 * If that couldn't happen, the "-nobackup" version
+			 * will be used.
+			 */
+			if (strcmp(update, "revert-reshape-nobackup") == 0 &&
+			    sb->reshape_position == 0 &&
+			    (__le32_to_cpu(sb->delta_disks) > 0 ||
+			     (__le32_to_cpu(sb->delta_disks) == 0 &&
+			      !(sb->feature_map & __cpu_to_le32(MD_FEATURE_RESHAPE_BACKWARDS))))) {
+				sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE);
+				sb->raid_disks = __cpu_to_le32(__le32_to_cpu(sb->raid_disks) -
+							       __le32_to_cpu(sb->delta_disks));
+				sb->delta_disks = 0;
+				goto done;
+			}
 			/* reshape_position is a little messy.
 			 * Its value must be a multiple of the larger
 			 * chunk size, and of the "after" data disks.
@@ -1363,6 +1381,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
 				sb->new_offset = __cpu_to_le32(-offset_delta);
 				sb->data_size = __cpu_to_le64(__le64_to_cpu(sb->data_size) - offset_delta);
 			}
+		done:;
 		}
 	} else if (strcmp(update, "_reshape_progress")==0)
 		sb->reshape_position = __cpu_to_le64(info->reshape_progress);
-- 
2.16.1

openSUSE Build Service is sponsored by