This source file includes following definitions.
- RF_CREATE_DAG_FUNC_DECL
- rf_applyPDA
- rf_PQDoubleRecoveryFunc
- rf_PQWriteDoubleRecoveryFunc
- RF_CREATE_DAG_FUNC_DECL
- RF_CREATE_DAG_FUNC_DECL
- RF_CREATE_DAG_FUNC_DECL
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
36
37 #include "rf_archs.h"
38
39 #if (RF_INCLUDE_DECL_PQ > 0) || (RF_INCLUDE_RAID6 > 0)
40
41 #include "rf_types.h"
42 #include "rf_raid.h"
43 #include "rf_dag.h"
44 #include "rf_dagdegrd.h"
45 #include "rf_dagdegwr.h"
46 #include "rf_dagfuncs.h"
47 #include "rf_dagutils.h"
48 #include "rf_etimer.h"
49 #include "rf_acctrace.h"
50 #include "rf_general.h"
51 #include "rf_pqdegdags.h"
52 #include "rf_pq.h"
53
54 void rf_applyPDA(RF_Raid_t *, RF_PhysDiskAddr_t *, RF_PhysDiskAddr_t *,
55 RF_PhysDiskAddr_t *, void *);
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102 #define INIT_DISK_NODE(node,name) \
103 do { \
104 rf_InitNode(node, rf_wait, RF_FALSE, rf_DiskReadFunc, \
105 rf_DiskReadUndoFunc, rf_GenericWakeupFunc, 2, 1, 4, 0, \
106 dag_h, name, allocList); \
107 (node)->succedents[0] = unblockNode; \
108 (node)->succedents[1] = recoveryNode; \
109 (node)->antecedents[0] = blockNode; \
110 (node)->antType[0] = rf_control; \
111 } while (0)
112
113 #define DISK_NODE_PARAMS(_node_,_p_) \
114 do { \
115 (_node_).params[0].p = _p_ ; \
116 (_node_).params[1].p = (_p_)->bufPtr; \
117 (_node_).params[2].v = parityStripeID; \
118 (_node_).params[3].v = RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY, \
119 0, 0, which_ru); \
120 } while (0)
121
122 #define DISK_NODE_PDA(node) ((node)->params[0].p)
123
124 RF_CREATE_DAG_FUNC_DECL(rf_PQ_DoubleDegRead)
125 {
126 rf_DoubleDegRead(raidPtr, asmap, dag_h, bp, flags, allocList,
127 "Rq", "PQ Recovery", rf_PQDoubleRecoveryFunc);
128 }
129
130 void
131 rf_applyPDA(RF_Raid_t *raidPtr, RF_PhysDiskAddr_t *pda,
132 RF_PhysDiskAddr_t *ppda, RF_PhysDiskAddr_t *qpda, void *bp)
133 {
134 RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout);
135 RF_RaidAddr_t s0off = rf_StripeUnitOffset(layoutPtr, ppda->startSector);
136 RF_SectorCount_t s0len = ppda->numSector, len;
137 RF_SectorNum_t suoffset;
138 unsigned coeff;
139 char *pbuf = ppda->bufPtr;
140 char *qbuf = qpda->bufPtr;
141 char *buf;
142 int delta;
143
144 suoffset = rf_StripeUnitOffset(layoutPtr, pda->startSector);
145 len = pda->numSector;
146
147 if ((suoffset < s0off + s0len) && (suoffset + len > s0off)) {
148 buf = pda->bufPtr;
149 coeff = rf_RaidAddressToStripeUnitID(&(raidPtr->Layout),
150 pda->raidAddress);
151 coeff = (coeff % raidPtr->Layout.numDataCol);
152
153 if (suoffset < s0off) {
154 delta = s0off - suoffset;
155 buf += rf_RaidAddressToStripeUnitID(&(raidPtr->Layout),
156 delta);
157 suoffset = s0off;
158 len -= delta;
159 }
160 if (suoffset > s0off) {
161 delta = suoffset - s0off;
162 pbuf += rf_RaidAddressToStripeUnitID(&(raidPtr->Layout),
163 delta);
164 qbuf += rf_RaidAddressToStripeUnitID(&(raidPtr->Layout),
165 delta);
166 }
167 if ((suoffset + len) > (s0len + s0off))
168 len = s0len + s0off - suoffset;
169
170
171 rf_bxor(buf, pbuf, rf_RaidAddressToByte(raidPtr, len), bp);
172
173
174 rf_IncQ((unsigned long *) qbuf, (unsigned long *) buf,
175 rf_RaidAddressToByte(raidPtr, len), coeff);
176 }
177 }
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199 int
200 rf_PQDoubleRecoveryFunc(RF_DagNode_t *node)
201 {
202 int np = node->numParams;
203 RF_AccessStripeMap_t *asmap =
204 (RF_AccessStripeMap_t *) node->params[np - 1].p;
205 RF_Raid_t *raidPtr = (RF_Raid_t *) node->params[np - 2].p;
206 RF_RaidLayout_t *layoutPtr = (RF_RaidLayout_t *) & (raidPtr->Layout);
207 int d, i;
208 unsigned coeff;
209 RF_RaidAddr_t sosAddr, suoffset;
210 RF_SectorCount_t len, secPerSU = layoutPtr->sectorsPerStripeUnit;
211 int two = 0;
212 RF_PhysDiskAddr_t *ppda, *ppda2, *qpda, *qpda2, *pda, npda;
213 char *buf;
214 int numDataCol = layoutPtr->numDataCol;
215 RF_Etimer_t timer;
216 RF_AccTraceEntry_t *tracerec = node->dagHdr->tracerec;
217
218 RF_ETIMER_START(timer);
219
220 if (asmap->failedPDAs[1] &&
221 (asmap->failedPDAs[1]->numSector +
222 asmap->failedPDAs[0]->numSector < secPerSU)) {
223 RF_ASSERT(0);
224 ppda = node->params[np - 6].p;
225 ppda2 = node->params[np - 5].p;
226 qpda = node->params[np - 4].p;
227 qpda2 = node->params[np - 3].p;
228 d = (np - 6);
229 two = 1;
230 } else {
231 ppda = node->params[np - 4].p;
232 qpda = node->params[np - 3].p;
233 d = (np - 4);
234 }
235
236 for (i = 0; i < d; i++) {
237 pda = node->params[i].p;
238 buf = pda->bufPtr;
239 suoffset = rf_StripeUnitOffset(layoutPtr, pda->startSector);
240 len = pda->numSector;
241 coeff = rf_RaidAddressToStripeUnitID(layoutPtr,
242 pda->raidAddress);
243
244 coeff = (coeff % raidPtr->Layout.numDataCol);
245
246 rf_applyPDA(raidPtr, pda, ppda, qpda, node->dagHdr->bp);
247 if (two)
248 rf_applyPDA(raidPtr, pda, ppda, qpda, node->dagHdr->bp);
249 }
250
251
252
253
254
255
256
257 if (asmap->failedPDAs[1] == NULL) {
258
259
260
261 pda = asmap->failedPDAs[0];
262 sosAddr = rf_RaidAddressOfPrevStripeBoundary(layoutPtr,
263 asmap->raidAddress);
264
265 coeff = rf_RaidAddressToStripeUnitID(layoutPtr,
266 pda->raidAddress);
267
268 coeff = (coeff % raidPtr->Layout.numDataCol);
269 for (i = 0; i < numDataCol; i++) {
270 npda.raidAddress = sosAddr + (i * secPerSU);
271 (raidPtr->Layout.map->MapSector) (raidPtr,
272 npda.raidAddress, &(npda.row), &(npda.col),
273 &(npda.startSector), 0);
274
275 if (RF_DEAD_DISK(raidPtr->Disks[npda.row][npda.col]
276 .status))
277 if (i != coeff)
278 break;
279 }
280 RF_ASSERT(i < numDataCol);
281 RF_ASSERT(two == 0);
282
283
284
285
286 if (coeff < i)
287 rf_PQ_recover((unsigned long *) ppda->bufPtr,
288 (unsigned long *) qpda->bufPtr,
289 (unsigned long *) pda->bufPtr,
290 (unsigned long *) ppda->bufPtr,
291 rf_RaidAddressToByte(raidPtr, pda->numSector),
292 coeff, i);
293 else
294 rf_PQ_recover((unsigned long *) ppda->bufPtr,
295 (unsigned long *) qpda->bufPtr,
296 (unsigned long *) ppda->bufPtr,
297 (unsigned long *) pda->bufPtr,
298 rf_RaidAddressToByte(raidPtr, pda->numSector),
299 i, coeff);
300 } else
301 RF_PANIC();
302
303 RF_ETIMER_STOP(timer);
304 RF_ETIMER_EVAL(timer);
305 if (tracerec)
306 tracerec->q_us += RF_ETIMER_VAL_US(timer);
307 rf_GenericWakeupFunc(node, 0);
308 return (0);
309 }
310
311 int
312 rf_PQWriteDoubleRecoveryFunc(RF_DagNode_t *node)
313 {
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340 int np = node->numParams;
341 RF_AccessStripeMap_t *asmap = (RF_AccessStripeMap_t *)
342 node->params[np - 1].p;
343 RF_Raid_t *raidPtr = (RF_Raid_t *) node->params[np - 2].p;
344 RF_RaidLayout_t *layoutPtr = (RF_RaidLayout_t *) & (raidPtr->Layout);
345 int i;
346 RF_RaidAddr_t sosAddr;
347 unsigned coeff;
348 RF_StripeCount_t secPerSU = layoutPtr->sectorsPerStripeUnit;
349 RF_PhysDiskAddr_t *ppda, *qpda, *pda, npda;
350 int numDataCol = layoutPtr->numDataCol;
351 RF_Etimer_t timer;
352 RF_AccTraceEntry_t *tracerec = node->dagHdr->tracerec;
353
354 RF_ASSERT(node->numResults == 2);
355 RF_ASSERT(asmap->failedPDAs[1] == NULL);
356 RF_ETIMER_START(timer);
357 ppda = node->results[0];
358 qpda = node->results[1];
359
360 for (i = 0; i < numDataCol - 2; i++)
361 rf_applyPDA(raidPtr, node->params[i].p, ppda, qpda,
362 node->dagHdr->bp);
363
364
365 pda = asmap->failedPDAs[0];
366 sosAddr = rf_RaidAddressOfPrevStripeBoundary(layoutPtr,
367 asmap->raidAddress);
368
369 coeff = rf_RaidAddressToStripeUnitID(layoutPtr, pda->raidAddress);
370
371 coeff = (coeff % raidPtr->Layout.numDataCol);
372 for (i = 0; i < numDataCol; i++) {
373 npda.raidAddress = sosAddr + (i * secPerSU);
374 (raidPtr->Layout.map->MapSector) (raidPtr, npda.raidAddress,
375 &(npda.row), &(npda.col), &(npda.startSector), 0);
376
377 if (RF_DEAD_DISK(raidPtr->Disks[npda.row][npda.col].status))
378 if (i != coeff)
379 break;
380 }
381 RF_ASSERT(i < numDataCol);
382
383
384
385
386 if (coeff < i)
387 rf_PQ_recover((unsigned long *) ppda->bufPtr,
388 (unsigned long *) qpda->bufPtr,
389 (unsigned long *) ppda->bufPtr,
390 (unsigned long *) qpda->bufPtr,
391 rf_RaidAddressToByte(raidPtr, pda->numSector), coeff, i);
392 else
393 rf_PQ_recover((unsigned long *) ppda->bufPtr,
394 (unsigned long *) qpda->bufPtr,
395 (unsigned long *) qpda->bufPtr,
396 (unsigned long *) ppda->bufPtr,
397 rf_RaidAddressToByte(raidPtr, pda->numSector), i, coeff);
398
399
400 bzero(qpda->bufPtr, rf_RaidAddressToByte(raidPtr, qpda->numSector));
401 rf_IncQ((unsigned long *) qpda->bufPtr, (unsigned long *) ppda->bufPtr,
402 rf_RaidAddressToByte(raidPtr, qpda->numSector), i);
403
404
405
406
407
408
409 RF_ASSERT(asmap->numStripeUnitsAccessed == 1);
410
411 rf_IncQ((unsigned long *) qpda->bufPtr,
412 (unsigned long *) asmap->failedPDAs[0]->bufPtr,
413 rf_RaidAddressToByte(raidPtr, qpda->numSector), coeff);
414 rf_bxor(asmap->failedPDAs[0]->bufPtr, ppda->bufPtr,
415 rf_RaidAddressToByte(raidPtr, ppda->numSector), node->dagHdr->bp);
416
417
418 for (i = 0; i < numDataCol - 2; i++)
419 rf_applyPDA(raidPtr, node->params[i].p, ppda, qpda,
420 node->dagHdr->bp);
421
422 RF_ETIMER_STOP(timer);
423 RF_ETIMER_EVAL(timer);
424 if (tracerec)
425 tracerec->q_us += RF_ETIMER_VAL_US(timer);
426
427 rf_GenericWakeupFunc(node, 0);
428 return (0);
429 }
430
431 RF_CREATE_DAG_FUNC_DECL(rf_PQ_DDLargeWrite)
432 {
433 RF_PANIC();
434 }
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464 RF_CREATE_DAG_FUNC_DECL(rf_PQ_200_CreateWriteDAG)
465 {
466 RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout);
467 RF_SectorCount_t sectorsPerSU = layoutPtr->sectorsPerStripeUnit;
468 int sum;
469 int nf = asmap->numDataFailed;
470
471 sum = asmap->failedPDAs[0]->numSector;
472 if (nf == 2)
473 sum += asmap->failedPDAs[1]->numSector;
474
475 if ((nf == 2) && (sum == (2 * sectorsPerSU))) {
476
477 rf_PQ_DDLargeWrite(raidPtr, asmap, dag_h, bp, flags, allocList);
478 return;
479 }
480 if ((nf == asmap->numStripeUnitsAccessed) || (sum >= sectorsPerSU)) {
481
482 rf_PQ_DDSimpleSmallWrite(raidPtr, asmap, dag_h, bp, flags,
483 allocList);
484 return;
485 }
486 RF_PANIC();
487 }
488
489 RF_CREATE_DAG_FUNC_DECL(rf_PQ_DDSimpleSmallWrite)
490 {
491 rf_DoubleDegSmallWrite(raidPtr, asmap, dag_h, bp, flags, allocList,
492 "Rq", "Wq", "PQ Recovery", rf_PQWriteDoubleRecoveryFunc);
493 }
494
495 #endif