This source file includes following definitions.
- rf_RegularONPFunc
- rf_SimpleONPFunc
- rf_RecoveryPFunc
- rf_RegularPFunc
- rf_PQDagSelect
- rf_PQOne
- rf_PQOneTwo
- RF_CREATE_DAG_FUNC_DECL
- rf_RegularONQFunc
- rf_SimpleONQFunc
- RF_CREATE_DAG_FUNC_DECL
- rf_RegularQSubr
- rf_DegrQSubr
- rf_RegularPQFunc
- rf_RegularQFunc
- rf_Degraded_100_PQFunc
- rf_RecoveryQFunc
- rf_RecoveryPQFunc
- rf_PQ_DegradedWriteQFunc
- rf_IncQ
- rf_QDelta
- rf_PQ_recover
- rf_InvertQ
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_archs.h"
36 #include "rf_types.h"
37 #include "rf_raid.h"
38 #include "rf_dag.h"
39 #include "rf_dagffrd.h"
40 #include "rf_dagffwr.h"
41 #include "rf_dagdegrd.h"
42 #include "rf_dagdegwr.h"
43 #include "rf_dagutils.h"
44 #include "rf_dagfuncs.h"
45 #include "rf_etimer.h"
46 #include "rf_pqdeg.h"
47 #include "rf_general.h"
48 #include "rf_map.h"
49 #include "rf_pq.h"
50
51 RF_RedFuncs_t rf_pFuncs = {
52 rf_RegularONPFunc, "Regular Old-New P",
53 rf_SimpleONPFunc, "Simple Old-New P"
54 };
55 RF_RedFuncs_t rf_pRecoveryFuncs = {
56 rf_RecoveryPFunc, "Recovery P Func",
57 rf_RecoveryPFunc, "Recovery P Func"
58 };
59
60 int
61 rf_RegularONPFunc(RF_DagNode_t *node)
62 {
63 return (rf_RegularXorFunc(node));
64 }
65
66
67
68
69
70
71 int
72 rf_SimpleONPFunc(RF_DagNode_t *node)
73 {
74 return (rf_SimpleXorFunc(node));
75 }
76
77 int
78 rf_RecoveryPFunc(RF_DagNode_t *node)
79 {
80 return (rf_RecoveryXorFunc(node));
81 }
82
83 int
84 rf_RegularPFunc(RF_DagNode_t *node)
85 {
86 return (rf_RegularXorFunc(node));
87 }
88
89
90 #if (RF_INCLUDE_DECL_PQ > 0) || (RF_INCLUDE_RAID6 > 0)
91
92 void rf_QDelta(char *dest, char *obuf, char *nbuf, unsigned length,
93 unsigned char coeff);
94 void rf_InvertQ(unsigned long *qbuf, unsigned long *abuf, unsigned length,
95 unsigned coeff);
96
97 RF_RedFuncs_t rf_qFuncs = {
98 rf_RegularONQFunc, "Regular Old-New Q",
99 rf_SimpleONQFunc, "Simple Old-New Q"
100 };
101 RF_RedFuncs_t rf_qRecoveryFuncs = {
102 rf_RecoveryQFunc, "Recovery Q Func",
103 rf_RecoveryQFunc, "Recovery Q Func"
104 };
105 RF_RedFuncs_t rf_pqRecoveryFuncs = {
106 rf_RecoveryPQFunc, "Recovery PQ Func",
107 rf_RecoveryPQFunc, "Recovery PQ Func"
108 };
109
110 void
111 rf_PQDagSelect(RF_Raid_t *raidPtr, RF_IoType_t type,
112 RF_AccessStripeMap_t *asmap, RF_VoidFuncPtr *createFunc)
113 {
114 RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout);
115 unsigned ndfail = asmap->numDataFailed;
116 unsigned npfail = asmap->numParityFailed;
117 unsigned ntfail = npfail + ndfail;
118
119 RF_ASSERT(RF_IO_IS_R_OR_W(type));
120 if (ntfail > 2) {
121 RF_ERRORMSG("more than two disks failed in a single group !"
122 " Aborting I/O operation.\n");
123 *createFunc = NULL;
124 return;
125 }
126
127 if (type == RF_IO_TYPE_READ) {
128 switch (ndfail) {
129 case 0:
130
131 *createFunc = (RF_VoidFuncPtr)
132 rf_CreateFaultFreeReadDAG;
133 break;
134 case 1:
135
136
137
138
139
140
141
142 if (ntfail == 2) {
143 if (asmap->failedPDAs[1]->type ==
144 RF_PDA_TYPE_PARITY)
145 *createFunc = (RF_VoidFuncPtr)
146 rf_PQ_110_CreateReadDAG;
147 else
148 *createFunc = (RF_VoidFuncPtr)
149 rf_PQ_101_CreateReadDAG;
150 } else {
151
152
153
154
155 if (rf_NumFailedDataUnitsInStripe(raidPtr,
156 asmap) == 2)
157 *createFunc = (RF_VoidFuncPtr)
158 rf_PQ_200_CreateReadDAG;
159 else
160 *createFunc = (RF_VoidFuncPtr)
161 rf_PQ_100_CreateReadDAG;
162 }
163 break;
164 case 2:
165
166
167 *createFunc = (RF_VoidFuncPtr) rf_PQ_200_CreateReadDAG;
168 break;
169 }
170 return;
171 }
172
173 switch (ntfail) {
174 case 0:
175 if (rf_suppressLocksAndLargeWrites ||
176 (((asmap->numStripeUnitsAccessed <=
177 (layoutPtr->numDataCol / 2)) &&
178 (layoutPtr->numDataCol != 1)) ||
179 (asmap->parityInfo->next != NULL) ||
180 (asmap->qInfo->next != NULL) ||
181 rf_CheckStripeForFailures(raidPtr, asmap))) {
182
183 *createFunc = (RF_VoidFuncPtr) rf_PQCreateSmallWriteDAG;
184 } else {
185 *createFunc = (RF_VoidFuncPtr) rf_PQCreateLargeWriteDAG;
186 }
187 break;
188
189 case 1:
190 if (npfail == 1) {
191 RF_ASSERT((asmap->failedPDAs[0]->type ==
192 RF_PDA_TYPE_PARITY) ||
193 (asmap->failedPDAs[0]->type == RF_PDA_TYPE_Q));
194 if (asmap->failedPDAs[0]->type == RF_PDA_TYPE_Q) {
195
196
197
198 if (((asmap->numStripeUnitsAccessed <=
199 (layoutPtr->numDataCol / 2)) ||
200 (asmap->numStripeUnitsAccessed == 1)) ||
201 rf_NumFailedDataUnitsInStripe(raidPtr,
202 asmap))
203 *createFunc = (RF_VoidFuncPtr)
204 rf_PQ_001_CreateSmallWriteDAG;
205 else
206 *createFunc = (RF_VoidFuncPtr)
207 rf_PQ_001_CreateLargeWriteDAG;
208 } else {
209 if (((asmap->numStripeUnitsAccessed <=
210 (layoutPtr->numDataCol / 2)) ||
211 (asmap->numStripeUnitsAccessed == 1)) ||
212 rf_NumFailedDataUnitsInStripe(raidPtr,
213 asmap))
214 *createFunc = (RF_VoidFuncPtr)
215 rf_PQ_010_CreateSmallWriteDAG;
216 else
217 *createFunc = (RF_VoidFuncPtr)
218 rf_PQ_010_CreateLargeWriteDAG;
219 }
220 } else {
221
222
223
224
225 if (rf_NumFailedDataUnitsInStripe(raidPtr, asmap) == 2)
226 *createFunc = (RF_VoidFuncPtr)
227 rf_PQ_200_CreateWriteDAG;
228 else
229 *createFunc = (RF_VoidFuncPtr)
230 rf_PQ_100_CreateWriteDAG;
231 }
232 break;
233
234 case 2:
235 switch (npfail) {
236 case 2:
237 *createFunc = (RF_VoidFuncPtr) rf_PQ_011_CreateWriteDAG;
238 break;
239 case 1:
240 RF_ASSERT(asmap->failedPDAs[0]->type ==
241 RF_PDA_TYPE_DATA);
242 RF_ASSERT((asmap->failedPDAs[1]->type ==
243 RF_PDA_TYPE_PARITY) ||
244 (asmap->failedPDAs[1]->type ==
245 RF_PDA_TYPE_Q));
246 if (asmap->failedPDAs[1]->type == RF_PDA_TYPE_Q)
247 *createFunc = (RF_VoidFuncPtr)
248 rf_PQ_101_CreateWriteDAG;
249 else
250 *createFunc = (RF_VoidFuncPtr)
251 rf_PQ_110_CreateWriteDAG;
252 break;
253 case 0:
254 *createFunc = (RF_VoidFuncPtr) rf_PQ_200_CreateWriteDAG;
255 break;
256 }
257 break;
258
259 default:
260 *createFunc = NULL;
261 RF_PANIC();
262 }
263 return;
264 }
265
266
267
268
269
270 #if 0
271 void
272 rf_PQOne(RF_Raid_t *raidPtr, int *nSucc, int *nAnte,
273 RF_AccessStripeMap_t *asmap)
274 {
275 *nSucc = *nAnte = 1;
276 }
277
278 void
279 rf_PQOneTwo(RF_Raid_t *raidPtr, int *nSucc, int *nAnte,
280 RF_AccessStripeMap_t *asmap)
281 {
282 *nSucc = 1;
283 *nAnte = 2;
284 }
285 #endif
286
287 RF_CREATE_DAG_FUNC_DECL(rf_PQCreateLargeWriteDAG)
288 {
289 rf_CommonCreateLargeWriteDAG(raidPtr, asmap, dag_h, bp, flags,
290 allocList, 2, rf_RegularPQFunc, RF_FALSE);
291 }
292
293 int
294 rf_RegularONQFunc(RF_DagNode_t *node)
295 {
296 int np = node->numParams;
297 int d;
298 RF_Raid_t *raidPtr = (RF_Raid_t *) node->params[np - 1].p;
299 int i;
300 RF_AccTraceEntry_t *tracerec = node->dagHdr->tracerec;
301 RF_Etimer_t timer;
302 char *qbuf, *qpbuf;
303 char *obuf, *nbuf;
304 RF_PhysDiskAddr_t *old, *new;
305 unsigned long coeff;
306 unsigned secPerSU = raidPtr->Layout.sectorsPerStripeUnit;
307
308 RF_ETIMER_START(timer);
309
310 d = (np - 3) / 4;
311 RF_ASSERT(4 * d + 3 == np);
312 qbuf = (char *) node->params[2 * d + 1].p;
313 for (i = 0; i < d; i++) {
314 old = (RF_PhysDiskAddr_t *) node->params[2 * i].p;
315 obuf = (char *) node->params[2 * i + 1].p;
316 new = (RF_PhysDiskAddr_t *) node->params[2 * (d + 1 + i)].p;
317 nbuf = (char *) node->params[2 * (d + 1 + i) + 1].p;
318 RF_ASSERT(new->numSector == old->numSector);
319 RF_ASSERT(new->raidAddress == old->raidAddress);
320
321
322
323
324 coeff = rf_RaidAddressToStripeUnitID(&(raidPtr->Layout),
325 new->raidAddress);
326
327
328
329
330 coeff = (coeff % raidPtr->Layout.numDataCol);
331 qpbuf = qbuf + rf_RaidAddressToByte(raidPtr,
332 old->startSector % secPerSU);
333 rf_QDelta(qpbuf, obuf, nbuf, rf_RaidAddressToByte(raidPtr,
334 old->numSector), coeff);
335 }
336
337 RF_ETIMER_STOP(timer);
338 RF_ETIMER_EVAL(timer);
339 tracerec->q_us += RF_ETIMER_VAL_US(timer);
340 rf_GenericWakeupFunc(node, 0);
341
342
343
344 return (0);
345 }
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366 int
367 rf_SimpleONQFunc(RF_DagNode_t *node)
368 {
369 int np = node->numParams;
370 int d;
371 RF_Raid_t *raidPtr = (RF_Raid_t *) node->params[np - 1].p;
372 int i;
373 RF_AccTraceEntry_t *tracerec = node->dagHdr->tracerec;
374 RF_Etimer_t timer;
375 char *qbuf;
376 char *obuf, *nbuf;
377 RF_PhysDiskAddr_t *old, *new;
378 unsigned long coeff;
379
380 RF_ETIMER_START(timer);
381
382 d = (np - 3) / 4;
383 RF_ASSERT(4 * d + 3 == np);
384 qbuf = (char *) node->params[2 * d + 1].p;
385 for (i = 0; i < d; i++) {
386 old = (RF_PhysDiskAddr_t *) node->params[2 * i].p;
387 obuf = (char *) node->params[2 * i + 1].p;
388 new = (RF_PhysDiskAddr_t *) node->params[2 * (d + 1 + i)].p;
389 nbuf = (char *) node->params[2 * (d + 1 + i) + 1].p;
390 RF_ASSERT(new->numSector == old->numSector);
391 RF_ASSERT(new->raidAddress == old->raidAddress);
392
393
394
395
396 coeff = rf_RaidAddressToStripeUnitID(&(raidPtr->Layout),
397 new->raidAddress);
398
399
400
401
402 coeff = (coeff % raidPtr->Layout.numDataCol);
403 rf_QDelta(qbuf, obuf, nbuf, rf_RaidAddressToByte(raidPtr,
404 old->numSector), coeff);
405 }
406
407 RF_ETIMER_STOP(timer);
408 RF_ETIMER_EVAL(timer);
409 tracerec->q_us += RF_ETIMER_VAL_US(timer);
410 rf_GenericWakeupFunc(node, 0);
411
412
413
414 return (0);
415 }
416
417 RF_CREATE_DAG_FUNC_DECL(rf_PQCreateSmallWriteDAG)
418 {
419 rf_CommonCreateSmallWriteDAG(raidPtr, asmap, dag_h, bp, flags,
420 allocList, &rf_pFuncs, &rf_qFuncs);
421 }
422
423
424 void rf_RegularQSubr(RF_DagNode_t *, char *);
425
426 void
427 rf_RegularQSubr(RF_DagNode_t *node, char *qbuf)
428 {
429 int np = node->numParams;
430 int d;
431 RF_Raid_t *raidPtr = (RF_Raid_t *) node->params[np - 1].p;
432 unsigned secPerSU = raidPtr->Layout.sectorsPerStripeUnit;
433 int i;
434 RF_AccTraceEntry_t *tracerec = node->dagHdr->tracerec;
435 RF_Etimer_t timer;
436 char *obuf, *qpbuf;
437 RF_PhysDiskAddr_t *old;
438 unsigned long coeff;
439
440 RF_ETIMER_START(timer);
441
442 d = (np - 1) / 2;
443 RF_ASSERT(2 * d + 1 == np);
444 for (i = 0; i < d; i++) {
445 old = (RF_PhysDiskAddr_t *) node->params[2 * i].p;
446 obuf = (char *) node->params[2 * i + 1].p;
447 coeff = rf_RaidAddressToStripeUnitID(&(raidPtr->Layout),
448 old->raidAddress);
449
450
451
452
453 coeff = (coeff % raidPtr->Layout.numDataCol);
454
455
456
457
458
459 qpbuf = qbuf + rf_RaidAddressToByte(raidPtr,
460 old->startSector % secPerSU);
461 rf_IncQ((unsigned long *) qpbuf, (unsigned long *) obuf,
462 rf_RaidAddressToByte(raidPtr, old->numSector), coeff);
463 }
464
465 RF_ETIMER_STOP(timer);
466 RF_ETIMER_EVAL(timer);
467 tracerec->q_us += RF_ETIMER_VAL_US(timer);
468 }
469
470
471
472
473
474
475 void rf_DegrQSubr(RF_DagNode_t *);
476
477 void
478 rf_DegrQSubr(RF_DagNode_t *node)
479 {
480 int np = node->numParams;
481 int d;
482 RF_Raid_t *raidPtr = (RF_Raid_t *) node->params[np - 1].p;
483 unsigned secPerSU = raidPtr->Layout.sectorsPerStripeUnit;
484 RF_AccTraceEntry_t *tracerec = node->dagHdr->tracerec;
485 RF_Etimer_t timer;
486 char *qbuf = node->results[1];
487 char *obuf, *qpbuf;
488 RF_PhysDiskAddr_t *old;
489 unsigned long coeff;
490 unsigned fail_start;
491 int i, j;
492
493 old = (RF_PhysDiskAddr_t *) node->params[np - 2].p;
494 fail_start = old->startSector % secPerSU;
495
496 RF_ETIMER_START(timer);
497
498 d = (np - 2) / 2;
499 RF_ASSERT(2 * d + 2 == np);
500 for (i = 0; i < d; i++) {
501 old = (RF_PhysDiskAddr_t *) node->params[2 * i].p;
502 obuf = (char *) node->params[2 * i + 1].p;
503 coeff = rf_RaidAddressToStripeUnitID(&(raidPtr->Layout),
504 old->raidAddress);
505
506
507
508
509 coeff = (coeff % raidPtr->Layout.numDataCol);
510
511
512
513
514
515 j = old->startSector % secPerSU;
516 RF_ASSERT(j >= fail_start);
517 qpbuf = qbuf + rf_RaidAddressToByte(raidPtr, j - fail_start);
518 rf_IncQ((unsigned long *) qpbuf, (unsigned long *) obuf,
519 rf_RaidAddressToByte(raidPtr, old->numSector), coeff);
520 }
521
522 RF_ETIMER_STOP(timer);
523 RF_ETIMER_EVAL(timer);
524 tracerec->q_us += RF_ETIMER_VAL_US(timer);
525 }
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545 int
546 rf_RegularPQFunc(RF_DagNode_t *node)
547 {
548 rf_RegularQSubr(node, node->results[1]);
549 return (rf_RegularXorFunc(node));
550 }
551
552 int
553 rf_RegularQFunc(RF_DagNode_t *node)
554 {
555
556 rf_RegularQSubr(node, node->results[0]);
557 rf_GenericWakeupFunc(node, 0);
558
559
560
561 return (0);
562 }
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586 void
587 rf_Degraded_100_PQFunc(RF_DagNode_t *node)
588 {
589 int np = node->numParams;
590
591 RF_ASSERT(np >= 2);
592 rf_DegrQSubr(node);
593 rf_RecoveryXorFunc(node);
594 }
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629 int
630 rf_RecoveryQFunc(RF_DagNode_t *node)
631 {
632 RF_Raid_t *raidPtr = (RF_Raid_t *) node->params[node->numParams - 1].p;
633 RF_RaidLayout_t *layoutPtr = (RF_RaidLayout_t *) & raidPtr->Layout;
634 RF_PhysDiskAddr_t *failedPDA =
635 (RF_PhysDiskAddr_t *) node->params[node->numParams - 2].p;
636 int i;
637 RF_PhysDiskAddr_t *pda;
638 RF_RaidAddr_t suoffset;
639 RF_RaidAddr_t failedSUOffset =
640 rf_StripeUnitOffset(layoutPtr, failedPDA->startSector);
641 char *srcbuf, *destbuf;
642 RF_AccTraceEntry_t *tracerec = node->dagHdr->tracerec;
643 RF_Etimer_t timer;
644 unsigned long coeff;
645
646 RF_ETIMER_START(timer);
647
648 bcopy(node->params[node->numParams - 3].p, node->results[0],
649 rf_RaidAddressToByte(raidPtr, failedPDA->numSector));
650 for (i = 0; i < node->numParams - 4; i += 2) {
651 RF_ASSERT(node->params[i + 1].p != node->results[0]);
652 pda = (RF_PhysDiskAddr_t *) node->params[i].p;
653 srcbuf = (char *) node->params[i + 1].p;
654 suoffset = rf_StripeUnitOffset(layoutPtr, pda->startSector);
655 destbuf = ((char *) node->results[0]) +
656 rf_RaidAddressToByte(raidPtr, suoffset - failedSUOffset);
657 coeff = rf_RaidAddressToStripeUnitID(&(raidPtr->Layout),
658 pda->raidAddress);
659
660 coeff = (coeff % raidPtr->Layout.numDataCol);
661 rf_IncQ((unsigned long *) destbuf, (unsigned long *) srcbuf,
662 rf_RaidAddressToByte(raidPtr, pda->numSector), coeff);
663 }
664
665 coeff = (rf_RaidAddressToStripeUnitID(&(raidPtr->Layout),
666 failedPDA->startSector) % raidPtr->Layout.numDataCol);
667 rf_InvertQ(node->results[0], node->results[0],
668 rf_RaidAddressToByte(raidPtr, pda->numSector), coeff);
669 RF_ETIMER_STOP(timer);
670 RF_ETIMER_EVAL(timer);
671 tracerec->q_us += RF_ETIMER_VAL_US(timer);
672 rf_GenericWakeupFunc(node, 0);
673 return (0);
674 }
675
676 int
677 rf_RecoveryPQFunc(RF_DagNode_t *node)
678 {
679 RF_Raid_t *raidPtr = (RF_Raid_t *) node->params[node->numParams - 1].p;
680 printf("raid%d: Recovery from PQ not implemented.\n", raidPtr->raidid);
681 return (1);
682 }
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698 void
699 rf_PQ_DegradedWriteQFunc(RF_DagNode_t *node)
700 {
701 int np = node->numParams;
702 int d;
703 RF_Raid_t *raidPtr = (RF_Raid_t *) node->params[np - 1].p;
704 unsigned secPerSU = raidPtr->Layout.sectorsPerStripeUnit;
705 RF_AccTraceEntry_t *tracerec = node->dagHdr->tracerec;
706 RF_Etimer_t timer;
707 char *qbuf = node->results[0];
708 char *obuf, *qpbuf;
709 RF_PhysDiskAddr_t *old;
710 unsigned long coeff;
711 int fail_start, i, j;
712
713 old = (RF_PhysDiskAddr_t *) node->params[np - 2].p;
714 fail_start = old->startSector % secPerSU;
715
716 RF_ETIMER_START(timer);
717
718 d = (np - 2) / 2;
719 RF_ASSERT(2 * d + 2 == np);
720
721 for (i = 0; i < d; i++) {
722 old = (RF_PhysDiskAddr_t *) node->params[2 * i].p;
723 obuf = (char *) node->params[2 * i + 1].p;
724 coeff = rf_RaidAddressToStripeUnitID(&(raidPtr->Layout),
725 old->raidAddress);
726
727
728
729
730 coeff = (coeff % raidPtr->Layout.numDataCol);
731 j = old->startSector % secPerSU;
732 RF_ASSERT(j >= fail_start);
733 qpbuf = qbuf + rf_RaidAddressToByte(raidPtr, j - fail_start);
734 rf_IncQ((unsigned long *) qpbuf, (unsigned long *) obuf,
735 rf_RaidAddressToByte(raidPtr, old->numSector), coeff);
736 }
737
738 RF_ETIMER_STOP(timer);
739 RF_ETIMER_EVAL(timer);
740 tracerec->q_us += RF_ETIMER_VAL_US(timer);
741 rf_GenericWakeupFunc(node, 0);
742 }
743
744
745
746
747
748
749
750
751
752
753
754
755
756 void
757 rf_IncQ(unsigned long *dest, unsigned long *buf, unsigned length,
758 unsigned coeff)
759 {
760 unsigned long a, d, new;
761 unsigned long a1, a2;
762 unsigned int *q = &(rf_qfor[28 - coeff][0]);
763 unsigned r = rf_rn[coeff + 1];
764
765 #define EXTRACT(a,i) ((a >> (5L*i)) & 0x1f)
766 #define INSERT(a,i) (a << (5L*i))
767
768 length /= 8;
769
770 while (length) {
771 a = *buf++;
772 d = *dest;
773 a1 = EXTRACT(a, 0) ^ r;
774 a2 = EXTRACT(a, 1) ^ r;
775 new = INSERT(a2, 1) | a1;
776 a1 = EXTRACT(a, 2) ^ r;
777 a2 = EXTRACT(a, 3) ^ r;
778 a1 = q[a1];
779 a2 = q[a2];
780 new = new | INSERT(a1, 2) | INSERT(a2, 3);
781 a1 = EXTRACT(a, 4) ^ r;
782 a2 = EXTRACT(a, 5) ^ r;
783 a1 = q[a1];
784 a2 = q[a2];
785 new = new | INSERT(a1, 4) | INSERT(a2, 5);
786 a1 = EXTRACT(a, 5) ^ r;
787 a2 = EXTRACT(a, 6) ^ r;
788 a1 = q[a1];
789 a2 = q[a2];
790 new = new | INSERT(a1, 5) | INSERT(a2, 6);
791 #if RF_LONGSHIFT > 2
792 a1 = EXTRACT(a, 7) ^ r;
793 a2 = EXTRACT(a, 8) ^ r;
794 a1 = q[a1];
795 a2 = q[a2];
796 new = new | INSERT(a1, 7) | INSERT(a2, 8);
797 a1 = EXTRACT(a, 9) ^ r;
798 a2 = EXTRACT(a, 10) ^ r;
799 a1 = q[a1];
800 a2 = q[a2];
801 new = new | INSERT(a1, 9) | INSERT(a2, 10);
802 a1 = EXTRACT(a, 11) ^ r;
803 a2 = EXTRACT(a, 12) ^ r;
804 a1 = q[a1];
805 a2 = q[a2];
806 new = new | INSERT(a1, 11) | INSERT(a2, 12);
807 #endif
808 d ^= new;
809 *dest++ = d;
810 length--;
811 }
812 }
813
814
815
816
817
818
819
820
821
822
823
824
825
826 void
827 rf_QDelta(char *dest, char *obuf, char *nbuf, unsigned length,
828 unsigned char coeff)
829 {
830 unsigned long a, d, new;
831 unsigned long a1, a2;
832 unsigned int *q = &(rf_qfor[28 - coeff][0]);
833 unsigned int r = rf_rn[coeff + 1];
834
835 r = a1 = a2 = new = d = a = 0;
836 q = NULL;
837
838 #ifdef _KERNEL
839
840
841
842
843 bzero(dest, length);
844 #else
845
846
847 length /= 8;
848 while (length) {
849 a = *obuf++;
850
851
852 a ^= *nbuf++;
853 d = *dest;
854 a1 = EXTRACT(a, 0) ^ r;
855 a2 = EXTRACT(a, 1) ^ r;
856 a1 = q[a1];
857 a2 = q[a2];
858 new = INSERT(a2, 1) | a1;
859 a1 = EXTRACT(a, 2) ^ r;
860 a2 = EXTRACT(a, 3) ^ r;
861 a1 = q[a1];
862 a2 = q[a2];
863 new = new | INSERT(a1, 2) | INSERT(a2, 3);
864 a1 = EXTRACT(a, 4) ^ r;
865 a2 = EXTRACT(a, 5) ^ r;
866 a1 = q[a1];
867 a2 = q[a2];
868 new = new | INSERT(a1, 4) | INSERT(a2, 5);
869 a1 = EXTRACT(a, 5) ^ r;
870 a2 = EXTRACT(a, 6) ^ r;
871 a1 = q[a1];
872 a2 = q[a2];
873 new = new | INSERT(a1, 5) | INSERT(a2, 6);
874 #if RF_LONGSHIFT > 2
875 a1 = EXTRACT(a, 7) ^ r;
876 a2 = EXTRACT(a, 8) ^ r;
877 a1 = q[a1];
878 a2 = q[a2];
879 new = new | INSERT(a1, 7) | INSERT(a2, 8);
880 a1 = EXTRACT(a, 9) ^ r;
881 a2 = EXTRACT(a, 10) ^ r;
882 a1 = q[a1];
883 a2 = q[a2];
884 new = new | INSERT(a1, 9) | INSERT(a2, 10);
885 a1 = EXTRACT(a, 11) ^ r;
886 a2 = EXTRACT(a, 12) ^ r;
887 a1 = q[a1];
888 a2 = q[a2];
889 new = new | INSERT(a1, 11) | INSERT(a2, 12);
890 #endif
891 d ^= new;
892 *dest++ = d;
893 length--;
894 }
895 #endif
896 }
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911 void
912 rf_PQ_recover(unsigned long *pbuf, unsigned long *qbuf, unsigned long *abuf,
913 unsigned long *bbuf, unsigned length, unsigned coeff_a, unsigned coeff_b)
914 {
915 unsigned long p, q, a, a0, a1;
916 int col = (29 * coeff_a) + coeff_b;
917 unsigned char *q0 = &(rf_qinv[col][0]);
918
919 length /= 8;
920 while (length) {
921 p = *pbuf++;
922 q = *qbuf++;
923 a0 = EXTRACT(p, 0);
924 a1 = EXTRACT(q, 0);
925 a = q0[a0 << 5 | a1];
926
927 #define MF(i) \
928 do { \
929 a0 = EXTRACT(p, i); \
930 a1 = EXTRACT(q, i); \
931 a = a | INSERT(q0[a0<<5 | a1], i); \
932 } while (0)
933
934 MF(1);
935 MF(2);
936 MF(3);
937 MF(4);
938 MF(5);
939 MF(6);
940 #if 0
941 MF(7);
942 MF(8);
943 MF(9);
944 MF(10);
945 MF(11);
946 MF(12);
947 #endif
948 *abuf++ = a;
949 *bbuf++ = a ^ p;
950 length--;
951 }
952 }
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973 void
974 rf_InvertQ(unsigned long *qbuf, unsigned long *abuf, unsigned length,
975 unsigned coeff)
976 {
977 unsigned long a, new;
978 unsigned long a1, a2;
979 unsigned int *q = &(rf_qfor[3 + coeff][0]);
980 unsigned r = rf_rn[coeff + 1];
981
982
983 length /= 8;
984 while (length) {
985 a = *qbuf++;
986 a1 = EXTRACT(a, 0);
987 a2 = EXTRACT(a, 1);
988 a1 = r ^ q[a1];
989 a2 = r ^ q[a2];
990 new = INSERT(a2, 1) | a1;
991
992 #define M(i,j) \
993 do { \
994 a1 = EXTRACT(a, i); \
995 a2 = EXTRACT(a, j); \
996 a1 = r ^ q[a1]; \
997 a2 = r ^ q[a2]; \
998 new = new | INSERT(a1, i) | INSERT(a2, j); \
999 } while (0)
1000
1001 M(2, 3);
1002 M(4, 5);
1003 M(5, 6);
1004 #if RF_LONGSHIFT > 2
1005 M(7, 8);
1006 M(9, 10);
1007 M(11, 12);
1008 #endif
1009 *abuf++ = new;
1010 length--;
1011 }
1012 }
1013 #endif