summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ReadMe.c53
-rw-r--r--mdadm.c9
-rw-r--r--mdadm.h40
-rw-r--r--super-ddf.c39
4 files changed, 120 insertions, 21 deletions
diff --git a/ReadMe.c b/ReadMe.c
index ea977d2..dd53c48 100644
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -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}
};
diff --git a/mdadm.c b/mdadm.c
index 72e7926..1fef4b9 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -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 */
diff --git a/mdadm.h b/mdadm.h
index f8f3685..f580e3e 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -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,