1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include <linux/export.h>
22#include <linux/raid/pq.h>
23
24
25static void raid6_2data_recov_intx1(int disks, size_t bytes, int faila,
26 int failb, void **ptrs)
27{
28 u8 *p, *q, *dp, *dq;
29 u8 px, qx, db;
30 const u8 *pbmul;
31 const u8 *qmul;
32
33 p = (u8 *)ptrs[disks-2];
34 q = (u8 *)ptrs[disks-1];
35
36
37
38
39 dp = (u8 *)ptrs[faila];
40 ptrs[faila] = (void *)raid6_empty_zero_page;
41 ptrs[disks-2] = dp;
42 dq = (u8 *)ptrs[failb];
43 ptrs[failb] = (void *)raid6_empty_zero_page;
44 ptrs[disks-1] = dq;
45
46 raid6_call.gen_syndrome(disks, bytes, ptrs);
47
48
49 ptrs[faila] = dp;
50 ptrs[failb] = dq;
51 ptrs[disks-2] = p;
52 ptrs[disks-1] = q;
53
54
55 pbmul = raid6_gfmul[raid6_gfexi[failb-faila]];
56 qmul = raid6_gfmul[raid6_gfinv[raid6_gfexp[faila]^raid6_gfexp[failb]]];
57
58
59 while ( bytes-- ) {
60 px = *p ^ *dp;
61 qx = qmul[*q ^ *dq];
62 *dq++ = db = pbmul[px] ^ qx;
63 *dp++ = db ^ px;
64 p++; q++;
65 }
66}
67
68
69static void raid6_datap_recov_intx1(int disks, size_t bytes, int faila,
70 void **ptrs)
71{
72 u8 *p, *q, *dq;
73 const u8 *qmul;
74
75 p = (u8 *)ptrs[disks-2];
76 q = (u8 *)ptrs[disks-1];
77
78
79
80 dq = (u8 *)ptrs[faila];
81 ptrs[faila] = (void *)raid6_empty_zero_page;
82 ptrs[disks-1] = dq;
83
84 raid6_call.gen_syndrome(disks, bytes, ptrs);
85
86
87 ptrs[faila] = dq;
88 ptrs[disks-1] = q;
89
90
91 qmul = raid6_gfmul[raid6_gfinv[raid6_gfexp[faila]]];
92
93
94 while ( bytes-- ) {
95 *p++ ^= *dq = qmul[*q ^ *dq];
96 q++; dq++;
97 }
98}
99
100
101const struct raid6_recov_calls raid6_recov_intx1 = {
102 .data2 = raid6_2data_recov_intx1,
103 .datap = raid6_datap_recov_intx1,
104 .valid = NULL,
105 .name = "intx1",
106 .priority = 0,
107};
108
109#ifndef __KERNEL__
110
111
112
113void raid6_dual_recov(int disks, size_t bytes, int faila, int failb, void **ptrs)
114{
115 if ( faila > failb ) {
116 int tmp = faila;
117 faila = failb;
118 failb = tmp;
119 }
120
121 if ( failb == disks-1 ) {
122 if ( faila == disks-2 ) {
123
124 raid6_call.gen_syndrome(disks, bytes, ptrs);
125 } else {
126
127
128
129 }
130 } else {
131 if ( failb == disks-2 ) {
132
133 raid6_datap_recov(disks, bytes, faila, ptrs);
134 } else {
135
136 raid6_2data_recov(disks, bytes, faila, failb, ptrs);
137 }
138 }
139}
140
141#endif
142