71 lines
2.2 KiB
Diff
71 lines
2.2 KiB
Diff
|
based on
|
||
|
commit 6fb79233b050b4a3575f0e466ab04b5d301ac1de
|
||
|
Author: Neil Brown <neilb@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.
|
||
|
|
||
|
---
|
||
|
Create.c | 20 ++++++++++++++++++--
|
||
|
1 file changed, 18 insertions(+), 2 deletions(-)
|
||
|
|
||
|
--- Create.c.orig
|
||
|
+++ Create.c
|
||
|
@@ -63,6 +63,7 @@ int Create(struct supertype *st, char *m
|
||
|
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 */
|
||
|
void *super;
|
||
|
@@ -203,6 +204,8 @@ int Create(struct supertype *st, char *m
|
||
|
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 *m
|
||
|
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 ++;
|
||
|
+ array.active_disks--;
|
||
|
+ missing_disks++;
|
||
|
+ }
|
||
|
|
||
|
if (level <= 0 && first_missing != subdevs * 2) {
|
||
|
fprintf(stderr,
|
||
|
@@ -360,11 +375,12 @@ int Create(struct supertype *st, char *m
|
||
|
if (fstat(mdfd, &stb)==0)
|
||
|
array.md_minor = minor(stb.st_rdev);
|
||
|
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
|
||
|
)
|