[PATCH 3/6] FIX: reshape raid0 on second array

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When reshape_array() is called for raid0 array (second and next),
we know that mdmon will update metadata. To do this after takeover
and mdmon start(optional) metadata is reread to be sure that
we should reshape this array and what reshape conditions we should check.

If info was read internally we should release it before exit.

Signed-off-by: Adam Kwolek <adam.kwolek@xxxxxxxxx>
---

 Grow.c |   57 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/Grow.c b/Grow.c
index fadaf2d..7cc6bae 100644
--- a/Grow.c
+++ b/Grow.c
@@ -1240,7 +1240,7 @@ char *analyse_change(struct mdinfo *info, struct reshape *re)
 	return NULL;
 }
 
-static int reshape_array(char *container, int fd, char *devname,
+static int reshape_array(char *container, int cfd, int fd, char *devname,
 			 struct supertype *st, struct mdinfo *info,
 			 int force, char *backup_file, int quiet, int forked);
 static int reshape_container(char *container, int cfd, char *devname,
@@ -1560,8 +1560,8 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
 			goto release;
 		}
 		sync_metadata(st);
-		rv = reshape_array(container, fd, devname, st, &info, force,
-				   backup_file, quiet, 0);
+		rv = reshape_array(container, cfd, fd, devname,
+				   st, &info, force, backup_file, quiet, 0);
 		frozen = 0;
 	}
 release:
@@ -1570,7 +1570,7 @@ release:
 	return rv;
 }
 
-static int reshape_array(char *container, int fd, char *devname,
+static int reshape_array(char *container, int cfd, int fd, char *devname,
 			 struct supertype *st, struct mdinfo *info,
 			 int force,
 			 char *backup_file, int quiet, int forked)
@@ -1595,6 +1595,8 @@ static int reshape_array(char *container, int fd, char *devname,
 	unsigned long long array_size;
 	int done;
 	struct mdinfo *sra;
+	int info_reloaded = 0;
+
 
 	msg = analyse_change(info, &reshape);
 	if (msg) {
@@ -1648,7 +1650,43 @@ static int reshape_array(char *container, int fd, char *devname,
 	if (reshape.level > 0 && st->ss->external &&
 	    !mdmon_running(st->container_dev)) {
 		start_mdmon(st->container_dev);
-		ping_monitor(container);
+	}
+	ping_monitor(container);
+
+	/* reload metadat as it is possible to change made by monitor
+	 */
+	if ((cfd >= 0) &&
+	   (info->array.level == 0)) {
+		char *subarray = strchr(info->text_version+1, '/')+1;
+
+		st->ss->load_container(st, cfd, NULL);
+		info = st->ss->container_content(st, subarray);
+		sysfs_init(info, fd, st->devnum);
+		info_reloaded = 1;
+		msg = analyse_change(info, &reshape);
+		if (msg) {
+			fprintf(stderr, Name ": %s\n", msg);
+			return 1;
+		}
+	}
+
+	if (ioctl(fd, GET_ARRAY_INFO, &array) != 0) {
+		dprintf("Canot get array information.\n");
+		return 1;
+	}
+	spares_needed = max(reshape.before.data_disks,
+			    reshape.after.data_disks)
+		+ reshape.parity - array.raid_disks;
+
+	if (!force && spares_needed < info->array.spare_disks) {
+		fprintf(stderr,
+			Name ": Need %d spare%s to avoid degraded array,"
+				" and only have %d.\n"
+				"       Use --force to over-ride this check.\n",
+			spares_needed,
+			spares_needed == 1 ? "" : "s",
+			info->array.spare_disks);
+		return 1;
 	}
 
 	/* ->reshape_super might have chosen some spares from the
@@ -2033,6 +2071,8 @@ static int reshape_array(char *container, int fd, char *devname,
 		}
 	}
 out:
+	if (info_reloaded)
+		sysfs_free(info);
 	if (forked)
 		return 0;
 	exit(0);
@@ -2045,6 +2085,8 @@ release:
 	}
 	if (!forked)
 		unfreeze(st);
+	if (info_reloaded)
+		sysfs_free(info);
 	return rv;
 }
 
@@ -2153,7 +2195,7 @@ int reshape_container(char *container, int cfd, char *devname,
 
 		sysfs_init(content, fd, mdstat->devnum);
 
-		rv = reshape_array(container, fd, adev, st,
+		rv = reshape_array(container, cfd, fd, adev, st,
 				   content, force,
 				   backup_file, quiet, 1);
 		close(fd);
@@ -3178,7 +3220,8 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
 	int err = sysfs_set_str(info, NULL, "array_state", "readonly");
 	if (err)
 		return err;
-	return reshape_array(NULL, mdfd, "array", st, info, 1, backup_file, 0, 0);
+	return reshape_array(NULL, -1, mdfd, "array", st,
+			     info, 1, backup_file, 0, 0);
 }
 
 

--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux RAID Wiki]     [ATA RAID]     [Linux SCSI Target Infrastructure]     [Linux Block]     [Linux IDE]     [Linux SCSI]     [Linux Hams]     [Device Mapper]     [Device Mapper Cryptographics]     [Kernel]     [Linux Admin]     [Linux Net]     [GFS]     [RPM]     [git]     [Yosemite Forum]


  Powered by Linux