1818// -----------------------------------------------------------------------------
1919#include " common/debug.h"
2020#include " ErasureCodeIsa.h"
21- #include " xor_op.h"
2221#include " include/ceph_assert.h"
2322using namespace std ;
2423using namespace ceph ;
2524
2625// -----------------------------------------------------------------------------
2726extern " C" {
2827#include " isa-l/include/erasure_code.h"
28+ #include " isa-l/include/raid.h"
2929}
3030// -----------------------------------------------------------------------------
3131#define dout_context g_ceph_context
@@ -121,10 +121,9 @@ ErasureCodeIsaDefault::isa_encode(char **data,
121121 char **coding,
122122 int blocksize)
123123{
124-
125124 if (m == 1 )
126125 // single parity stripe
127- region_xor (( unsigned char **) data , (unsigned char *) coding[ 0 ], k, blocksize );
126+ xor_gen (k+m, blocksize , (void **) data );
128127 else
129128 ec_encode_data (blocksize, k, m, encode_tbls,
130129 (unsigned char **) data, (unsigned char **) coding);
@@ -157,61 +156,81 @@ ErasureCodeIsaDefault::isa_decode(int *erasures,
157156 int nerrs = 0 ;
158157 int i, r, s;
159158
159+ unsigned char *recover_source[k];
160+ unsigned char *recover_target[m];
161+ unsigned char *recover_buf[k+1 ];
162+
160163 // count the errors
161164 for (int l = 0 ; erasures[l] != -1 ; l++) {
162165 nerrs++;
163166 }
164167
165- unsigned char *recover_source[k];
166- unsigned char *recover_target[m];
167-
168- memset (recover_source, 0 , sizeof (recover_source));
169- memset (recover_target, 0 , sizeof (recover_target));
168+ if (nerrs > m)
169+ return -1 ;
170170
171- // ---------------------------------------------
172- // Assign source and target buffers
173- // ---------------------------------------------
174- for (i = 0 , s = 0 , r = 0 ; ((r < k) || (s < nerrs)) && (i < (k + m)); i++) {
175- if (!erasure_contains (erasures, i)) {
176- if (r < k) {
171+ // -----------------------------------
172+ // Assign source and target buffers.
173+ // -----------------------------------
174+ if ((m == 1 ) ||
175+ ((matrixtype == kVandermonde ) && (nerrs == 1 ) && (erasures[0 ] < (k + 1 )))) {
176+ // We need a single buffer to use the xor_gen() optimisation.
177+ // The last index must point to the erasure, and index that contained
178+ // the erasure must point to the parity.
179+ memset (recover_buf, 0 , sizeof (recover_buf));
180+ bool parity_set = false ;
181+ for (i = 0 ; i < (k + 1 ); i++) {
182+ if (erasure_contains (erasures, i)) {
183+ if (i < k) {
184+ recover_buf[i] = (unsigned char *) coding[0 ];
185+ recover_buf[k] = (unsigned char *) data[i];
186+ parity_set = true ;
187+ } else {
188+ recover_buf[i] = (unsigned char *) coding[0 ];
189+ }
190+ } else {
177191 if (i < k) {
178- recover_source[r ] = (unsigned char *) data[i];
192+ recover_buf[i ] = (unsigned char *) data[i];
179193 } else {
180- recover_source[r] = (unsigned char *) coding[i - k];
194+ if (!parity_set) {
195+ recover_buf[i] = (unsigned char *) coding[0 ];
196+ }
181197 }
182- r++;
183198 }
184- } else {
185- if (s < m) {
186- if (i < k) {
187- recover_target[s] = (unsigned char *) data[i];
188- } else {
189- recover_target[s] = (unsigned char *) coding[i - k];
199+ }
200+ }
201+ else {
202+ // We need source and target buffers to use ec_encode_data().
203+ // The erasure must be moved to the target buffer.
204+ memset (recover_source, 0 , sizeof (recover_source));
205+ memset (recover_target, 0 , sizeof (recover_target));
206+ for (i = 0 , s = 0 , r = 0 ; ((r < k) || (s < nerrs)) && (i < (k + m)); i++) {
207+ if (!erasure_contains (erasures, i)) {
208+ if (r < k) {
209+ if (i < k) {
210+ recover_source[r] = (unsigned char *) data[i];
211+ } else {
212+ recover_source[r] = (unsigned char *) coding[i - k];
213+ }
214+ r++;
215+ }
216+ } else {
217+ if (s < m) {
218+ if (i < k) {
219+ recover_target[s] = (unsigned char *) data[i];
220+ } else {
221+ recover_target[s] = (unsigned char *) coding[i - k];
222+ }
223+ s++;
190224 }
191- s++;
192225 }
193226 }
194227 }
195228
196- if (m == 1 ) {
229+ if ((m == 1 ) ||
230+ ((matrixtype == kVandermonde ) && (nerrs == 1 ) && (erasures[0 ] < (k + 1 )))) {
197231 // single parity decoding
198- ceph_assert (1 == nerrs);
199- dout (20 ) << " isa_decode: reconstruct using region xor [" <<
200- erasures[0 ] << " ]" << dendl;
201- region_xor (recover_source, recover_target[0 ], k, blocksize);
202- return 0 ;
203- }
204-
205-
206- if ((matrixtype == kVandermonde ) &&
207- (nerrs == 1 ) &&
208- (erasures[0 ] < (k + 1 ))) {
209- // use xor decoding if a data chunk is missing or the first coding chunk
210- dout (20 ) << " isa_decode: reconstruct using region xor [" <<
211- erasures[0 ] << " ]" << dendl;
212- ceph_assert (1 == s);
213- ceph_assert (k == r);
214- region_xor (recover_source, recover_target[0 ], k, blocksize);
232+ dout (20 ) << " isa_decode: reconstruct using xor_gen [" << erasures[0 ] << " ]" << dendl;
233+ xor_gen (k+1 , blocksize, (void **) recover_buf);
215234 return 0 ;
216235 }
217236
@@ -221,9 +240,6 @@ ErasureCodeIsaDefault::isa_decode(int *erasures,
221240
222241 int decode_index[k];
223242
224- if (nerrs > m)
225- return -1 ;
226-
227243 std::string erasure_signature; // describes a matrix configuration for caching
228244
229245 // ---------------------------------------------
0 commit comments