diff options
-rw-r--r-- | ReadMe.c | 53 | ||||
-rw-r--r-- | mdadm.c | 9 | ||||
-rw-r--r-- | mdadm.h | 40 | ||||
-rw-r--r-- | super-ddf.c | 39 |
4 files changed, 120 insertions, 21 deletions
@@ -584,16 +584,49 @@ char Help_config[] = /* name/number mappings */ mapping_t r5layout[] = { - { "left-asymmetric", 0}, - { "right-asymmetric", 1}, - { "left-symmetric", 2}, - { "right-symmetric", 3}, - - { "default", 2}, - { "la", 0}, - { "ra", 1}, - { "ls", 2}, - { "rs", 3}, + { "left-asymmetric", ALGORITHM_LEFT_ASYMMETRIC}, + { "right-asymmetric", ALGORITHM_RIGHT_ASYMMETRIC}, + { "left-symmetric", ALGORITHM_LEFT_SYMMETRIC}, + { "right-symmetric", ALGORITHM_RIGHT_SYMMETRIC}, + + { "default", ALGORITHM_LEFT_SYMMETRIC}, + { "la", ALGORITHM_LEFT_ASYMMETRIC}, + { "ra", ALGORITHM_RIGHT_ASYMMETRIC}, + { "ls", ALGORITHM_LEFT_SYMMETRIC}, + { "rs", ALGORITHM_RIGHT_SYMMETRIC}, + + { "parity-first", ALGORITHM_PARITY_0}, + { "parity-last", ALGORITHM_PARITY_N}, + { "ddf-zero-restart", ALGORITHM_RIGHT_ASYMMETRIC}, + { "ddf-N-restart", ALGORITHM_LEFT_ASYMMETRIC}, + { "ddf-N-continue", ALGORITHM_LEFT_SYMMETRIC}, + + { NULL, 0} +}; +mapping_t r6layout[] = { + { "left-asymmetric", ALGORITHM_LEFT_ASYMMETRIC}, + { "right-asymmetric", ALGORITHM_RIGHT_ASYMMETRIC}, + { "left-symmetric", ALGORITHM_LEFT_SYMMETRIC}, + { "right-symmetric", ALGORITHM_RIGHT_SYMMETRIC}, + + { "default", ALGORITHM_LEFT_SYMMETRIC}, + { "la", ALGORITHM_LEFT_ASYMMETRIC}, + { "ra", ALGORITHM_RIGHT_ASYMMETRIC}, + { "ls", ALGORITHM_LEFT_SYMMETRIC}, + { "rs", ALGORITHM_RIGHT_SYMMETRIC}, + + { "parity-first", ALGORITHM_PARITY_0}, + { "parity-last", ALGORITHM_PARITY_N}, + { "ddf-zero-restart", ALGORITHM_ROTATING_ZERO_RESTART}, + { "ddf-N-restart", ALGORITHM_ROTATING_N_RESTART}, + { "ddf-N-continue", ALGORITHM_ROTATING_N_CONTINUE}, + + { "left-asymmetric-6", ALGORITHM_LEFT_ASYMMETRIC_6}, + { "right-asymmetric-6", ALGORITHM_RIGHT_ASYMMETRIC_6}, + { "left-symmetric-6", ALGORITHM_LEFT_SYMMETRIC_6}, + { "right-symmetric-6", ALGORITHM_RIGHT_SYMMETRIC_6}, + { "parity-first-6", ALGORITHM_PARITY_0_6}, + { NULL, 0} }; @@ -437,7 +437,6 @@ int main(int argc, char *argv[]) exit(2); case 5: - case 6: layout = map_name(r5layout, optarg); if (layout==UnSet) { fprintf(stderr, Name ": layout %s not understood for raid5.\n", @@ -445,6 +444,14 @@ int main(int argc, char *argv[]) exit(2); } break; + case 6: + layout = map_name(r6layout, optarg); + if (layout==UnSet) { + fprintf(stderr, Name ": layout %s not understood for raid6.\n", + optarg); + exit(2); + } + break; case 10: /* 'f', 'o' or 'n' followed by a number <= raid_disks */ @@ -394,7 +394,7 @@ extern int restore_stripes(int *dest, unsigned long long *offsets, extern char *map_num(mapping_t *map, int num); extern int map_name(mapping_t *map, char *name); -extern mapping_t r5layout[], pers[], modes[], faultylayout[]; +extern mapping_t r5layout[], r6layout[], pers[], modes[], faultylayout[]; extern char *map_dev(int major, int minor, int create); @@ -937,8 +937,44 @@ static inline int xasprintf(char **strp, const char *fmt, ...) { #define makedev(M,m) (((M)<<8) | (m)) #endif -/* for raid5 */ +/* for raid4/5/6 */ #define ALGORITHM_LEFT_ASYMMETRIC 0 #define ALGORITHM_RIGHT_ASYMMETRIC 1 #define ALGORITHM_LEFT_SYMMETRIC 2 #define ALGORITHM_RIGHT_SYMMETRIC 3 + +/* Define non-rotating (raid4) algorithms. These allow + * conversion of raid4 to raid5. + */ +#define ALGORITHM_PARITY_0 4 /* P or P,Q are initial devices */ +#define ALGORITHM_PARITY_N 5 /* P or P,Q are final devices. */ + +/* DDF RAID6 layouts differ from md/raid6 layouts in two ways. + * Firstly, the exact positioning of the parity block is slightly + * different between the 'LEFT_*' modes of md and the "_N_*" modes + * of DDF. + * Secondly, or order of datablocks over which the Q syndrome is computed + * is different. + * Consequently we have different layouts for DDF/raid6 than md/raid6. + * These layouts are from the DDFv1.2 spec. + * Interestingly DDFv1.2-Errata-A does not specify N_CONTINUE but + * leaves RLQ=3 as 'Vendor Specific' + */ + +#define ALGORITHM_ROTATING_ZERO_RESTART 8 /* DDF PRL=6 RLQ=1 */ +#define ALGORITHM_ROTATING_N_RESTART 9 /* DDF PRL=6 RLQ=2 */ +#define ALGORITHM_ROTATING_N_CONTINUE 10 /*DDF PRL=6 RLQ=3 */ + + +/* For every RAID5 algorithm we define a RAID6 algorithm + * with exactly the same layout for data and parity, and + * with the Q block always on the last device (N-1). + * This allows trivial conversion from RAID5 to RAID6 + */ +#define ALGORITHM_LEFT_ASYMMETRIC_6 16 +#define ALGORITHM_RIGHT_ASYMMETRIC_6 17 +#define ALGORITHM_LEFT_SYMMETRIC_6 18 +#define ALGORITHM_RIGHT_SYMMETRIC_6 19 +#define ALGORITHM_PARITY_0_6 20 +#define ALGORITHM_PARITY_N_6 ALGORITHM_PARITY_N + diff --git a/super-ddf.c b/super-ddf.c index 6c75998..b021801 100644 --- a/super-ddf.c +++ b/super-ddf.c @@ -1759,20 +1759,25 @@ static int layout_to_rlq(int level, int layout, int raiddisks) } break; case 5: - case 6: switch(layout) { case ALGORITHM_LEFT_ASYMMETRIC: return DDF_RAID5_N_RESTART; case ALGORITHM_RIGHT_ASYMMETRIC: - if (level == 5) - return DDF_RAID5_0_RESTART; - else - return DDF_RAID6_0_RESTART; + return DDF_RAID5_0_RESTART; case ALGORITHM_LEFT_SYMMETRIC: return DDF_RAID5_N_CONTINUE; case ALGORITHM_RIGHT_SYMMETRIC: return -1; /* not mentioned in standard */ } + case 6: + switch(layout) { + case ALGORITHM_ROTATING_N_RESTART: + return DDF_RAID5_N_RESTART; + case ALGORITHM_ROTATING_ZERO_RESTART: + return DDF_RAID6_0_RESTART; + case ALGORITHM_ROTATING_N_CONTINUE: + return DDF_RAID5_N_CONTINUE; + } } return -1; } @@ -1807,11 +1812,11 @@ static int rlq_to_layout(int rlq, int prl, int raiddisks) case DDF_RAID6: switch(rlq) { case DDF_RAID5_N_RESTART: - return ALGORITHM_LEFT_ASYMMETRIC; + return ALGORITHM_ROTATING_N_RESTART; case DDF_RAID6_0_RESTART: - return ALGORITHM_RIGHT_ASYMMETRIC; + return ALGORITHM_ROTATING_ZERO_RESTART; case DDF_RAID5_N_CONTINUE: - return ALGORITHM_LEFT_SYMMETRIC; + return ALGORITHM_ROTATING_N_CONTINUE; default: return -1; } @@ -3537,6 +3542,23 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a, } #endif /* MDASSEMBLE */ +static int ddf_level_to_layout(int level) +{ + switch(level) { + case 0: + case 1: + return 0; + case 5: + return ALGORITHM_LEFT_SYMMETRIC; + case 6: + return ALGORITHM_ROTATING_N_CONTINUE; + case 10: + return 0x102; + default: + return UnSet; + } +} + struct superswitch super_ddf = { #ifndef MDASSEMBLE .examine_super = examine_super_ddf, @@ -3562,6 +3584,7 @@ struct superswitch super_ddf = { .free_super = free_super_ddf, .match_metadata_desc = match_metadata_desc_ddf, .container_content = container_content_ddf, + .default_layout = ddf_level_to_layout, .external = 1, |