Neil Brown: Allow creation of a RAID6 with a single missing device.

Martin F. Krafft madduck at alioth.debian.org
Wed Jun 25 15:42:26 UTC 2008


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

Author: Neil Brown <neilb at suse.de>
Date:   Mon Apr 28 16:30:09 2008 +1000

Allow creation of a RAID6 with a single missing device.

This did not work before as we couldn't mark it clean as there would
be some parity blocks out of sync, and raid6 will not assemble a
dirty degraded array.
So make such arrays doubly degraded (the last device becomes a spare)
and clean.

---

 ChangeLog |    1 +
 Create.c  |   20 ++++++++++++++++++--
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index df88d29..c4d996d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,7 @@ Changes Prior to this release
     -   For v0.90 superblocks, print the 'Events' count as a real count,
 	not 2 numbers separated by a dot.
     -   Updates some URLs in the man page.
+    -   Allow creation of a RAID6 with exactly one missing device.
 
 Changes Prior to 2.6.4 release
     -   Make "--create --auto=mdp" work for non-standard device names.
diff --git a/Create.c b/Create.c
index b7a3f7d..8407579 100644
--- a/Create.c
+++ b/Create.c
@@ -63,6 +63,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
 	int fail=0, warn=0;
 	struct stat stb;
 	int first_missing = subdevs * 2;
+	int second_missing = subdevs * 2;
 	int missing_disks = 0;
 	int insert_point = subdevs * 2; /* where to insert a missing drive */
 	int pass;
@@ -203,6 +204,8 @@ int Create(struct supertype *st, char *mddev, int mdfd,
 		if (strcasecmp(dname, "missing")==0) {
 			if (first_missing > dnum)
 				first_missing = dnum;
+			if (second_missing > dnum && dnum > first_missing)
+				second_missing = dnum;
 			missing_disks ++;
 			continue;
 		}
@@ -341,6 +344,18 @@ int Create(struct supertype *st, char *mddev, int mdfd,
 			break;
 		}
 	}
+	/* For raid6, if creating with 1 missing drive, make a good drive
+	 * into a spare, else the create will fail
+	 */
+	if (assume_clean == 0 && force == 0 && first_missing < raiddisks &&
+	    second_missing >= raiddisks && level == 6) {
+		insert_point = raiddisks - 1;
+		if (insert_point == first_missing)
+			insert_point--;
+		sparedisks ++;
+		info.array.active_disks--;
+		missing_disks++;
+	}
 
 	if (level <= 0 && first_missing != subdevs * 2) {
 		fprintf(stderr,
@@ -360,11 +375,12 @@ int Create(struct supertype *st, char *mddev, int mdfd,
 	if (fstat(mdfd, &stb)==0)
 		info.array.md_minor = minor(stb.st_rdev);
 	info.array.not_persistent = 0;
-	/*** FIX: Need to do something about RAID-6 here ***/
+
 	if ( ( (level == 4 || level == 5) &&
 	       (insert_point < raiddisks || first_missing < raiddisks) )
 	     ||
-	     ( level == 6 && missing_disks == 2)
+	     ( level == 6 && (insert_point < raiddisks
+			      || second_missing < raiddisks))
 	     ||
 	     assume_clean
 		)




More information about the pkg-mdadm-commits mailing list