]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Allow creation of a RAID6 with a single missing device.
authorNeil Brown <neilb@suse.de>
Mon, 28 Apr 2008 06:30:09 +0000 (16:30 +1000)
committerNeil Brown <neilb@suse.de>
Mon, 28 Apr 2008 06:30:09 +0000 (16:30 +1000)
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
Create.c

index df88d29d31ebebf00547c003dc2c465e3b591bb9..c4d996d95991db363fa0e7fc10dbf2ebd068aead 100644 (file)
--- 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.
index b7a3f7d239cbfcf3d9abdbaf6b2b28ec021b2e6a..84075797f394930702f110f148c0393cd32cd7a8 100644 (file)
--- 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
                )