NeilBrown: Grow_restart to handle reducing number of devices in an array.

Martin F. Krafft madduck at alioth.debian.org
Wed Jan 27 02:01:04 UTC 2010


Module: mdadm
Branch: build
Commit: 82f2d6abf0c1614cf96ff3666e42daf71695afbf
URL:    http://git.debian.org/?p=pkg-mdadm/mdadm.git;a=commit;h=82f2d6abf0c1614cf96ff3666e42daf71695afbf

Author: NeilBrown <neilb at suse.de>
Date:   Fri Oct 16 17:43:51 2009 +1100

Grow_restart to handle reducing number of devices in an array.

FIXME this is wrong . what direction does reshape_position move?

If the device count in an array is shrinking, the critical
region is different so the tests need to be different when
restarting.

Signed-off-by: NeilBrown <neilb at suse.de>

---

 Grow.c |   41 +++++++++++++++++++++++++++++++----------
 1 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/Grow.c b/Grow.c
index 043e28f..9eb637c 100644
--- a/Grow.c
+++ b/Grow.c
@@ -1543,7 +1543,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
 	int i, j;
 	int old_disks;
 	unsigned long long *offsets;
-	unsigned long long  nstripe, ostripe, last_block;
+	unsigned long long  nstripe, ostripe;
 	int ndata, odata;
 
 	if (info->new_level != info->array.level)
@@ -1734,17 +1734,38 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
 	if (info->delta_disks == 0)
 		/* Alway need backup data when size doesn't change */
 		return 1;
-	nstripe = ostripe = 0;
-	last_block = 0;
-	while (nstripe >= ostripe) {
-		nstripe += info->new_chunk / 512;
-		last_block = nstripe * ndata;
-		ostripe = last_block / odata / (info->array.chunk_size/512) *
-			(info->array.chunk_size/512);
+	if (info->delta_disks < 0) {
+		/* When shrinking, the critical section is at the end.
+		 * So see if we are before the critical section.
+		 */
+		unsigned long long first_block;
+		nstripe = ostripe = 0;
+		first_block = 0;
+		while (ostripe >= nstripe) {
+			ostripe += info->array.chunk_size / 512;
+			first_block = ostripe * odata;
+			nstripe = first_block / ndata / (info->new_chunk/512) *
+				(info->new_chunk/512);
+		}
+
+		if (info->reshape_progress >= first_block)
+			return 0;
 	}
+	if (info->delta_disks > 0) {
+		/* See if we are beyond the critical section. */
+		unsigned long long last_block;
+		nstripe = ostripe = 0;
+		last_block = 0;
+		while (nstripe >= ostripe) {
+			nstripe += info->new_chunk / 512;
+			last_block = nstripe * ndata;
+			ostripe = last_block / odata / (info->array.chunk_size/512) *
+				(info->array.chunk_size/512);
+		}
 
-	if (info->reshape_progress >= last_block)
-		return 0;
+		if (info->reshape_progress >= last_block)
+			return 0;
+	}
 	/* needed to recover critical section! */
 	return 1;
 }




More information about the pkg-mdadm-commits mailing list