• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  // SPDX-License-Identifier: GPL-2.0-or-later
2  /* -*- linux-c -*- ------------------------------------------------------- *
3   *
4   *   Copyright 2002-2007 H. Peter Anvin - All Rights Reserved
5   *
6   * ----------------------------------------------------------------------- */
7  
8  /*
9   * raid6test.c
10   *
11   * Test RAID-6 recovery with various algorithms
12   */
13  
14  #include <stdlib.h>
15  #include <stdio.h>
16  #include <string.h>
17  #include <linux/raid/pq.h>
18  
19  #define NDISKS		16	/* Including P and Q */
20  
21  const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
22  
23  char *dataptrs[NDISKS];
24  char data[NDISKS][PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
25  char recovi[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
26  char recovj[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
27  
makedata(int start,int stop)28  static void makedata(int start, int stop)
29  {
30  	int i, j;
31  
32  	for (i = start; i <= stop; i++) {
33  		for (j = 0; j < PAGE_SIZE; j++)
34  			data[i][j] = rand();
35  
36  		dataptrs[i] = data[i];
37  	}
38  }
39  
disk_type(int d)40  static char disk_type(int d)
41  {
42  	switch (d) {
43  	case NDISKS-2:
44  		return 'P';
45  	case NDISKS-1:
46  		return 'Q';
47  	default:
48  		return 'D';
49  	}
50  }
51  
test_disks(int i,int j)52  static int test_disks(int i, int j)
53  {
54  	int erra, errb;
55  
56  	memset(recovi, 0xf0, PAGE_SIZE);
57  	memset(recovj, 0xba, PAGE_SIZE);
58  
59  	dataptrs[i] = recovi;
60  	dataptrs[j] = recovj;
61  
62  	raid6_dual_recov(NDISKS, PAGE_SIZE, i, j, (void **)&dataptrs);
63  
64  	erra = memcmp(data[i], recovi, PAGE_SIZE);
65  	errb = memcmp(data[j], recovj, PAGE_SIZE);
66  
67  	if (i < NDISKS-2 && j == NDISKS-1) {
68  		/* We don't implement the DQ failure scenario, since it's
69  		   equivalent to a RAID-5 failure (XOR, then recompute Q) */
70  		erra = errb = 0;
71  	} else {
72  		printf("algo=%-8s  faila=%3d(%c)  failb=%3d(%c)  %s\n",
73  		       raid6_call.name,
74  		       i, disk_type(i),
75  		       j, disk_type(j),
76  		       (!erra && !errb) ? "OK" :
77  		       !erra ? "ERRB" :
78  		       !errb ? "ERRA" : "ERRAB");
79  	}
80  
81  	dataptrs[i] = data[i];
82  	dataptrs[j] = data[j];
83  
84  	return erra || errb;
85  }
86  
main(int argc,char * argv[])87  int main(int argc, char *argv[])
88  {
89  	const struct raid6_calls *const *algo;
90  	const struct raid6_recov_calls *const *ra;
91  	int i, j, p1, p2;
92  	int err = 0;
93  
94  	makedata(0, NDISKS-1);
95  
96  	for (ra = raid6_recov_algos; *ra; ra++) {
97  		if ((*ra)->valid  && !(*ra)->valid())
98  			continue;
99  
100  		raid6_2data_recov = (*ra)->data2;
101  		raid6_datap_recov = (*ra)->datap;
102  
103  		printf("using recovery %s\n", (*ra)->name);
104  
105  		for (algo = raid6_algos; *algo; algo++) {
106  			if ((*algo)->valid && !(*algo)->valid())
107  				continue;
108  
109  			raid6_call = **algo;
110  
111  			/* Nuke syndromes */
112  			memset(data[NDISKS-2], 0xee, 2*PAGE_SIZE);
113  
114  			/* Generate assumed good syndrome */
115  			raid6_call.gen_syndrome(NDISKS, PAGE_SIZE,
116  						(void **)&dataptrs);
117  
118  			for (i = 0; i < NDISKS-1; i++)
119  				for (j = i+1; j < NDISKS; j++)
120  					err += test_disks(i, j);
121  
122  			if (!raid6_call.xor_syndrome)
123  				continue;
124  
125  			for (p1 = 0; p1 < NDISKS-2; p1++)
126  				for (p2 = p1; p2 < NDISKS-2; p2++) {
127  
128  					/* Simulate rmw run */
129  					raid6_call.xor_syndrome(NDISKS, p1, p2, PAGE_SIZE,
130  								(void **)&dataptrs);
131  					makedata(p1, p2);
132  					raid6_call.xor_syndrome(NDISKS, p1, p2, PAGE_SIZE,
133                                                                  (void **)&dataptrs);
134  
135  					for (i = 0; i < NDISKS-1; i++)
136  						for (j = i+1; j < NDISKS; j++)
137  							err += test_disks(i, j);
138  				}
139  
140  		}
141  		printf("\n");
142  	}
143  
144  	printf("\n");
145  	/* Pick the best algorithm test */
146  	raid6_select_algo();
147  
148  	if (err)
149  		printf("\n*** ERRORS FOUND ***\n");
150  
151  	return err;
152  }
153