1 /* $NetBSD: rf_evenodd.c,v 1.7 2001/11/13 07:11:14 lukem Exp $ */ 2 /* 3 * Copyright (c) 1995 Carnegie-Mellon University. 4 * All rights reserved. 5 * 6 * Author: Chang-Ming Wu 7 * 8 * Permission to use, copy, modify and distribute this software and 9 * its documentation is hereby granted, provided that both the copyright 10 * notice and this permission notice appear in all copies of the 11 * software, derivative works or modified versions, and any portions 12 * thereof, and that both notices appear in supporting documentation. 13 * 14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 16 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 * 18 * Carnegie Mellon requests users of this software to return to 19 * 20 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 21 * School of Computer Science 22 * Carnegie Mellon University 23 * Pittsburgh PA 15213-3890 24 * 25 * any improvements or extensions that they make and grant Carnegie the 26 * rights to redistribute these changes. 27 */ 28 29 /***************************************************************************************** 30 * 31 * rf_evenodd.c -- implements EVENODD array architecture 32 * 33 ****************************************************************************************/ 34 35 #include <sys/cdefs.h> 36 __KERNEL_RCSID(0, "$NetBSD: rf_evenodd.c,v 1.7 2001/11/13 07:11:14 lukem Exp $"); 37 38 #include "rf_archs.h" 39 40 #if RF_INCLUDE_EVENODD > 0 41 42 #include <dev/raidframe/raidframevar.h> 43 44 #include "rf_raid.h" 45 #include "rf_dag.h" 46 #include "rf_dagffrd.h" 47 #include "rf_dagffwr.h" 48 #include "rf_dagdegrd.h" 49 #include "rf_dagdegwr.h" 50 #include "rf_dagutils.h" 51 #include "rf_dagfuncs.h" 52 #include "rf_etimer.h" 53 #include "rf_general.h" 54 #include "rf_evenodd.h" 55 #include "rf_parityscan.h" 56 #include "rf_utils.h" 57 #include "rf_map.h" 58 #include "rf_pq.h" 59 #include "rf_mcpair.h" 60 #include "rf_evenodd.h" 61 #include "rf_evenodd_dagfuncs.h" 62 #include "rf_evenodd_dags.h" 63 #include "rf_engine.h" 64 65 typedef struct RF_EvenOddConfigInfo_s { 66 RF_RowCol_t **stripeIdentifier; /* filled in at config time & used by 67 * IdentifyStripe */ 68 } RF_EvenOddConfigInfo_t; 69 70 int 71 rf_ConfigureEvenOdd(listp, raidPtr, cfgPtr) 72 RF_ShutdownList_t **listp; 73 RF_Raid_t *raidPtr; 74 RF_Config_t *cfgPtr; 75 { 76 RF_RaidLayout_t *layoutPtr = &raidPtr->Layout; 77 RF_EvenOddConfigInfo_t *info; 78 RF_RowCol_t i, j, startdisk; 79 80 RF_MallocAndAdd(info, sizeof(RF_EvenOddConfigInfo_t), (RF_EvenOddConfigInfo_t *), raidPtr->cleanupList); 81 layoutPtr->layoutSpecificInfo = (void *) info; 82 83 RF_ASSERT(raidPtr->numRow == 1); 84 85 info->stripeIdentifier = rf_make_2d_array(raidPtr->numCol, raidPtr->numCol, raidPtr->cleanupList); 86 startdisk = 0; 87 for (i = 0; i < raidPtr->numCol; i++) { 88 for (j = 0; j < raidPtr->numCol; j++) { 89 info->stripeIdentifier[i][j] = (startdisk + j) % raidPtr->numCol; 90 } 91 if ((startdisk -= 2) < 0) 92 startdisk += raidPtr->numCol; 93 } 94 95 /* fill in the remaining layout parameters */ 96 layoutPtr->numStripe = layoutPtr->stripeUnitsPerDisk; 97 layoutPtr->bytesPerStripeUnit = layoutPtr->sectorsPerStripeUnit << raidPtr->logBytesPerSector; 98 layoutPtr->numDataCol = raidPtr->numCol - 2; /* ORIG: 99 * layoutPtr->numDataCol 100 * = raidPtr->numCol-1; */ 101 #if RF_EO_MATRIX_DIM > 17 102 if (raidPtr->numCol <= 17) { 103 printf("Number of stripe units in a parity stripe is smaller than 17. Please\n"); 104 printf("define the macro RF_EO_MATRIX_DIM in file rf_evenodd_dagfuncs.h to \n"); 105 printf("be 17 to increase performance. \n"); 106 return (EINVAL); 107 } 108 #elif RF_EO_MATRIX_DIM == 17 109 if (raidPtr->numCol > 17) { 110 printf("Number of stripe units in a parity stripe is bigger than 17. Please\n"); 111 printf("define the macro RF_EO_MATRIX_DIM in file rf_evenodd_dagfuncs.h to \n"); 112 printf("be 257 for encoding and decoding functions to work. \n"); 113 return (EINVAL); 114 } 115 #endif 116 layoutPtr->dataSectorsPerStripe = layoutPtr->numDataCol * layoutPtr->sectorsPerStripeUnit; 117 layoutPtr->numParityCol = 2; 118 layoutPtr->dataStripeUnitsPerDisk = layoutPtr->stripeUnitsPerDisk; 119 raidPtr->sectorsPerDisk = layoutPtr->stripeUnitsPerDisk * layoutPtr->sectorsPerStripeUnit; 120 121 raidPtr->totalSectors = layoutPtr->stripeUnitsPerDisk * layoutPtr->numDataCol * layoutPtr->sectorsPerStripeUnit; 122 123 return (0); 124 } 125 126 int 127 rf_GetDefaultNumFloatingReconBuffersEvenOdd(RF_Raid_t * raidPtr) 128 { 129 return (20); 130 } 131 132 RF_HeadSepLimit_t 133 rf_GetDefaultHeadSepLimitEvenOdd(RF_Raid_t * raidPtr) 134 { 135 return (10); 136 } 137 138 void 139 rf_IdentifyStripeEvenOdd( 140 RF_Raid_t * raidPtr, 141 RF_RaidAddr_t addr, 142 RF_RowCol_t ** diskids, 143 RF_RowCol_t * outRow) 144 { 145 RF_StripeNum_t stripeID = rf_RaidAddressToStripeID(&raidPtr->Layout, addr); 146 RF_EvenOddConfigInfo_t *info = (RF_EvenOddConfigInfo_t *) raidPtr->Layout.layoutSpecificInfo; 147 148 *outRow = 0; 149 *diskids = info->stripeIdentifier[stripeID % raidPtr->numCol]; 150 } 151 /* The layout of stripe unit on the disks are: c0 c1 c2 c3 c4 152 153 0 1 2 E P 154 5 E P 3 4 155 P 6 7 8 E 156 10 11 E P 9 157 E P 12 13 14 158 .... 159 160 We use the MapSectorRAID5 to map data information because the routine can be shown to map exactly 161 the layout of data stripe unit as shown above although we have 2 redundant information now. 162 But for E and P, we use rf_MapEEvenOdd and rf_MapParityEvenOdd which are different method from raid-5. 163 */ 164 165 166 void 167 rf_MapParityEvenOdd( 168 RF_Raid_t * raidPtr, 169 RF_RaidAddr_t raidSector, 170 RF_RowCol_t * row, 171 RF_RowCol_t * col, 172 RF_SectorNum_t * diskSector, 173 int remap) 174 { 175 RF_StripeNum_t SUID = raidSector / raidPtr->Layout.sectorsPerStripeUnit; 176 RF_StripeNum_t endSUIDofthisStrip = (SUID / raidPtr->Layout.numDataCol + 1) * raidPtr->Layout.numDataCol - 1; 177 178 *row = 0; 179 *col = (endSUIDofthisStrip + 2) % raidPtr->numCol; 180 *diskSector = (SUID / (raidPtr->Layout.numDataCol)) * raidPtr->Layout.sectorsPerStripeUnit + 181 (raidSector % raidPtr->Layout.sectorsPerStripeUnit); 182 } 183 184 void 185 rf_MapEEvenOdd( 186 RF_Raid_t * raidPtr, 187 RF_RaidAddr_t raidSector, 188 RF_RowCol_t * row, 189 RF_RowCol_t * col, 190 RF_SectorNum_t * diskSector, 191 int remap) 192 { 193 RF_StripeNum_t SUID = raidSector / raidPtr->Layout.sectorsPerStripeUnit; 194 RF_StripeNum_t endSUIDofthisStrip = (SUID / raidPtr->Layout.numDataCol + 1) * raidPtr->Layout.numDataCol - 1; 195 196 *row = 0; 197 *col = (endSUIDofthisStrip + 1) % raidPtr->numCol; 198 *diskSector = (SUID / (raidPtr->Layout.numDataCol)) * raidPtr->Layout.sectorsPerStripeUnit + 199 (raidSector % raidPtr->Layout.sectorsPerStripeUnit); 200 } 201 202 void 203 rf_EODagSelect( 204 RF_Raid_t * raidPtr, 205 RF_IoType_t type, 206 RF_AccessStripeMap_t * asmap, 207 RF_VoidFuncPtr * createFunc) 208 { 209 RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout); 210 unsigned ndfail = asmap->numDataFailed; 211 unsigned npfail = asmap->numParityFailed + asmap->numQFailed; 212 unsigned ntfail = npfail + ndfail; 213 214 RF_ASSERT(RF_IO_IS_R_OR_W(type)); 215 if (ntfail > 2) { 216 RF_ERRORMSG("more than two disks failed in a single group! Aborting I/O operation.\n"); 217 /* *infoFunc = */ *createFunc = NULL; 218 return; 219 } 220 /* ok, we can do this I/O */ 221 if (type == RF_IO_TYPE_READ) { 222 switch (ndfail) { 223 case 0: 224 /* fault free read */ 225 *createFunc = (RF_VoidFuncPtr) rf_CreateFaultFreeReadDAG; /* same as raid 5 */ 226 break; 227 case 1: 228 /* lost a single data unit */ 229 /* two cases: (1) parity is not lost. do a normal raid 230 * 5 reconstruct read. (2) parity is lost. do a 231 * reconstruct read using "e". */ 232 if (ntfail == 2) { /* also lost redundancy */ 233 if (asmap->failedPDAs[1]->type == RF_PDA_TYPE_PARITY) 234 *createFunc = (RF_VoidFuncPtr) rf_EO_110_CreateReadDAG; 235 else 236 *createFunc = (RF_VoidFuncPtr) rf_EO_101_CreateReadDAG; 237 } else { 238 /* P and E are ok. But is there a failure in 239 * some unaccessed data unit? */ 240 if (rf_NumFailedDataUnitsInStripe(raidPtr, asmap) == 2) 241 *createFunc = (RF_VoidFuncPtr) rf_EO_200_CreateReadDAG; 242 else 243 *createFunc = (RF_VoidFuncPtr) rf_EO_100_CreateReadDAG; 244 } 245 break; 246 case 2: 247 /* *createFunc = rf_EO_200_CreateReadDAG; */ 248 *createFunc = NULL; 249 break; 250 } 251 return; 252 } 253 /* a write */ 254 switch (ntfail) { 255 case 0: /* fault free */ 256 if (rf_suppressLocksAndLargeWrites || 257 (((asmap->numStripeUnitsAccessed <= (layoutPtr->numDataCol / 2)) && (layoutPtr->numDataCol != 1)) || 258 (asmap->parityInfo->next != NULL) || (asmap->qInfo->next != NULL) || rf_CheckStripeForFailures(raidPtr, asmap))) { 259 260 *createFunc = (RF_VoidFuncPtr) rf_EOCreateSmallWriteDAG; 261 } else { 262 *createFunc = (RF_VoidFuncPtr) rf_EOCreateLargeWriteDAG; 263 } 264 break; 265 266 case 1: /* single disk fault */ 267 if (npfail == 1) { 268 RF_ASSERT((asmap->failedPDAs[0]->type == RF_PDA_TYPE_PARITY) || (asmap->failedPDAs[0]->type == RF_PDA_TYPE_Q)); 269 if (asmap->failedPDAs[0]->type == RF_PDA_TYPE_Q) { /* q died, treat like 270 * normal mode raid5 271 * write. */ 272 if (((asmap->numStripeUnitsAccessed <= (layoutPtr->numDataCol / 2)) || (asmap->numStripeUnitsAccessed == 1)) 273 || (asmap->parityInfo->next != NULL) || rf_NumFailedDataUnitsInStripe(raidPtr, asmap)) 274 *createFunc = (RF_VoidFuncPtr) rf_EO_001_CreateSmallWriteDAG; 275 else 276 *createFunc = (RF_VoidFuncPtr) rf_EO_001_CreateLargeWriteDAG; 277 } else {/* parity died, small write only updating Q */ 278 if (((asmap->numStripeUnitsAccessed <= (layoutPtr->numDataCol / 2)) || (asmap->numStripeUnitsAccessed == 1)) 279 || (asmap->qInfo->next != NULL) || rf_NumFailedDataUnitsInStripe(raidPtr, asmap)) 280 *createFunc = (RF_VoidFuncPtr) rf_EO_010_CreateSmallWriteDAG; 281 else 282 *createFunc = (RF_VoidFuncPtr) rf_EO_010_CreateLargeWriteDAG; 283 } 284 } else { /* data missing. Do a P reconstruct write if 285 * only a single data unit is lost in the 286 * stripe, otherwise a reconstruct write which 287 * employnig both P and E units. */ 288 if (rf_NumFailedDataUnitsInStripe(raidPtr, asmap) == 2) { 289 if (asmap->numStripeUnitsAccessed == 1) 290 *createFunc = (RF_VoidFuncPtr) rf_EO_200_CreateWriteDAG; 291 else 292 *createFunc = NULL; /* No direct support for 293 * this case now, like 294 * that in Raid-5 */ 295 } else { 296 if (asmap->numStripeUnitsAccessed != 1 && asmap->failedPDAs[0]->numSector != layoutPtr->sectorsPerStripeUnit) 297 *createFunc = NULL; /* No direct support for 298 * this case now, like 299 * that in Raid-5 */ 300 else 301 *createFunc = (RF_VoidFuncPtr) rf_EO_100_CreateWriteDAG; 302 } 303 } 304 break; 305 306 case 2: /* two disk faults */ 307 switch (npfail) { 308 case 2: /* both p and q dead */ 309 *createFunc = (RF_VoidFuncPtr) rf_EO_011_CreateWriteDAG; 310 break; 311 case 1: /* either p or q and dead data */ 312 RF_ASSERT(asmap->failedPDAs[0]->type == RF_PDA_TYPE_DATA); 313 RF_ASSERT((asmap->failedPDAs[1]->type == RF_PDA_TYPE_PARITY) || (asmap->failedPDAs[1]->type == RF_PDA_TYPE_Q)); 314 if (asmap->failedPDAs[1]->type == RF_PDA_TYPE_Q) { 315 if (asmap->numStripeUnitsAccessed != 1 && asmap->failedPDAs[0]->numSector != layoutPtr->sectorsPerStripeUnit) 316 *createFunc = NULL; /* In both PQ and 317 * EvenOdd, no direct 318 * support for this case 319 * now, like that in 320 * Raid-5 */ 321 else 322 *createFunc = (RF_VoidFuncPtr) rf_EO_101_CreateWriteDAG; 323 } else { 324 if (asmap->numStripeUnitsAccessed != 1 && asmap->failedPDAs[0]->numSector != layoutPtr->sectorsPerStripeUnit) 325 *createFunc = NULL; /* No direct support for 326 * this case, like that 327 * in Raid-5 */ 328 else 329 *createFunc = (RF_VoidFuncPtr) rf_EO_110_CreateWriteDAG; 330 } 331 break; 332 case 0: /* double data loss */ 333 /* if(asmap->failedPDAs[0]->numSector + 334 * asmap->failedPDAs[1]->numSector == 2 * 335 * layoutPtr->sectorsPerStripeUnit ) createFunc = 336 * rf_EOCreateLargeWriteDAG; else */ 337 *createFunc = NULL; /* currently, in Evenodd, No 338 * support for simultaneous 339 * access of both failed SUs */ 340 break; 341 } 342 break; 343 344 default: /* more than 2 disk faults */ 345 *createFunc = NULL; 346 RF_PANIC(); 347 } 348 return; 349 } 350 351 352 int 353 rf_VerifyParityEvenOdd(raidPtr, raidAddr, parityPDA, correct_it, flags) 354 RF_Raid_t *raidPtr; 355 RF_RaidAddr_t raidAddr; 356 RF_PhysDiskAddr_t *parityPDA; 357 int correct_it; 358 RF_RaidAccessFlags_t flags; 359 { 360 RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout); 361 RF_RaidAddr_t startAddr = rf_RaidAddressOfPrevStripeBoundary(layoutPtr, raidAddr); 362 RF_SectorCount_t numsector = parityPDA->numSector; 363 int numbytes = rf_RaidAddressToByte(raidPtr, numsector); 364 int bytesPerStripe = numbytes * layoutPtr->numDataCol; 365 RF_DagHeader_t *rd_dag_h, *wr_dag_h; /* read, write dag */ 366 RF_DagNode_t *blockNode, *unblockNode, *wrBlock, *wrUnblock; 367 RF_AccessStripeMapHeader_t *asm_h; 368 RF_AccessStripeMap_t *asmap; 369 RF_AllocListElem_t *alloclist; 370 RF_PhysDiskAddr_t *pda; 371 char *pbuf, *buf, *end_p, *p; 372 char *redundantbuf2; 373 int redundantTwoErr = 0, redundantOneErr = 0; 374 int parity_cant_correct = RF_FALSE, red2_cant_correct = RF_FALSE, 375 parity_corrected = RF_FALSE, red2_corrected = RF_FALSE; 376 int i, retcode; 377 RF_ReconUnitNum_t which_ru; 378 RF_StripeNum_t psID = rf_RaidAddressToParityStripeID(layoutPtr, raidAddr, &which_ru); 379 int stripeWidth = layoutPtr->numDataCol + layoutPtr->numParityCol; 380 RF_AccTraceEntry_t tracerec; 381 RF_MCPair_t *mcpair; 382 383 retcode = RF_PARITY_OKAY; 384 385 mcpair = rf_AllocMCPair(); 386 rf_MakeAllocList(alloclist); 387 RF_MallocAndAdd(buf, numbytes * (layoutPtr->numDataCol + layoutPtr->numParityCol), (char *), alloclist); 388 RF_CallocAndAdd(pbuf, 1, numbytes, (char *), alloclist); /* use calloc to make 389 * sure buffer is zeroed */ 390 end_p = buf + bytesPerStripe; 391 RF_CallocAndAdd(redundantbuf2, 1, numbytes, (char *), alloclist); /* use calloc to make 392 * sure buffer is zeroed */ 393 394 rd_dag_h = rf_MakeSimpleDAG(raidPtr, stripeWidth, numbytes, buf, rf_DiskReadFunc, rf_DiskReadUndoFunc, 395 "Rod", alloclist, flags, RF_IO_NORMAL_PRIORITY); 396 blockNode = rd_dag_h->succedents[0]; 397 unblockNode = blockNode->succedents[0]->succedents[0]; 398 399 /* map the stripe and fill in the PDAs in the dag */ 400 asm_h = rf_MapAccess(raidPtr, startAddr, layoutPtr->dataSectorsPerStripe, buf, RF_DONT_REMAP); 401 asmap = asm_h->stripeMap; 402 403 for (pda = asmap->physInfo, i = 0; i < layoutPtr->numDataCol; i++, pda = pda->next) { 404 RF_ASSERT(pda); 405 rf_RangeRestrictPDA(raidPtr, parityPDA, pda, 0, 1); 406 RF_ASSERT(pda->numSector != 0); 407 if (rf_TryToRedirectPDA(raidPtr, pda, 0)) 408 goto out; /* no way to verify parity if disk is 409 * dead. return w/ good status */ 410 blockNode->succedents[i]->params[0].p = pda; 411 blockNode->succedents[i]->params[2].v = psID; 412 blockNode->succedents[i]->params[3].v = RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY, 0, 0, which_ru); 413 } 414 415 RF_ASSERT(!asmap->parityInfo->next); 416 rf_RangeRestrictPDA(raidPtr, parityPDA, asmap->parityInfo, 0, 1); 417 RF_ASSERT(asmap->parityInfo->numSector != 0); 418 if (rf_TryToRedirectPDA(raidPtr, asmap->parityInfo, 1)) 419 goto out; 420 blockNode->succedents[layoutPtr->numDataCol]->params[0].p = asmap->parityInfo; 421 422 RF_ASSERT(!asmap->qInfo->next); 423 rf_RangeRestrictPDA(raidPtr, parityPDA, asmap->qInfo, 0, 1); 424 RF_ASSERT(asmap->qInfo->numSector != 0); 425 if (rf_TryToRedirectPDA(raidPtr, asmap->qInfo, 1)) 426 goto out; 427 /* if disk is dead, b/c no reconstruction is implemented right now, 428 * the function "rf_TryToRedirectPDA" always return one, which cause 429 * go to out and return w/ good status */ 430 blockNode->succedents[layoutPtr->numDataCol + 1]->params[0].p = asmap->qInfo; 431 432 /* fire off the DAG */ 433 memset((char *) &tracerec, 0, sizeof(tracerec)); 434 rd_dag_h->tracerec = &tracerec; 435 436 if (rf_verifyParityDebug) { 437 printf("Parity verify read dag:\n"); 438 rf_PrintDAGList(rd_dag_h); 439 } 440 RF_LOCK_MUTEX(mcpair->mutex); 441 mcpair->flag = 0; 442 rf_DispatchDAG(rd_dag_h, (void (*) (void *)) rf_MCPairWakeupFunc, 443 (void *) mcpair); 444 while (!mcpair->flag) 445 RF_WAIT_COND(mcpair->cond, mcpair->mutex); 446 RF_UNLOCK_MUTEX(mcpair->mutex); 447 if (rd_dag_h->status != rf_enable) { 448 RF_ERRORMSG("Unable to verify parity: can't read the stripe\n"); 449 retcode = RF_PARITY_COULD_NOT_VERIFY; 450 goto out; 451 } 452 for (p = buf, i = 0; p < end_p; p += numbytes, i++) { 453 rf_e_encToBuf(raidPtr, i, p, RF_EO_MATRIX_DIM - 2, redundantbuf2, numsector); 454 /* the corresponding columes in EvenOdd encoding Matrix for 455 * these p pointers which point to the databuffer in a full 456 * stripe are sequentially from 0 to layoutPtr->numDataCol-1 */ 457 rf_bxor(p, pbuf, numbytes, NULL); 458 } 459 RF_ASSERT(i == layoutPtr->numDataCol); 460 461 for (i = 0; i < numbytes; i++) { 462 if (pbuf[i] != buf[bytesPerStripe + i]) { 463 if (!correct_it) { 464 RF_ERRORMSG3("Parity verify error: byte %d of parity is 0x%x should be 0x%x\n", 465 i, (u_char) buf[bytesPerStripe + i], (u_char) pbuf[i]); 466 } 467 } 468 redundantOneErr = 1; 469 break; 470 } 471 472 for (i = 0; i < numbytes; i++) { 473 if (redundantbuf2[i] != buf[bytesPerStripe + numbytes + i]) { 474 if (!correct_it) { 475 RF_ERRORMSG3("Parity verify error: byte %d of second redundant information is 0x%x should be 0x%x\n", 476 i, (u_char) buf[bytesPerStripe + numbytes + i], (u_char) redundantbuf2[i]); 477 } 478 redundantTwoErr = 1; 479 break; 480 } 481 } 482 if (redundantOneErr || redundantTwoErr) 483 retcode = RF_PARITY_BAD; 484 485 /* correct the first redundant disk, ie parity if it is error */ 486 if (redundantOneErr && correct_it) { 487 wr_dag_h = rf_MakeSimpleDAG(raidPtr, 1, numbytes, pbuf, rf_DiskWriteFunc, rf_DiskWriteUndoFunc, 488 "Wnp", alloclist, flags, RF_IO_NORMAL_PRIORITY); 489 wrBlock = wr_dag_h->succedents[0]; 490 wrUnblock = wrBlock->succedents[0]->succedents[0]; 491 wrBlock->succedents[0]->params[0].p = asmap->parityInfo; 492 wrBlock->succedents[0]->params[2].v = psID; 493 wrBlock->succedents[0]->params[3].v = RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY, 0, 0, which_ru); 494 memset((char *) &tracerec, 0, sizeof(tracerec)); 495 wr_dag_h->tracerec = &tracerec; 496 if (rf_verifyParityDebug) { 497 printf("Parity verify write dag:\n"); 498 rf_PrintDAGList(wr_dag_h); 499 } 500 RF_LOCK_MUTEX(mcpair->mutex); 501 mcpair->flag = 0; 502 rf_DispatchDAG(wr_dag_h, (void (*) (void *)) rf_MCPairWakeupFunc, 503 (void *) mcpair); 504 while (!mcpair->flag) 505 RF_WAIT_COND(mcpair->cond, mcpair->mutex); 506 RF_UNLOCK_MUTEX(mcpair->mutex); 507 if (wr_dag_h->status != rf_enable) { 508 RF_ERRORMSG("Unable to correct parity in VerifyParity: can't write the stripe\n"); 509 parity_cant_correct = RF_TRUE; 510 } else { 511 parity_corrected = RF_TRUE; 512 } 513 rf_FreeDAG(wr_dag_h); 514 } 515 if (redundantTwoErr && correct_it) { 516 wr_dag_h = rf_MakeSimpleDAG(raidPtr, 1, numbytes, redundantbuf2, rf_DiskWriteFunc, rf_DiskWriteUndoFunc, 517 "Wnred2", alloclist, flags, RF_IO_NORMAL_PRIORITY); 518 wrBlock = wr_dag_h->succedents[0]; 519 wrUnblock = wrBlock->succedents[0]->succedents[0]; 520 wrBlock->succedents[0]->params[0].p = asmap->qInfo; 521 wrBlock->succedents[0]->params[2].v = psID; 522 wrBlock->succedents[0]->params[3].v = RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY, 0, 0, which_ru); 523 memset((char *) &tracerec, 0, sizeof(tracerec)); 524 wr_dag_h->tracerec = &tracerec; 525 if (rf_verifyParityDebug) { 526 printf("Dag of write new second redundant information in parity verify :\n"); 527 rf_PrintDAGList(wr_dag_h); 528 } 529 RF_LOCK_MUTEX(mcpair->mutex); 530 mcpair->flag = 0; 531 rf_DispatchDAG(wr_dag_h, (void (*) (void *)) rf_MCPairWakeupFunc, 532 (void *) mcpair); 533 while (!mcpair->flag) 534 RF_WAIT_COND(mcpair->cond, mcpair->mutex); 535 RF_UNLOCK_MUTEX(mcpair->mutex); 536 if (wr_dag_h->status != rf_enable) { 537 RF_ERRORMSG("Unable to correct second redundant information in VerifyParity: can't write the stripe\n"); 538 red2_cant_correct = RF_TRUE; 539 } else { 540 red2_corrected = RF_TRUE; 541 } 542 rf_FreeDAG(wr_dag_h); 543 } 544 if ((redundantOneErr && parity_cant_correct) || 545 (redundantTwoErr && red2_cant_correct)) 546 retcode = RF_PARITY_COULD_NOT_CORRECT; 547 if ((retcode = RF_PARITY_BAD) && parity_corrected && red2_corrected) 548 retcode = RF_PARITY_CORRECTED; 549 550 551 out: 552 rf_FreeAccessStripeMap(asm_h); 553 rf_FreeAllocList(alloclist); 554 rf_FreeDAG(rd_dag_h); 555 rf_FreeMCPair(mcpair); 556 return (retcode); 557 } 558 #endif /* RF_INCLUDE_EVENODD > 0 */ 559