0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <linux/export.h>
0017 #include <linux/raid/pq.h>
0018
0019
0020 static void raid6_2data_recov_intx1(int disks, size_t bytes, int faila,
0021 int failb, void **ptrs)
0022 {
0023 u8 *p, *q, *dp, *dq;
0024 u8 px, qx, db;
0025 const u8 *pbmul;
0026 const u8 *qmul;
0027
0028 p = (u8 *)ptrs[disks-2];
0029 q = (u8 *)ptrs[disks-1];
0030
0031
0032
0033
0034 dp = (u8 *)ptrs[faila];
0035 ptrs[faila] = (void *)raid6_empty_zero_page;
0036 ptrs[disks-2] = dp;
0037 dq = (u8 *)ptrs[failb];
0038 ptrs[failb] = (void *)raid6_empty_zero_page;
0039 ptrs[disks-1] = dq;
0040
0041 raid6_call.gen_syndrome(disks, bytes, ptrs);
0042
0043
0044 ptrs[faila] = dp;
0045 ptrs[failb] = dq;
0046 ptrs[disks-2] = p;
0047 ptrs[disks-1] = q;
0048
0049
0050 pbmul = raid6_gfmul[raid6_gfexi[failb-faila]];
0051 qmul = raid6_gfmul[raid6_gfinv[raid6_gfexp[faila]^raid6_gfexp[failb]]];
0052
0053
0054 while ( bytes-- ) {
0055 px = *p ^ *dp;
0056 qx = qmul[*q ^ *dq];
0057 *dq++ = db = pbmul[px] ^ qx;
0058 *dp++ = db ^ px;
0059 p++; q++;
0060 }
0061 }
0062
0063
0064 static void raid6_datap_recov_intx1(int disks, size_t bytes, int faila,
0065 void **ptrs)
0066 {
0067 u8 *p, *q, *dq;
0068 const u8 *qmul;
0069
0070 p = (u8 *)ptrs[disks-2];
0071 q = (u8 *)ptrs[disks-1];
0072
0073
0074
0075 dq = (u8 *)ptrs[faila];
0076 ptrs[faila] = (void *)raid6_empty_zero_page;
0077 ptrs[disks-1] = dq;
0078
0079 raid6_call.gen_syndrome(disks, bytes, ptrs);
0080
0081
0082 ptrs[faila] = dq;
0083 ptrs[disks-1] = q;
0084
0085
0086 qmul = raid6_gfmul[raid6_gfinv[raid6_gfexp[faila]]];
0087
0088
0089 while ( bytes-- ) {
0090 *p++ ^= *dq = qmul[*q ^ *dq];
0091 q++; dq++;
0092 }
0093 }
0094
0095
0096 const struct raid6_recov_calls raid6_recov_intx1 = {
0097 .data2 = raid6_2data_recov_intx1,
0098 .datap = raid6_datap_recov_intx1,
0099 .valid = NULL,
0100 .name = "intx1",
0101 .priority = 0,
0102 };
0103
0104 #ifndef __KERNEL__
0105
0106
0107
0108 void raid6_dual_recov(int disks, size_t bytes, int faila, int failb, void **ptrs)
0109 {
0110 if ( faila > failb ) {
0111 int tmp = faila;
0112 faila = failb;
0113 failb = tmp;
0114 }
0115
0116 if ( failb == disks-1 ) {
0117 if ( faila == disks-2 ) {
0118
0119 raid6_call.gen_syndrome(disks, bytes, ptrs);
0120 } else {
0121
0122
0123
0124 }
0125 } else {
0126 if ( failb == disks-2 ) {
0127
0128 raid6_datap_recov(disks, bytes, faila, ptrs);
0129 } else {
0130
0131 raid6_2data_recov(disks, bytes, faila, failb, ptrs);
0132 }
0133 }
0134 }
0135
0136 #endif