This source file includes following definitions.
- rf_RegularPEFunc
- rf_RegularONEFunc
- rf_SimpleONEFunc
- rf_RegularESubroutine
- rf_RegularEFunc
- rf_DegrESubroutine
- rf_Degraded_100_EOFunc
- rf_e_EncOneSect
- rf_e_encToBuf
- rf_RecoveryEFunc
- rf_EO_DegradedWriteEFunc
- rf_doubleEOdecode
- rf_EvenOddDoubleRecoveryFunc
- rf_EOWriteDoubleRecoveryFunc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 #include "rf_types.h"
36 #include "rf_raid.h"
37 #include "rf_dag.h"
38 #include "rf_dagffrd.h"
39 #include "rf_dagffwr.h"
40 #include "rf_dagdegrd.h"
41 #include "rf_dagdegwr.h"
42 #include "rf_dagutils.h"
43 #include "rf_dagfuncs.h"
44 #include "rf_etimer.h"
45 #include "rf_general.h"
46 #include "rf_configure.h"
47 #include "rf_parityscan.h"
48 #include "rf_evenodd.h"
49 #include "rf_evenodd_dagfuncs.h"
50
51
52 RF_RedFuncs_t rf_EOSmallWritePFuncs = {
53 rf_RegularXorFunc, "Regular Old-New P",
54 rf_SimpleXorFunc, "Simple Old-New P"
55 };
56 RF_RedFuncs_t rf_EOSmallWriteEFuncs = {
57 rf_RegularONEFunc, "Regular Old-New E",
58 rf_SimpleONEFunc, "Regular Old-New E"
59 };
60
61 RF_RedFuncs_t rf_eoPRecoveryFuncs = {
62 rf_RecoveryXorFunc, "Recovery Xr",
63 rf_RecoveryXorFunc, "Recovery Xr"
64 };
65 RF_RedFuncs_t rf_eoERecoveryFuncs = {
66 rf_RecoveryEFunc, "Recovery E Func",
67 rf_RecoveryEFunc, "Recovery E Func"
68 };
69
70
71
72
73
74
75 int
76 rf_RegularPEFunc(RF_DagNode_t *node)
77 {
78 rf_RegularESubroutine(node, node->results[1]);
79 rf_RegularXorFunc(node);
80 #if 1
81 return (0);
82 #endif
83 }
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111 int
112 rf_RegularONEFunc(RF_DagNode_t *node)
113 {
114 RF_Raid_t *raidPtr = (RF_Raid_t *) node->params[node->numParams - 1].p;
115 RF_RaidLayout_t *layoutPtr = (RF_RaidLayout_t *) & raidPtr->Layout;
116 int EpdaIndex = (node->numParams - 1) / 2 - 1;
117
118
119
120
121 int i, k, retcode = 0;
122 int suoffset, length;
123 RF_RowCol_t scol;
124 char *srcbuf, *destbuf;
125 RF_AccTraceEntry_t *tracerec = node->dagHdr->tracerec;
126 RF_Etimer_t timer;
127 RF_PhysDiskAddr_t *pda, *EPDA = (RF_PhysDiskAddr_t *)
128 node->params[EpdaIndex].p;
129
130 int ESUOffset = rf_StripeUnitOffset(layoutPtr, EPDA->startSector);
131
132 RF_ASSERT(EPDA->type == RF_PDA_TYPE_Q);
133 RF_ASSERT(ESUOffset == 0);
134
135 RF_ETIMER_START(timer);
136
137
138
139
140
141 for (k = 0; k < EpdaIndex; k += 2) {
142 length = rf_RaidAddressToByte(raidPtr,
143 ((RF_PhysDiskAddr_t *) node->params[k].p)->numSector);
144 retcode = rf_bxor(node->params[k + EpdaIndex + 3].p,
145 node->params[k + 1].p, length, node->dagHdr->bp);
146 }
147
148
149
150
151 for (i = 0; i < EpdaIndex; i += 2)
152 if (node->params[i + 1].p != node->results[0]) {
153
154 pda = (RF_PhysDiskAddr_t *) node->params[i].p;
155 srcbuf = (char *) node->params[i + 1].p;
156 scol = rf_EUCol(layoutPtr, pda->raidAddress);
157 suoffset = rf_StripeUnitOffset(layoutPtr,
158 pda->startSector);
159 destbuf = ((char *) node->results[0]) +
160 rf_RaidAddressToByte(raidPtr, suoffset);
161 rf_e_encToBuf(raidPtr, scol, srcbuf,
162 RF_EO_MATRIX_DIM - 2, destbuf, pda->numSector);
163 }
164
165
166
167
168 for (k = 0; k < EpdaIndex; k += 2) {
169 length = rf_RaidAddressToByte(raidPtr,
170 ((RF_PhysDiskAddr_t *) node->params[k].p)->numSector);
171 retcode = rf_bxor(node->params[k + EpdaIndex + 3].p,
172 node->params[k + 1].p, length, node->dagHdr->bp);
173 }
174 RF_ETIMER_STOP(timer);
175 RF_ETIMER_EVAL(timer);
176 tracerec->q_us += RF_ETIMER_VAL_US(timer);
177 rf_GenericWakeupFunc(node, 0);
178 #if 1
179 return (0);
180 #endif
181 }
182
183 int
184 rf_SimpleONEFunc(RF_DagNode_t *node)
185 {
186 RF_Raid_t *raidPtr = (RF_Raid_t *) node->params[node->numParams - 1].p;
187 RF_RaidLayout_t *layoutPtr = (RF_RaidLayout_t *) & raidPtr->Layout;
188 RF_PhysDiskAddr_t *pda = (RF_PhysDiskAddr_t *) node->params[0].p;
189 int retcode = 0;
190 char *srcbuf, *destbuf;
191 RF_AccTraceEntry_t *tracerec = node->dagHdr->tracerec;
192 int length;
193 RF_RowCol_t scol;
194 RF_Etimer_t timer;
195
196 RF_ASSERT(((RF_PhysDiskAddr_t *) node->params[2].p)->type ==
197 RF_PDA_TYPE_Q);
198 if (node->dagHdr->status == rf_enable) {
199 RF_ETIMER_START(timer);
200
201 length = rf_RaidAddressToByte(raidPtr,
202 ((RF_PhysDiskAddr_t *) node->params[4].p)->numSector);
203
204 retcode = rf_bxor(node->params[5].p, node->params[1].p,
205 length, node->dagHdr->bp);
206
207
208
209
210 scol = rf_EUCol(layoutPtr, pda->raidAddress);
211 srcbuf = node->params[1].p;
212 destbuf = node->params[3].p;
213
214 rf_e_encToBuf(raidPtr, scol, srcbuf, RF_EO_MATRIX_DIM - 2,
215 destbuf, pda->numSector);
216 rf_bxor(node->params[5].p, node->params[1].p, length,
217 node->dagHdr->bp);
218 RF_ETIMER_STOP(timer);
219 RF_ETIMER_EVAL(timer);
220 tracerec->q_us += RF_ETIMER_VAL_US(timer);
221
222 }
223 return (rf_GenericWakeupFunc(node, retcode));
224
225
226
227
228 }
229
230
231
232
233
234
235 void
236 rf_RegularESubroutine(RF_DagNode_t *node, char *ebuf)
237 {
238 RF_Raid_t *raidPtr = (RF_Raid_t *) node->params[node->numParams - 1].p;
239 RF_RaidLayout_t *layoutPtr = (RF_RaidLayout_t *) & raidPtr->Layout;
240 RF_PhysDiskAddr_t *pda;
241 int i, suoffset;
242 RF_RowCol_t scol;
243 char *srcbuf, *destbuf;
244 RF_AccTraceEntry_t *tracerec = node->dagHdr->tracerec;
245 RF_Etimer_t timer;
246
247 RF_ETIMER_START(timer);
248 for (i = 0; i < node->numParams - 2; i += 2) {
249 RF_ASSERT(node->params[i + 1].p != ebuf);
250 pda = (RF_PhysDiskAddr_t *) node->params[i].p;
251 suoffset = rf_StripeUnitOffset(layoutPtr, pda->startSector);
252 scol = rf_EUCol(layoutPtr, pda->raidAddress);
253 srcbuf = (char *) node->params[i + 1].p;
254 destbuf = ebuf + rf_RaidAddressToByte(raidPtr, suoffset);
255 rf_e_encToBuf(raidPtr, scol, srcbuf, RF_EO_MATRIX_DIM - 2,
256 destbuf, pda->numSector);
257 }
258 RF_ETIMER_STOP(timer);
259 RF_ETIMER_EVAL(timer);
260 tracerec->xor_us += RF_ETIMER_VAL_US(timer);
261 }
262
263
264
265
266
267 int
268 rf_RegularEFunc(RF_DagNode_t *node)
269 {
270 rf_RegularESubroutine(node, node->results[0]);
271 rf_GenericWakeupFunc(node, 0);
272 #if 1
273 return (0);
274 #endif
275 }
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291 void
292 rf_DegrESubroutine(RF_DagNode_t *node, char *ebuf)
293 {
294 RF_Raid_t *raidPtr = (RF_Raid_t *) node->params[node->numParams - 1].p;
295 RF_RaidLayout_t *layoutPtr = (RF_RaidLayout_t *) & raidPtr->Layout;
296 RF_PhysDiskAddr_t *failedPDA = (RF_PhysDiskAddr_t *) node->params[node->numParams - 2].p;
297 RF_PhysDiskAddr_t *pda;
298 int i, suoffset, failedSUOffset = rf_StripeUnitOffset(layoutPtr, failedPDA->startSector);
299 RF_RowCol_t scol;
300 char *srcbuf, *destbuf;
301 RF_AccTraceEntry_t *tracerec = node->dagHdr->tracerec;
302 RF_Etimer_t timer;
303
304 RF_ETIMER_START(timer);
305 for (i = 0; i < node->numParams - 2; i += 2) {
306 RF_ASSERT(node->params[i + 1].p != ebuf);
307 pda = (RF_PhysDiskAddr_t *) node->params[i].p;
308 suoffset = rf_StripeUnitOffset(layoutPtr, pda->startSector);
309 scol = rf_EUCol(layoutPtr, pda->raidAddress);
310 srcbuf = (char *) node->params[i + 1].p;
311 destbuf = ebuf + rf_RaidAddressToByte(raidPtr, suoffset - failedSUOffset);
312 rf_e_encToBuf(raidPtr, scol, srcbuf, RF_EO_MATRIX_DIM - 2, destbuf, pda->numSector);
313 }
314
315 RF_ETIMER_STOP(timer);
316 RF_ETIMER_EVAL(timer);
317 tracerec->q_us += RF_ETIMER_VAL_US(timer);
318 }
319
320
321
322
323
324
325
326
327 int
328 rf_Degraded_100_EOFunc(RF_DagNode_t *node)
329 {
330 rf_DegrESubroutine(node, node->results[1]);
331 rf_RecoveryXorFunc(node);
332 #if 1
333 return (0);
334
335 #endif
336 }
337
338
339
340
341
342
343
344
345 void
346 rf_e_EncOneSect(RF_RowCol_t srcLogicCol, char *srcSecbuf,
347 RF_RowCol_t destLogicCol, char *destSecbuf, int bytesPerSector)
348 {
349 int S_index;
350
351
352
353 int numRowInEncMatrix = (RF_EO_MATRIX_DIM) - 1;
354 RF_RowCol_t j, indexInDest;
355
356
357
358
359 RF_RowCol_t indexInSrc;
360
361
362
363 int bytesPerEU = bytesPerSector / numRowInEncMatrix;
364
365 #if RF_EO_MATRIX_DIM > 17
366 int shortsPerEU = bytesPerEU / sizeof(short);
367 short *destShortBuf, *srcShortBuf1, *srcShortBuf2;
368 short temp1;
369 #elif RF_EO_MATRIX_DIM == 17
370 int longsPerEU = bytesPerEU / sizeof(long);
371 long *destLongBuf, *srcLongBuf1, *srcLongBuf2;
372 long temp1;
373 #endif
374
375 #if RF_EO_MATRIX_DIM > 17
376 RF_ASSERT(sizeof(short) == 2 || sizeof(short) == 1);
377 RF_ASSERT(bytesPerEU % sizeof(short) == 0);
378 #elif RF_EO_MATRIX_DIM == 17
379 RF_ASSERT(sizeof(long) == 8 || sizeof(long) == 4);
380 RF_ASSERT(bytesPerEU % sizeof(long) == 0);
381 #endif
382
383 S_index = rf_EO_Mod((RF_EO_MATRIX_DIM - 1 + destLogicCol - srcLogicCol), RF_EO_MATRIX_DIM);
384 #if RF_EO_MATRIX_DIM > 17
385 srcShortBuf1 = (short *) (srcSecbuf + S_index * bytesPerEU);
386 #elif RF_EO_MATRIX_DIM == 17
387 srcLongBuf1 = (long *) (srcSecbuf + S_index * bytesPerEU);
388 #endif
389
390 for (indexInDest = 0; indexInDest < numRowInEncMatrix; indexInDest++) {
391 indexInSrc = rf_EO_Mod((indexInDest + destLogicCol - srcLogicCol), RF_EO_MATRIX_DIM);
392
393 #if RF_EO_MATRIX_DIM > 17
394 destShortBuf = (short *) (destSecbuf + indexInDest * bytesPerEU);
395 srcShortBuf2 = (short *) (srcSecbuf + indexInSrc * bytesPerEU);
396 for (j = 0; j < shortsPerEU; j++) {
397 temp1 = destShortBuf[j] ^ srcShortBuf1[j];
398
399
400 if (indexInSrc != RF_EO_MATRIX_DIM - 1)
401 destShortBuf[j] = (srcShortBuf2[j]) ^ temp1;
402
403
404 else
405 destShortBuf[j] = temp1;
406 }
407
408 #elif RF_EO_MATRIX_DIM == 17
409 destLongBuf = (long *) (destSecbuf + indexInDest * bytesPerEU);
410 srcLongBuf2 = (long *) (srcSecbuf + indexInSrc * bytesPerEU);
411 for (j = 0; j < longsPerEU; j++) {
412 temp1 = destLongBuf[j] ^ srcLongBuf1[j];
413 if (indexInSrc != RF_EO_MATRIX_DIM - 1)
414 destLongBuf[j] = (srcLongBuf2[j]) ^ temp1;
415 else
416 destLongBuf[j] = temp1;
417 }
418 #endif
419 }
420 }
421
422 void
423 rf_e_encToBuf(RF_Raid_t *raidPtr, RF_RowCol_t srcLogicCol, char *srcbuf,
424 RF_RowCol_t destLogicCol, char *destbuf, int numSector)
425 {
426 int i, bytesPerSector = rf_RaidAddressToByte(raidPtr, 1);
427
428 for (i = 0; i < numSector; i++) {
429 rf_e_EncOneSect(srcLogicCol, srcbuf, destLogicCol, destbuf, bytesPerSector);
430 srcbuf += bytesPerSector;
431 destbuf += bytesPerSector;
432 }
433 }
434
435
436
437
438
439
440
441 int
442 rf_RecoveryEFunc(RF_DagNode_t *node)
443 {
444 RF_Raid_t *raidPtr = (RF_Raid_t *) node->params[node->numParams - 1].p;
445 RF_RaidLayout_t *layoutPtr = (RF_RaidLayout_t *) & raidPtr->Layout;
446 RF_PhysDiskAddr_t *failedPDA = (RF_PhysDiskAddr_t *) node->params[node->numParams - 2].p;
447 RF_RowCol_t scol;
448 RF_RowCol_t fcol = rf_EUCol(layoutPtr, failedPDA->raidAddress);
449
450 int i;
451 RF_PhysDiskAddr_t *pda;
452 int suoffset, failedSUOffset = rf_StripeUnitOffset(layoutPtr, failedPDA->startSector);
453 char *srcbuf, *destbuf;
454 RF_AccTraceEntry_t *tracerec = node->dagHdr->tracerec;
455 RF_Etimer_t timer;
456
457 bzero((char *) node->results[0], rf_RaidAddressToByte(raidPtr, failedPDA->numSector));
458 if (node->dagHdr->status == rf_enable) {
459 RF_ETIMER_START(timer);
460 for (i = 0; i < node->numParams - 2; i += 2)
461 if (node->params[i + 1].p != node->results[0]) {
462 pda = (RF_PhysDiskAddr_t *) node->params[i].p;
463 if (i == node->numParams - 4)
464 scol = RF_EO_MATRIX_DIM - 2;
465
466 else
467 scol = rf_EUCol(layoutPtr, pda->raidAddress);
468 srcbuf = (char *) node->params[i + 1].p;
469 suoffset = rf_StripeUnitOffset(layoutPtr, pda->startSector);
470 destbuf = ((char *) node->results[0]) + rf_RaidAddressToByte(raidPtr, suoffset - failedSUOffset);
471 rf_e_encToBuf(raidPtr, scol, srcbuf, fcol, destbuf, pda->numSector);
472 }
473 RF_ETIMER_STOP(timer);
474 RF_ETIMER_EVAL(timer);
475 tracerec->xor_us += RF_ETIMER_VAL_US(timer);
476 }
477 return (rf_GenericWakeupFunc(node, 0));
478 }
479
480
481
482
483
484
485 int
486 rf_EO_DegradedWriteEFunc(RF_DagNode_t *node)
487 {
488 rf_DegrESubroutine(node, node->results[0]);
489 rf_GenericWakeupFunc(node, 0);
490 #if 1
491 return (0);
492 #endif
493 }
494
495
496
497
498
499
500
501 void
502 rf_doubleEOdecode(RF_Raid_t *raidPtr, char **rrdbuf, char **dest,
503 RF_RowCol_t *fcol, char *pbuf, char *ebuf)
504 {
505 RF_RaidLayout_t *layoutPtr = (RF_RaidLayout_t *) &(raidPtr->Layout);
506 int i, j, k, f1, f2, row;
507 int rrdrow, erow, count = 0;
508 int bytesPerSector = rf_RaidAddressToByte(raidPtr, 1);
509 int numRowInEncMatrix = (RF_EO_MATRIX_DIM) - 1;
510 #if 0
511 int pcol = (RF_EO_MATRIX_DIM) - 1;
512 #endif
513 int ecol = (RF_EO_MATRIX_DIM) - 2;
514 int bytesPerEU = bytesPerSector / numRowInEncMatrix;
515 int numDataCol = layoutPtr->numDataCol;
516 #if RF_EO_MATRIX_DIM > 17
517 int shortsPerEU = bytesPerEU / sizeof(short);
518 short *rrdbuf_current, *pbuf_current, *ebuf_current;
519 short *dest_smaller, *dest_smaller_current;
520 short *dest_larger, *dest_larger_current;
521 short *temp;
522 short *P;
523
524 RF_ASSERT(bytesPerEU % sizeof(short) == 0);
525 RF_Malloc(P, bytesPerEU, (short *));
526 RF_Malloc(temp, bytesPerEU, (short *));
527 #elif RF_EO_MATRIX_DIM == 17
528 int longsPerEU = bytesPerEU / sizeof(long);
529 long *rrdbuf_current, *pbuf_current, *ebuf_current;
530 long *dest_smaller, *dest_smaller_current;
531 long *dest_larger, *dest_larger_current;
532 long *temp;
533 long *P;
534
535 RF_ASSERT(bytesPerEU % sizeof(long) == 0);
536 RF_Malloc(P, bytesPerEU, (long *));
537 RF_Malloc(temp, bytesPerEU, (long *));
538 #endif
539 RF_ASSERT(*((long *) dest[0]) == 0);
540 RF_ASSERT(*((long *) dest[1]) == 0);
541 bzero((char *) P, bytesPerEU);
542 bzero((char *) temp, bytesPerEU);
543 RF_ASSERT(*P == 0);
544
545
546
547
548
549 for (i = 0; i < numRowInEncMatrix; i++)
550 for (k = 0; k < longsPerEU; k++) {
551 #if RF_EO_MATRIX_DIM > 17
552 ebuf_current = ((short *) ebuf) + i * shortsPerEU + k;
553 pbuf_current = ((short *) pbuf) + i * shortsPerEU + k;
554 #elif RF_EO_MATRIX_DIM == 17
555 ebuf_current = ((long *) ebuf) + i * longsPerEU + k;
556 pbuf_current = ((long *) pbuf) + i * longsPerEU + k;
557 #endif
558 P[k] ^= *ebuf_current;
559 P[k] ^= *pbuf_current;
560 }
561 RF_ASSERT(fcol[0] != fcol[1]);
562 if (fcol[0] < fcol[1]) {
563 #if RF_EO_MATRIX_DIM > 17
564 dest_smaller = (short *) (dest[0]);
565 dest_larger = (short *) (dest[1]);
566 #elif RF_EO_MATRIX_DIM == 17
567 dest_smaller = (long *) (dest[0]);
568 dest_larger = (long *) (dest[1]);
569 #endif
570 f1 = fcol[0];
571 f2 = fcol[1];
572 } else {
573 #if RF_EO_MATRIX_DIM > 17
574 dest_smaller = (short *) (dest[1]);
575 dest_larger = (short *) (dest[0]);
576 #elif RF_EO_MATRIX_DIM == 17
577 dest_smaller = (long *) (dest[1]);
578 dest_larger = (long *) (dest[0]);
579 #endif
580 f1 = fcol[1];
581 f2 = fcol[0];
582 }
583 row = (RF_EO_MATRIX_DIM) - 1;
584 while ((row = rf_EO_Mod((row + f1 - f2), RF_EO_MATRIX_DIM)) !=
585 ((RF_EO_MATRIX_DIM) - 1)) {
586 #if RF_EO_MATRIX_DIM > 17
587 dest_larger_current = dest_larger + row * shortsPerEU;
588 dest_smaller_current = dest_smaller + row * shortsPerEU;
589 #elif RF_EO_MATRIX_DIM == 17
590 dest_larger_current = dest_larger + row * longsPerEU;
591 dest_smaller_current = dest_smaller + row * longsPerEU;
592 #endif
593
594
595
596
597
598
599 for (j = 0; j < numDataCol; j++) {
600 if (j == f1 || j == f2)
601 continue;
602 rrdrow = rf_EO_Mod((row + f2 - j), RF_EO_MATRIX_DIM);
603 if (rrdrow != (RF_EO_MATRIX_DIM) - 1) {
604 #if RF_EO_MATRIX_DIM > 17
605 rrdbuf_current = (short *) (rrdbuf[j]) +
606 rrdrow * shortsPerEU;
607 for (k = 0; k < shortsPerEU; k++)
608 temp[k] ^= *(rrdbuf_current + k);
609 #elif RF_EO_MATRIX_DIM == 17
610 rrdbuf_current = (long *) (rrdbuf[j]) +
611 rrdrow * longsPerEU;
612 for (k = 0; k < longsPerEU; k++)
613 temp[k] ^= *(rrdbuf_current + k);
614 #endif
615 }
616 }
617
618
619
620
621
622
623
624
625 erow = rf_EO_Mod((row + f2 - ecol), (RF_EO_MATRIX_DIM));
626 if (erow != (RF_EO_MATRIX_DIM) - 1) {
627 #if RF_EO_MATRIX_DIM > 17
628 ebuf_current = (short *) ebuf + shortsPerEU * erow;
629 for (k = 0; k < shortsPerEU; k++)
630 temp[k] ^= *(ebuf_current + k);
631 #elif RF_EO_MATRIX_DIM == 17
632 ebuf_current = (long *) ebuf + longsPerEU * erow;
633 for (k = 0; k < longsPerEU; k++)
634 temp[k] ^= *(ebuf_current + k);
635 #endif
636 }
637
638
639
640
641
642 #if RF_EO_MATRIX_DIM > 17
643 for (k = 0; k < shortsPerEU; k++)
644 temp[k] ^= P[k];
645
646 for (k = 0; k < shortsPerEU; k++)
647 dest_larger_current[k] = temp[k];
648 #elif RF_EO_MATRIX_DIM == 17
649 for (k = 0; k < longsPerEU; k++)
650 temp[k] ^= P[k];
651
652 for (k = 0; k < longsPerEU; k++)
653 dest_larger_current[k] = temp[k];
654 #endif
655
656
657
658
659
660
661 for (j = 0; j < numDataCol; j++) {
662 if (j == f1 || j == f2)
663 continue;
664 #if RF_EO_MATRIX_DIM > 17
665 rrdbuf_current = (short *) (rrdbuf[j]) +
666 row * shortsPerEU;
667 for (k = 0; k < shortsPerEU; k++)
668 temp[k] ^= *(rrdbuf_current + k);
669 #elif RF_EO_MATRIX_DIM == 17
670 rrdbuf_current = (long *) (rrdbuf[j]) +
671 row * longsPerEU;
672 for (k = 0; k < longsPerEU; k++)
673 temp[k] ^= *(rrdbuf_current + k);
674 #endif
675 }
676
677
678 #if RF_EO_MATRIX_DIM > 17
679 pbuf_current = (short *) pbuf + shortsPerEU * row;
680 for (k = 0; k < shortsPerEU; k++)
681 temp[k] ^= *(pbuf_current + k);
682 for (k = 0; k < shortsPerEU; k++)
683 dest_smaller_current[k] = temp[k];
684 #elif RF_EO_MATRIX_DIM == 17
685 pbuf_current = (long *) pbuf + longsPerEU * row;
686 for (k = 0; k < longsPerEU; k++)
687 temp[k] ^= *(pbuf_current + k);
688 for (k = 0; k < longsPerEU; k++)
689 dest_smaller_current[k] = temp[k];
690 #endif
691 count++;
692 }
693
694
695
696
697
698 RF_ASSERT(count == numRowInEncMatrix);
699 RF_Free((char *) P, bytesPerEU);
700 RF_Free((char *) temp, bytesPerEU);
701 }
702
703
704
705
706
707 int
708 rf_EvenOddDoubleRecoveryFunc(RF_DagNode_t *node)
709 {
710 int ndataParam = 0;
711 int np = node->numParams;
712 RF_AccessStripeMap_t *asmap = (RF_AccessStripeMap_t *)
713 node->params[np - 1].p;
714 RF_Raid_t *raidPtr = (RF_Raid_t *) node->params[np - 2].p;
715 RF_RaidLayout_t *layoutPtr = (RF_RaidLayout_t *) & (raidPtr->Layout);
716 int i, prm, sector, nresults = node->numResults;
717 RF_SectorCount_t secPerSU = layoutPtr->sectorsPerStripeUnit;
718 unsigned sosAddr;
719 int two = 0, mallc_one = 0, mallc_two = 0;
720
721
722
723 int bytesPerSector = rf_RaidAddressToByte(raidPtr, 1);
724 RF_PhysDiskAddr_t *ppda, *ppda2, *epda, *epda2, *pda, *pda0, *pda1,
725 npda;
726 RF_RowCol_t fcol[2], fsuoff[2], fsuend[2],
727 numDataCol = layoutPtr->numDataCol;
728 char **buf, *ebuf, *pbuf, *dest[2];
729 long *suoff = NULL, *suend = NULL, *prmToCol = NULL, psuoff, esuoff;
730 RF_SectorNum_t startSector, endSector;
731 RF_Etimer_t timer;
732 RF_AccTraceEntry_t *tracerec = node->dagHdr->tracerec;
733
734 RF_ETIMER_START(timer);
735
736
737
738
739
740 for (i = 0; i <= np; i++)
741 if (((RF_PhysDiskAddr_t *) node->params[i].p)->type !=
742 RF_PDA_TYPE_DATA) {
743 ndataParam = i;
744 break;
745 }
746 RF_Malloc(buf, numDataCol * sizeof(char *), (char **));
747 if (ndataParam != 0) {
748 RF_Malloc(suoff, ndataParam * sizeof(long), (long *));
749 RF_Malloc(suend, ndataParam * sizeof(long), (long *));
750 RF_Malloc(prmToCol, ndataParam * sizeof(long), (long *));
751 }
752 if (asmap->failedPDAs[1] &&
753 (asmap->failedPDAs[1]->numSector +
754 asmap->failedPDAs[0]->numSector) < secPerSU) {
755 RF_ASSERT(0);
756 ppda = node->params[np - 6].p;
757 ppda2 = node->params[np - 5].p;
758 RF_ASSERT(ppda2->type == RF_PDA_TYPE_PARITY);
759 epda = node->params[np - 4].p;
760 epda2 = node->params[np - 3].p;
761 RF_ASSERT(epda2->type == RF_PDA_TYPE_Q);
762 two = 1;
763 } else {
764 ppda = node->params[np - 4].p;
765 epda = node->params[np - 3].p;
766 psuoff = rf_StripeUnitOffset(layoutPtr, ppda->startSector);
767 esuoff = rf_StripeUnitOffset(layoutPtr, epda->startSector);
768 RF_ASSERT(psuoff == esuoff);
769 }
770
771
772
773
774
775
776
777
778 if (nresults == 1) {
779
780 pda = node->results[0];
781 bzero(pda->bufPtr, bytesPerSector * pda->numSector);
782 fsuoff[0] = rf_StripeUnitOffset(layoutPtr, pda->startSector);
783 fsuend[0] = fsuoff[0] + pda->numSector;
784 startSector = fsuoff[0];
785 endSector = fsuend[0];
786
787
788 fcol[0] = rf_EUCol(layoutPtr, pda->raidAddress);
789
790
791 sosAddr = rf_RaidAddressOfPrevStripeBoundary(layoutPtr,
792 asmap->raidAddress);
793 for (i = 0; i < numDataCol; i++) {
794 npda.raidAddress = sosAddr + (i * secPerSU);
795 (raidPtr->Layout.map->MapSector) (raidPtr,
796 npda.raidAddress, &(npda.row), &(npda.col),
797 &(npda.startSector), 0);
798
799 if (RF_DEAD_DISK(raidPtr
800 ->Disks[npda.row][npda.col].status))
801 if (i != fcol[0])
802 break;
803 }
804 RF_ASSERT(i < numDataCol);
805 fcol[1] = i;
806 } else {
807 RF_ASSERT(nresults == 2);
808 pda0 = node->results[0];
809 bzero(pda0->bufPtr, bytesPerSector * pda0->numSector);
810 pda1 = node->results[1];
811 bzero(pda1->bufPtr, bytesPerSector * pda1->numSector);
812
813
814
815
816 fcol[0] = rf_EUCol(layoutPtr, pda0->raidAddress);
817 fcol[1] = rf_EUCol(layoutPtr, pda1->raidAddress);
818
819
820
821
822 fsuoff[0] = rf_StripeUnitOffset(layoutPtr, pda0->startSector);
823 fsuend[0] = fsuoff[0] + pda0->numSector;
824 fsuoff[1] = rf_StripeUnitOffset(layoutPtr, pda1->startSector);
825 fsuend[1] = fsuoff[1] + pda1->numSector;
826
827 startSector = RF_MIN(pda0->startSector, pda1->startSector);
828
829 endSector = RF_MAX(fsuend[0], fsuend[1]);
830 }
831
832
833
834
835 for (prm = 0; prm < ndataParam; prm++) {
836 pda = node->params[prm].p;
837 suoff[prm] = rf_StripeUnitOffset(layoutPtr, pda->startSector);
838 suend[prm] = suoff[prm] + pda->numSector;
839 prmToCol[prm] = rf_EUCol(layoutPtr, pda->raidAddress);
840 }
841
842
843
844
845
846
847
848
849
850 for (sector = startSector; sector < endSector; sector++) {
851 if (nresults == 2)
852 if (!(fsuoff[0] <= sector && sector < fsuend[0]) &&
853 !(fsuoff[1] <= sector && sector < fsuend[1]))
854 continue;
855 for (prm = 0; prm < ndataParam; prm++)
856 if (suoff[prm] <= sector && sector < suend[prm])
857 buf[(prmToCol[prm])] = ((RF_PhysDiskAddr_t *)
858 node->params[prm].p)->bufPtr +
859 rf_RaidAddressToByte(raidPtr,
860 sector - suoff[prm]);
861
862
863
864
865
866
867
868 RF_ASSERT(nresults == 1 || nresults == 2);
869 if (nresults == 1) {
870 dest[0] = ((RF_PhysDiskAddr_t *)
871 node->results[0])->bufPtr +
872 rf_RaidAddressToByte(raidPtr, sector - fsuoff[0]);
873
874 RF_Malloc(dest[1], bytesPerSector, (char *));
875 bzero(dest[1], bytesPerSector);
876 mallc_two = 1;
877 } else {
878 if (fsuoff[0] <= sector && sector < fsuend[0])
879 dest[0] = ((RF_PhysDiskAddr_t *)
880 node->results[0])->bufPtr +
881 rf_RaidAddressToByte(raidPtr,
882 sector - fsuoff[0]);
883 else {
884 RF_Malloc(dest[0], bytesPerSector, (char *));
885 bzero(dest[0], bytesPerSector);
886 mallc_one = 1;
887 }
888 if (fsuoff[1] <= sector && sector < fsuend[1])
889 dest[1] = ((RF_PhysDiskAddr_t *)
890 node->results[1])->bufPtr +
891 rf_RaidAddressToByte(raidPtr,
892 sector - fsuoff[1]);
893 else {
894 RF_Malloc(dest[1], bytesPerSector, (char *));
895 bzero(dest[1], bytesPerSector);
896 mallc_two = 1;
897 }
898 RF_ASSERT(mallc_one == 0 || mallc_two == 0);
899 }
900 pbuf = ppda->bufPtr + rf_RaidAddressToByte(raidPtr,
901 sector - psuoff);
902 ebuf = epda->bufPtr + rf_RaidAddressToByte(raidPtr,
903 sector - esuoff);
904
905
906
907
908 rf_doubleEOdecode(raidPtr, buf, dest, fcol, pbuf, ebuf);
909
910
911
912
913 if (mallc_one == 1)
914 RF_Free(dest[0], bytesPerSector);
915 if (mallc_two == 1)
916 RF_Free(dest[1], bytesPerSector);
917 mallc_one = mallc_two = 0;
918 }
919 RF_Free(buf, numDataCol * sizeof(char *));
920 if (ndataParam != 0) {
921 RF_Free(suoff, ndataParam * sizeof(long));
922 RF_Free(suend, ndataParam * sizeof(long));
923 RF_Free(prmToCol, ndataParam * sizeof(long));
924 }
925 RF_ETIMER_STOP(timer);
926 RF_ETIMER_EVAL(timer);
927 if (tracerec) {
928 tracerec->q_us += RF_ETIMER_VAL_US(timer);
929 }
930 rf_GenericWakeupFunc(node, 0);
931 #if 1
932 return (0);
933 #endif
934 }
935
936
937
938
939
940
941
942
943
944 int
945 rf_EOWriteDoubleRecoveryFunc(RF_DagNode_t *node)
946 {
947 int np = node->numParams;
948 RF_AccessStripeMap_t *asmap =
949 (RF_AccessStripeMap_t *) node->params[np - 1].p;
950 RF_Raid_t *raidPtr = (RF_Raid_t *) node->params[np - 2].p;
951 RF_RaidLayout_t *layoutPtr = (RF_RaidLayout_t *) &(raidPtr->Layout);
952 RF_SectorNum_t sector;
953 RF_RowCol_t col, scol;
954 int prm, i, j;
955 RF_SectorCount_t secPerSU = layoutPtr->sectorsPerStripeUnit;
956 unsigned sosAddr;
957 unsigned bytesPerSector = rf_RaidAddressToByte(raidPtr, 1);
958 RF_int64 numbytes;
959 RF_SectorNum_t startSector, endSector;
960 RF_PhysDiskAddr_t *ppda, *epda, *pda, *fpda, npda;
961 RF_RowCol_t fcol[2], numDataCol = layoutPtr->numDataCol;
962 char **buf;
963
964
965
966
967 char *ebuf, *pbuf, *dest[2], *olddata[2];
968 RF_Etimer_t timer;
969 RF_AccTraceEntry_t *tracerec = node->dagHdr->tracerec;
970
971 RF_ASSERT(asmap->numDataFailed == 1);
972
973
974
975
976 RF_ETIMER_START(timer);
977 RF_Malloc(buf, numDataCol * sizeof(char *), (char **));
978
979 ppda = node->results[0];
980
981
982
983
984 epda = node->results[1];
985 fpda = asmap->failedPDAs[0];
986
987
988
989 startSector = rf_StripeUnitOffset(layoutPtr, fpda->startSector);
990 endSector = startSector + fpda->numSector;
991
992
993
994
995 for (prm = 0; prm < numDataCol - 2; prm++) {
996 pda = (RF_PhysDiskAddr_t *) node->params[prm].p;
997 col = rf_EUCol(layoutPtr, pda->raidAddress);
998 buf[col] = pda->bufPtr;
999 }
1000
1001
1002
1003
1004 pbuf = ppda->bufPtr;
1005 ebuf = epda->bufPtr;
1006
1007
1008
1009
1010 fcol[0] = rf_EUCol(layoutPtr, fpda->raidAddress);
1011
1012
1013 sosAddr = rf_RaidAddressOfPrevStripeBoundary(layoutPtr,
1014 asmap->raidAddress);
1015 for (i = 0; i < numDataCol; i++) {
1016 npda.raidAddress = sosAddr + (i * secPerSU);
1017 (raidPtr->Layout.map->MapSector) (raidPtr, npda.raidAddress,
1018 &(npda.row), &(npda.col), &(npda.startSector), 0);
1019
1020 if (RF_DEAD_DISK(raidPtr->Disks[npda.row][npda.col].status))
1021 if (i != fcol[0])
1022 break;
1023 }
1024 RF_ASSERT(i < numDataCol);
1025 fcol[1] = i;
1026
1027 numbytes = fpda->numSector * bytesPerSector;
1028 RF_Malloc(olddata[0], numbytes, (char *));
1029 RF_Malloc(olddata[1], numbytes, (char *));
1030 dest[0] = olddata[0];
1031 dest[1] = olddata[1];
1032 bzero(olddata[0], numbytes);
1033 bzero(olddata[1], numbytes);
1034
1035
1036
1037
1038
1039 for (sector = startSector, i = 0; sector < endSector; sector++, i++) {
1040 rf_doubleEOdecode(raidPtr, buf, dest, fcol, pbuf, ebuf);
1041 for (j = 0; j < numDataCol; j++)
1042 if ((j != fcol[0]) && (j != fcol[1]))
1043 buf[j] += bytesPerSector;
1044 dest[0] += bytesPerSector;
1045 dest[1] += bytesPerSector;
1046 ebuf += bytesPerSector;
1047 pbuf += bytesPerSector;
1048 }
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068 rf_bxor(((RF_PhysDiskAddr_t *) node->params[numDataCol].p)->bufPtr,
1069 olddata[0], numbytes, node->dagHdr->bp);
1070
1071
1072
1073
1074
1075 scol = rf_EUCol(layoutPtr, fpda->raidAddress);
1076
1077
1078
1079
1080 rf_e_encToBuf(raidPtr, scol, olddata[0], RF_EO_MATRIX_DIM - 2,
1081 epda->bufPtr, fpda->numSector);
1082
1083
1084 rf_bxor(olddata[0], ppda->bufPtr, numbytes, node->dagHdr->bp);
1085
1086 RF_Free(olddata[0], numbytes);
1087 RF_Free(olddata[1], numbytes);
1088 RF_Free(buf, numDataCol * sizeof(char *));
1089
1090 RF_ETIMER_STOP(timer);
1091 RF_ETIMER_EVAL(timer);
1092 if (tracerec) {
1093 tracerec->q_us += RF_ETIMER_VAL_US(timer);
1094 }
1095 rf_GenericWakeupFunc(node, 0);
1096 return (0);
1097 }