0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <stdlib.h>
0015 #include <stdio.h>
0016 #include <string.h>
0017 #include <linux/raid/pq.h>
0018
0019 #define NDISKS 16
0020
0021 const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
0022
0023 char *dataptrs[NDISKS];
0024 char data[NDISKS][PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
0025 char recovi[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
0026 char recovj[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
0027
0028 static void makedata(int start, int stop)
0029 {
0030 int i, j;
0031
0032 for (i = start; i <= stop; i++) {
0033 for (j = 0; j < PAGE_SIZE; j++)
0034 data[i][j] = rand();
0035
0036 dataptrs[i] = data[i];
0037 }
0038 }
0039
0040 static char disk_type(int d)
0041 {
0042 switch (d) {
0043 case NDISKS-2:
0044 return 'P';
0045 case NDISKS-1:
0046 return 'Q';
0047 default:
0048 return 'D';
0049 }
0050 }
0051
0052 static int test_disks(int i, int j)
0053 {
0054 int erra, errb;
0055
0056 memset(recovi, 0xf0, PAGE_SIZE);
0057 memset(recovj, 0xba, PAGE_SIZE);
0058
0059 dataptrs[i] = recovi;
0060 dataptrs[j] = recovj;
0061
0062 raid6_dual_recov(NDISKS, PAGE_SIZE, i, j, (void **)&dataptrs);
0063
0064 erra = memcmp(data[i], recovi, PAGE_SIZE);
0065 errb = memcmp(data[j], recovj, PAGE_SIZE);
0066
0067 if (i < NDISKS-2 && j == NDISKS-1) {
0068
0069
0070 erra = errb = 0;
0071 } else {
0072 printf("algo=%-8s faila=%3d(%c) failb=%3d(%c) %s\n",
0073 raid6_call.name,
0074 i, disk_type(i),
0075 j, disk_type(j),
0076 (!erra && !errb) ? "OK" :
0077 !erra ? "ERRB" :
0078 !errb ? "ERRA" : "ERRAB");
0079 }
0080
0081 dataptrs[i] = data[i];
0082 dataptrs[j] = data[j];
0083
0084 return erra || errb;
0085 }
0086
0087 int main(int argc, char *argv[])
0088 {
0089 const struct raid6_calls *const *algo;
0090 const struct raid6_recov_calls *const *ra;
0091 int i, j, p1, p2;
0092 int err = 0;
0093
0094 makedata(0, NDISKS-1);
0095
0096 for (ra = raid6_recov_algos; *ra; ra++) {
0097 if ((*ra)->valid && !(*ra)->valid())
0098 continue;
0099
0100 raid6_2data_recov = (*ra)->data2;
0101 raid6_datap_recov = (*ra)->datap;
0102
0103 printf("using recovery %s\n", (*ra)->name);
0104
0105 for (algo = raid6_algos; *algo; algo++) {
0106 if ((*algo)->valid && !(*algo)->valid())
0107 continue;
0108
0109 raid6_call = **algo;
0110
0111
0112 memset(data[NDISKS-2], 0xee, 2*PAGE_SIZE);
0113
0114
0115 raid6_call.gen_syndrome(NDISKS, PAGE_SIZE,
0116 (void **)&dataptrs);
0117
0118 for (i = 0; i < NDISKS-1; i++)
0119 for (j = i+1; j < NDISKS; j++)
0120 err += test_disks(i, j);
0121
0122 if (!raid6_call.xor_syndrome)
0123 continue;
0124
0125 for (p1 = 0; p1 < NDISKS-2; p1++)
0126 for (p2 = p1; p2 < NDISKS-2; p2++) {
0127
0128
0129 raid6_call.xor_syndrome(NDISKS, p1, p2, PAGE_SIZE,
0130 (void **)&dataptrs);
0131 makedata(p1, p2);
0132 raid6_call.xor_syndrome(NDISKS, p1, p2, PAGE_SIZE,
0133 (void **)&dataptrs);
0134
0135 for (i = 0; i < NDISKS-1; i++)
0136 for (j = i+1; j < NDISKS; j++)
0137 err += test_disks(i, j);
0138 }
0139
0140 }
0141 printf("\n");
0142 }
0143
0144 printf("\n");
0145
0146 raid6_select_algo();
0147
0148 if (err)
0149 printf("\n*** ERRORS FOUND ***\n");
0150
0151 return err;
0152 }