From 446894ea8db17a2dfc740f81d58190c5ac8167d5 Mon Sep 17 00:00:00 2001
From: NeilBrown <neilb@suse.de>
Date: Tue, 1 Nov 2011 15:45:46 +1100
Subject: [PATCH] Grow: fix check_reshape and open_code it.
References: bnc#730695

check_reshape should not try to parse the subarray string - only
metadata handlers are allowed to do that.

The common code and only interpret a subarray string by passing it to
"container_content" which will then return only the member for that
subarray.

So remove check_reshape and place similar logic explicitly at the two
call-sites.  They are different enough that it is probably clearer to
have explicit code.

Signed-off-by: NeilBrown <neilb@suse.de>
---
 Grow.c        |   54 ++++++++++++++++--------------------------------------
 super-intel.c |    4 ++--
 2 files changed, 18 insertions(+), 40 deletions(-)

--- mdadm-3.2.2.orig/Grow.c
+++ mdadm-3.2.2/Grow.c
@@ -1357,36 +1357,6 @@ static int reshape_container(char *conta
 			     char *backup_file,
 			     int quiet, int restart, int freeze_reshape);
 
-/*
- * helper routine to check metadata reshape avalability
- * 1. Do not "grow" arrays with volume activation blocked
- * 2. do not reshape containers with container reshape blocked
- *
- * IN:
- *	subarray - array name or NULL for container wide reshape
- *	content - md device info from container_content
- * OUT:
- *	0 - block reshape
- */
-static int check_reshape(char *subarray, struct mdinfo *content)
-{
-	char *ep;
-	unsigned int idx;
-
-	if (!subarray) {
-		if (content->array.state & (1<<MD_SB_BLOCK_CONTAINER_RESHAPE))
-			return 0;
-	} else {
-		/* do not "grow" arrays with volume activation blocked */
-		idx = strtoul(subarray, &ep, 10);
-		if (*ep == '\0'
-		    && content->container_member == (int) idx
-		    && (content->array.state & (1<<MD_SB_BLOCK_VOLUME)))
-			return 0;
-	}
-	return 1;
-}
-
 int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
 		 long long size,
 		 int level, char *layout_str, int chunksize, int raid_disks,
@@ -1504,12 +1474,16 @@ int Grow_reshape(char *devname, int fd,
 
 			cc = st->ss->container_content(st, subarray);
 			for (content = cc; content ; content = content->next) {
-				int allow_reshape;
+				int allow_reshape = 1;
 
 				/* check if reshape is allowed based on metadata
 				 * indications stored in content.array.status
 				 */
-				allow_reshape = check_reshape(subarray, content);
+				if (content->array.state & (1<<MD_SB_BLOCK_VOLUME))
+					allow_reshape = 0;
+				if (content->array.state
+				    & (1<<MD_SB_BLOCK_CONTAINER_RESHAPE))
+					allow_reshape = 0;
 				if (!allow_reshape) {
 					fprintf(stderr, Name
 						" cannot reshape arrays in"
@@ -3776,10 +3750,10 @@ int Grow_continue_command(char *devname,
 			goto Grow_continue_command_exit;
 		}
 
-		cc = st->ss->container_content(st, NULL);
+		cc = st->ss->container_content(st, subarray);
 		for (content = cc; content ; content = content->next) {
 			char *array;
-			int allow_reshape;
+			int allow_reshape = 1;
 
 			if (content->reshape_active == 0)
 				continue;
@@ -3788,10 +3762,14 @@ int Grow_continue_command(char *devname,
 			 * content->reshape_active state, therefore we
 			 * need to check_reshape based on
 			 * reshape_active and subarray name
-			*/
-			allow_reshape =
-			  check_reshape((content->reshape_active == CONTAINER_RESHAPE)? NULL : subarray,
-					content);
+			 */
+			if (content->array.state & (1<<MD_SB_BLOCK_VOLUME))
+				allow_reshape = 0;
+			if (content->reshape_active == CONTAINER_RESHAPE &&
+			    (content->array.state
+			     & (1<<MD_SB_BLOCK_CONTAINER_RESHAPE)))
+				allow_reshape = 0;
+
 			if (!allow_reshape) {
 				fprintf(stderr, Name
 					": cannot continue reshape of an array"
--- mdadm-3.2.2.orig/super-intel.c
+++ mdadm-3.2.2/super-intel.c
@@ -5760,8 +5760,8 @@ static struct mdinfo *container_content_
 						 map->num_members, /* raid disks */
 						 &chunk,
 						 1 /* verbose */)) {
-			fprintf(stderr, Name ": IMSM RAID gemetry validation failed. "
-				"Array %s activation is blocked.\n",
+			fprintf(stderr, Name ": IMSM RAID geometry validation"
+				" failed.  Array %s activation is blocked.\n",
 				dev->volume);
 			this->array.state |=
 			  (1<<MD_SB_BLOCK_CONTAINER_RESHAPE) |
