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 )