diff options
author | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1999-02-16 00:03:34 +0000 |
---|---|---|
committer | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1999-02-16 00:03:34 +0000 |
commit | 086450a69044f3ede65845d9a616116db9a6d006 (patch) | |
tree | a91a7d8f967737b7eed23cb127849d08e3af4d63 /sys/dev/raidframe/rf_evenodd.c | |
parent | 41fb84abc5659cc1a368cd59d7929ddf756c3297 (diff) |
Merge from NetBSD, mostly indentation
Diffstat (limited to 'sys/dev/raidframe/rf_evenodd.c')
-rw-r--r-- | sys/dev/raidframe/rf_evenodd.c | 888 |
1 files changed, 445 insertions, 443 deletions
diff --git a/sys/dev/raidframe/rf_evenodd.c b/sys/dev/raidframe/rf_evenodd.c index 90d18653cda..7b40675d9df 100644 --- a/sys/dev/raidframe/rf_evenodd.c +++ b/sys/dev/raidframe/rf_evenodd.c @@ -1,5 +1,5 @@ -/* $OpenBSD: rf_evenodd.c,v 1.1 1999/01/11 14:29:21 niklas Exp $ */ -/* $NetBSD: rf_evenodd.c,v 1.1 1998/11/13 04:20:29 oster Exp $ */ +/* $OpenBSD: rf_evenodd.c,v 1.2 1999/02/16 00:02:44 niklas Exp $ */ +/* $NetBSD: rf_evenodd.c,v 1.2 1999/02/05 00:06:11 oster Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. * All rights reserved. @@ -63,85 +63,92 @@ #include "rf_engine.h" typedef struct RF_EvenOddConfigInfo_s { - RF_RowCol_t **stripeIdentifier; /* filled in at config time & used by IdentifyStripe */ -} RF_EvenOddConfigInfo_t; - -int rf_ConfigureEvenOdd(listp, raidPtr, cfgPtr) - RF_ShutdownList_t **listp; - RF_Raid_t *raidPtr; - RF_Config_t *cfgPtr; + RF_RowCol_t **stripeIdentifier; /* filled in at config time & used by + * IdentifyStripe */ +} RF_EvenOddConfigInfo_t; + +int +rf_ConfigureEvenOdd(listp, raidPtr, cfgPtr) + RF_ShutdownList_t **listp; + RF_Raid_t *raidPtr; + RF_Config_t *cfgPtr; { - RF_RaidLayout_t *layoutPtr = &raidPtr->Layout; - RF_EvenOddConfigInfo_t *info; - RF_RowCol_t i, j, startdisk; - - RF_MallocAndAdd(info, sizeof(RF_EvenOddConfigInfo_t), (RF_EvenOddConfigInfo_t *), raidPtr->cleanupList); - layoutPtr->layoutSpecificInfo = (void *) info; - - RF_ASSERT(raidPtr->numRow == 1); - - info->stripeIdentifier = rf_make_2d_array(raidPtr->numCol, raidPtr->numCol, raidPtr->cleanupList); - startdisk = 0; - for (i=0; i<raidPtr->numCol; i++) { - for (j=0; j<raidPtr->numCol; j++) { - info->stripeIdentifier[i][j] = (startdisk + j) % raidPtr->numCol; - } - if ((startdisk -= 2) < 0) startdisk += raidPtr->numCol; - } - - /* fill in the remaining layout parameters */ - layoutPtr->numStripe = layoutPtr->stripeUnitsPerDisk; - layoutPtr->bytesPerStripeUnit = layoutPtr->sectorsPerStripeUnit << raidPtr->logBytesPerSector; - layoutPtr->numDataCol = raidPtr->numCol-2; /* ORIG: layoutPtr->numDataCol = raidPtr->numCol-1; */ + RF_RaidLayout_t *layoutPtr = &raidPtr->Layout; + RF_EvenOddConfigInfo_t *info; + RF_RowCol_t i, j, startdisk; + + RF_MallocAndAdd(info, sizeof(RF_EvenOddConfigInfo_t), (RF_EvenOddConfigInfo_t *), raidPtr->cleanupList); + layoutPtr->layoutSpecificInfo = (void *) info; + + RF_ASSERT(raidPtr->numRow == 1); + + info->stripeIdentifier = rf_make_2d_array(raidPtr->numCol, raidPtr->numCol, raidPtr->cleanupList); + startdisk = 0; + for (i = 0; i < raidPtr->numCol; i++) { + for (j = 0; j < raidPtr->numCol; j++) { + info->stripeIdentifier[i][j] = (startdisk + j) % raidPtr->numCol; + } + if ((startdisk -= 2) < 0) + startdisk += raidPtr->numCol; + } + + /* fill in the remaining layout parameters */ + layoutPtr->numStripe = layoutPtr->stripeUnitsPerDisk; + layoutPtr->bytesPerStripeUnit = layoutPtr->sectorsPerStripeUnit << raidPtr->logBytesPerSector; + layoutPtr->numDataCol = raidPtr->numCol - 2; /* ORIG: + * layoutPtr->numDataCol + * = raidPtr->numCol-1; */ #if RF_EO_MATRIX_DIM > 17 - if (raidPtr->numCol <= 17){ - printf("Number of stripe units in a parity stripe is smaller than 17. Please\n"); - printf("define the macro RF_EO_MATRIX_DIM in file rf_evenodd_dagfuncs.h to \n"); - printf("be 17 to increase performance. \n"); - return(EINVAL); - } + if (raidPtr->numCol <= 17) { + printf("Number of stripe units in a parity stripe is smaller than 17. Please\n"); + printf("define the macro RF_EO_MATRIX_DIM in file rf_evenodd_dagfuncs.h to \n"); + printf("be 17 to increase performance. \n"); + return (EINVAL); + } #elif RF_EO_MATRIX_DIM == 17 - if (raidPtr->numCol > 17) { - printf("Number of stripe units in a parity stripe is bigger than 17. Please\n"); - printf("define the macro RF_EO_MATRIX_DIM in file rf_evenodd_dagfuncs.h to \n"); - printf("be 257 for encoding and decoding functions to work. \n"); - return(EINVAL); - } + if (raidPtr->numCol > 17) { + printf("Number of stripe units in a parity stripe is bigger than 17. Please\n"); + printf("define the macro RF_EO_MATRIX_DIM in file rf_evenodd_dagfuncs.h to \n"); + printf("be 257 for encoding and decoding functions to work. \n"); + return (EINVAL); + } #endif - layoutPtr->dataSectorsPerStripe = layoutPtr->numDataCol * layoutPtr->sectorsPerStripeUnit; - layoutPtr->numParityCol = 2; - layoutPtr->dataStripeUnitsPerDisk = layoutPtr->stripeUnitsPerDisk; - raidPtr->sectorsPerDisk = layoutPtr->stripeUnitsPerDisk * layoutPtr->sectorsPerStripeUnit; + layoutPtr->dataSectorsPerStripe = layoutPtr->numDataCol * layoutPtr->sectorsPerStripeUnit; + layoutPtr->numParityCol = 2; + layoutPtr->dataStripeUnitsPerDisk = layoutPtr->stripeUnitsPerDisk; + raidPtr->sectorsPerDisk = layoutPtr->stripeUnitsPerDisk * layoutPtr->sectorsPerStripeUnit; - raidPtr->totalSectors = layoutPtr->stripeUnitsPerDisk * layoutPtr->numDataCol * layoutPtr->sectorsPerStripeUnit; + raidPtr->totalSectors = layoutPtr->stripeUnitsPerDisk * layoutPtr->numDataCol * layoutPtr->sectorsPerStripeUnit; - return(0); + return (0); } -int rf_GetDefaultNumFloatingReconBuffersEvenOdd(RF_Raid_t *raidPtr) +int +rf_GetDefaultNumFloatingReconBuffersEvenOdd(RF_Raid_t * raidPtr) { - return(20); + return (20); } -RF_HeadSepLimit_t rf_GetDefaultHeadSepLimitEvenOdd(RF_Raid_t *raidPtr) +RF_HeadSepLimit_t +rf_GetDefaultHeadSepLimitEvenOdd(RF_Raid_t * raidPtr) { - return(10); + return (10); } -void rf_IdentifyStripeEvenOdd( - RF_Raid_t *raidPtr, - RF_RaidAddr_t addr, - RF_RowCol_t **diskids, - RF_RowCol_t *outRow) +void +rf_IdentifyStripeEvenOdd( + RF_Raid_t * raidPtr, + RF_RaidAddr_t addr, + RF_RowCol_t ** diskids, + RF_RowCol_t * outRow) { - RF_StripeNum_t stripeID = rf_RaidAddressToStripeID(&raidPtr->Layout, addr); - RF_EvenOddConfigInfo_t *info = (RF_EvenOddConfigInfo_t *) raidPtr->Layout.layoutSpecificInfo; + RF_StripeNum_t stripeID = rf_RaidAddressToStripeID(&raidPtr->Layout, addr); + RF_EvenOddConfigInfo_t *info = (RF_EvenOddConfigInfo_t *) raidPtr->Layout.layoutSpecificInfo; - *outRow = 0; - *diskids = info->stripeIdentifier[ stripeID % raidPtr->numCol ]; + *outRow = 0; + *diskids = info->stripeIdentifier[stripeID % raidPtr->numCol]; } - -/* The layout of stripe unit on the disks are: c0 c1 c2 c3 c4 +/* The layout of stripe unit on the disks are: c0 c1 c2 c3 c4 0 1 2 E P 5 E P 3 4 @@ -150,407 +157,402 @@ void rf_IdentifyStripeEvenOdd( E P 12 13 14 .... - We use the MapSectorRAID5 to map data information because the routine can be shown to map exactly + We use the MapSectorRAID5 to map data information because the routine can be shown to map exactly the layout of data stripe unit as shown above although we have 2 redundant information now. But for E and P, we use rf_MapEEvenOdd and rf_MapParityEvenOdd which are different method from raid-5. */ -void rf_MapParityEvenOdd( - RF_Raid_t *raidPtr, - RF_RaidAddr_t raidSector, - RF_RowCol_t *row, - RF_RowCol_t *col, - RF_SectorNum_t *diskSector, - int remap) +void +rf_MapParityEvenOdd( + RF_Raid_t * raidPtr, + RF_RaidAddr_t raidSector, + RF_RowCol_t * row, + RF_RowCol_t * col, + RF_SectorNum_t * diskSector, + int remap) { - RF_StripeNum_t SUID = raidSector / raidPtr->Layout.sectorsPerStripeUnit; - RF_StripeNum_t endSUIDofthisStrip = (SUID/raidPtr->Layout.numDataCol + 1)*raidPtr->Layout.numDataCol - 1; + RF_StripeNum_t SUID = raidSector / raidPtr->Layout.sectorsPerStripeUnit; + RF_StripeNum_t endSUIDofthisStrip = (SUID / raidPtr->Layout.numDataCol + 1) * raidPtr->Layout.numDataCol - 1; - *row = 0; - *col = ( endSUIDofthisStrip + 2)%raidPtr->numCol; - *diskSector = (SUID / (raidPtr->Layout.numDataCol)) * raidPtr->Layout.sectorsPerStripeUnit + - (raidSector % raidPtr->Layout.sectorsPerStripeUnit); + *row = 0; + *col = (endSUIDofthisStrip + 2) % raidPtr->numCol; + *diskSector = (SUID / (raidPtr->Layout.numDataCol)) * raidPtr->Layout.sectorsPerStripeUnit + + (raidSector % raidPtr->Layout.sectorsPerStripeUnit); } -void rf_MapEEvenOdd( - RF_Raid_t *raidPtr, - RF_RaidAddr_t raidSector, - RF_RowCol_t *row, - RF_RowCol_t *col, - RF_SectorNum_t *diskSector, - int remap) +void +rf_MapEEvenOdd( + RF_Raid_t * raidPtr, + RF_RaidAddr_t raidSector, + RF_RowCol_t * row, + RF_RowCol_t * col, + RF_SectorNum_t * diskSector, + int remap) { - RF_StripeNum_t SUID = raidSector / raidPtr->Layout.sectorsPerStripeUnit; - RF_StripeNum_t endSUIDofthisStrip = (SUID/raidPtr->Layout.numDataCol + 1)*raidPtr->Layout.numDataCol - 1; + RF_StripeNum_t SUID = raidSector / raidPtr->Layout.sectorsPerStripeUnit; + RF_StripeNum_t endSUIDofthisStrip = (SUID / raidPtr->Layout.numDataCol + 1) * raidPtr->Layout.numDataCol - 1; - *row = 0; - *col = ( endSUIDofthisStrip + 1)%raidPtr->numCol; - *diskSector = (SUID / (raidPtr->Layout.numDataCol)) * raidPtr->Layout.sectorsPerStripeUnit + - (raidSector % raidPtr->Layout.sectorsPerStripeUnit); + *row = 0; + *col = (endSUIDofthisStrip + 1) % raidPtr->numCol; + *diskSector = (SUID / (raidPtr->Layout.numDataCol)) * raidPtr->Layout.sectorsPerStripeUnit + + (raidSector % raidPtr->Layout.sectorsPerStripeUnit); } -void rf_EODagSelect( - RF_Raid_t *raidPtr, - RF_IoType_t type, - RF_AccessStripeMap_t *asmap, - RF_VoidFuncPtr *createFunc) +void +rf_EODagSelect( + RF_Raid_t * raidPtr, + RF_IoType_t type, + RF_AccessStripeMap_t * asmap, + RF_VoidFuncPtr * createFunc) { - RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout); - unsigned ndfail = asmap->numDataFailed; - unsigned npfail = asmap->numParityFailed +asmap->numQFailed; - unsigned ntfail = npfail + ndfail; - - RF_ASSERT(RF_IO_IS_R_OR_W(type)); - if (ntfail > 2) - { - RF_ERRORMSG("more than two disks failed in a single group! Aborting I/O operation.\n"); - /* *infoFunc = */ *createFunc = NULL; - return; - } - - /* ok, we can do this I/O */ - if (type == RF_IO_TYPE_READ) - { - switch (ndfail) - { - case 0: - /* fault free read */ - *createFunc = (RF_VoidFuncPtr)rf_CreateFaultFreeReadDAG; /* same as raid 5 */ - break; - case 1: - /* lost a single data unit */ - /* two cases: - (1) parity is not lost. - do a normal raid 5 reconstruct read. - (2) parity is lost. - do a reconstruct read using "e". - */ - if (ntfail == 2) /* also lost redundancy */ - { - if (asmap->failedPDAs[1]->type == RF_PDA_TYPE_PARITY) - *createFunc = (RF_VoidFuncPtr)rf_EO_110_CreateReadDAG; - else - *createFunc = (RF_VoidFuncPtr)rf_EO_101_CreateReadDAG; - } - else - { - /* P and E are ok. But is there a failure - in some unaccessed data unit? - */ - if (rf_NumFailedDataUnitsInStripe(raidPtr,asmap)==2) - *createFunc = (RF_VoidFuncPtr)rf_EO_200_CreateReadDAG; - else - *createFunc = (RF_VoidFuncPtr)rf_EO_100_CreateReadDAG; - } - break; - case 2: - /* *createFunc = rf_EO_200_CreateReadDAG; */ - *createFunc = NULL; - break; - } - return; - } - - /* a write */ - switch (ntfail) - { - case 0: /* fault free */ - if (rf_suppressLocksAndLargeWrites || - (((asmap->numStripeUnitsAccessed <= (layoutPtr->numDataCol / 2)) && (layoutPtr->numDataCol != 1)) || - (asmap->parityInfo->next != NULL) || (asmap->qInfo->next != NULL) || rf_CheckStripeForFailures(raidPtr, asmap))) { - - *createFunc = (RF_VoidFuncPtr)rf_EOCreateSmallWriteDAG; - } - else { - *createFunc = (RF_VoidFuncPtr)rf_EOCreateLargeWriteDAG; - } - break; - - case 1: /* single disk fault */ - if (npfail==1) - { - RF_ASSERT ((asmap->failedPDAs[0]->type == RF_PDA_TYPE_PARITY) || (asmap->failedPDAs[0]->type == RF_PDA_TYPE_Q)); - if (asmap->failedPDAs[0]->type == RF_PDA_TYPE_Q) - { /* q died, treat like normal mode raid5 write.*/ - if (((asmap->numStripeUnitsAccessed <= (layoutPtr->numDataCol / 2)) || (asmap->numStripeUnitsAccessed == 1)) - || (asmap->parityInfo->next!=NULL) || rf_NumFailedDataUnitsInStripe(raidPtr,asmap)) - *createFunc = (RF_VoidFuncPtr)rf_EO_001_CreateSmallWriteDAG; - else - *createFunc = (RF_VoidFuncPtr)rf_EO_001_CreateLargeWriteDAG; - } - else - { /* parity died, small write only updating Q */ - if (((asmap->numStripeUnitsAccessed <= (layoutPtr->numDataCol / 2)) || (asmap->numStripeUnitsAccessed == 1)) - || (asmap->qInfo->next!=NULL) || rf_NumFailedDataUnitsInStripe(raidPtr,asmap)) - *createFunc = (RF_VoidFuncPtr)rf_EO_010_CreateSmallWriteDAG; - else - *createFunc = (RF_VoidFuncPtr)rf_EO_010_CreateLargeWriteDAG; - } + RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout); + unsigned ndfail = asmap->numDataFailed; + unsigned npfail = asmap->numParityFailed + asmap->numQFailed; + unsigned ntfail = npfail + ndfail; + + RF_ASSERT(RF_IO_IS_R_OR_W(type)); + if (ntfail > 2) { + RF_ERRORMSG("more than two disks failed in a single group! Aborting I/O operation.\n"); + /* *infoFunc = */ *createFunc = NULL; + return; } - else - { /* data missing. - Do a P reconstruct write if only a single data unit - is lost in the stripe, otherwise a reconstruct - write which employnig both P and E units. */ - if (rf_NumFailedDataUnitsInStripe(raidPtr,asmap)==2) - { - if (asmap->numStripeUnitsAccessed == 1) - *createFunc = (RF_VoidFuncPtr)rf_EO_200_CreateWriteDAG; - else - *createFunc = NULL; /* No direct support for this case now, like that in Raid-5 */ - } - else - { - if (asmap->numStripeUnitsAccessed != 1 && asmap->failedPDAs[0]->numSector != layoutPtr->sectorsPerStripeUnit) - *createFunc = NULL; /* No direct support for this case now, like that in Raid-5 */ - else *createFunc = (RF_VoidFuncPtr)rf_EO_100_CreateWriteDAG; - } + /* ok, we can do this I/O */ + if (type == RF_IO_TYPE_READ) { + switch (ndfail) { + case 0: + /* fault free read */ + *createFunc = (RF_VoidFuncPtr) rf_CreateFaultFreeReadDAG; /* same as raid 5 */ + break; + case 1: + /* lost a single data unit */ + /* two cases: (1) parity is not lost. do a normal raid + * 5 reconstruct read. (2) parity is lost. do a + * reconstruct read using "e". */ + if (ntfail == 2) { /* also lost redundancy */ + if (asmap->failedPDAs[1]->type == RF_PDA_TYPE_PARITY) + *createFunc = (RF_VoidFuncPtr) rf_EO_110_CreateReadDAG; + else + *createFunc = (RF_VoidFuncPtr) rf_EO_101_CreateReadDAG; + } else { + /* P and E are ok. But is there a failure in + * some unaccessed data unit? */ + if (rf_NumFailedDataUnitsInStripe(raidPtr, asmap) == 2) + *createFunc = (RF_VoidFuncPtr) rf_EO_200_CreateReadDAG; + else + *createFunc = (RF_VoidFuncPtr) rf_EO_100_CreateReadDAG; + } + break; + case 2: + /* *createFunc = rf_EO_200_CreateReadDAG; */ + *createFunc = NULL; + break; + } + return; } - break; - - case 2: /* two disk faults */ - switch (npfail) - { - case 2: /* both p and q dead */ - *createFunc = (RF_VoidFuncPtr)rf_EO_011_CreateWriteDAG; - break; - case 1: /* either p or q and dead data */ - RF_ASSERT(asmap->failedPDAs[0]->type == RF_PDA_TYPE_DATA); - RF_ASSERT ((asmap->failedPDAs[1]->type == RF_PDA_TYPE_PARITY) || (asmap->failedPDAs[1]->type == RF_PDA_TYPE_Q)); - if (asmap->failedPDAs[1]->type == RF_PDA_TYPE_Q) - { - if(asmap->numStripeUnitsAccessed != 1 && asmap->failedPDAs[0]->numSector != layoutPtr->sectorsPerStripeUnit) - *createFunc = NULL; /* In both PQ and EvenOdd, no direct support for this case now, like that in Raid-5 */ - else - *createFunc = (RF_VoidFuncPtr)rf_EO_101_CreateWriteDAG; - } - else - { - if (asmap->numStripeUnitsAccessed != 1 && asmap->failedPDAs[0]->numSector != layoutPtr->sectorsPerStripeUnit) - *createFunc = NULL; /* No direct support for this case, like that in Raid-5 */ - else - *createFunc = (RF_VoidFuncPtr)rf_EO_110_CreateWriteDAG; - } - break; - case 0: /* double data loss */ - /* if(asmap->failedPDAs[0]->numSector + asmap->failedPDAs[1]->numSector == 2 * layoutPtr->sectorsPerStripeUnit ) - *createFunc = rf_EOCreateLargeWriteDAG; - else */ - *createFunc = NULL; /* currently, in Evenodd, No support for simultaneous access of both failed SUs */ - break; + /* a write */ + switch (ntfail) { + case 0: /* fault free */ + if (rf_suppressLocksAndLargeWrites || + (((asmap->numStripeUnitsAccessed <= (layoutPtr->numDataCol / 2)) && (layoutPtr->numDataCol != 1)) || + (asmap->parityInfo->next != NULL) || (asmap->qInfo->next != NULL) || rf_CheckStripeForFailures(raidPtr, asmap))) { + + *createFunc = (RF_VoidFuncPtr) rf_EOCreateSmallWriteDAG; + } else { + *createFunc = (RF_VoidFuncPtr) rf_EOCreateLargeWriteDAG; + } + break; + + case 1: /* single disk fault */ + if (npfail == 1) { + RF_ASSERT((asmap->failedPDAs[0]->type == RF_PDA_TYPE_PARITY) || (asmap->failedPDAs[0]->type == RF_PDA_TYPE_Q)); + if (asmap->failedPDAs[0]->type == RF_PDA_TYPE_Q) { /* q died, treat like + * normal mode raid5 + * write. */ + if (((asmap->numStripeUnitsAccessed <= (layoutPtr->numDataCol / 2)) || (asmap->numStripeUnitsAccessed == 1)) + || (asmap->parityInfo->next != NULL) || rf_NumFailedDataUnitsInStripe(raidPtr, asmap)) + *createFunc = (RF_VoidFuncPtr) rf_EO_001_CreateSmallWriteDAG; + else + *createFunc = (RF_VoidFuncPtr) rf_EO_001_CreateLargeWriteDAG; + } else {/* parity died, small write only updating Q */ + if (((asmap->numStripeUnitsAccessed <= (layoutPtr->numDataCol / 2)) || (asmap->numStripeUnitsAccessed == 1)) + || (asmap->qInfo->next != NULL) || rf_NumFailedDataUnitsInStripe(raidPtr, asmap)) + *createFunc = (RF_VoidFuncPtr) rf_EO_010_CreateSmallWriteDAG; + else + *createFunc = (RF_VoidFuncPtr) rf_EO_010_CreateLargeWriteDAG; + } + } else { /* data missing. Do a P reconstruct write if + * only a single data unit is lost in the + * stripe, otherwise a reconstruct write which + * employnig both P and E units. */ + if (rf_NumFailedDataUnitsInStripe(raidPtr, asmap) == 2) { + if (asmap->numStripeUnitsAccessed == 1) + *createFunc = (RF_VoidFuncPtr) rf_EO_200_CreateWriteDAG; + else + *createFunc = NULL; /* No direct support for + * this case now, like + * that in Raid-5 */ + } else { + if (asmap->numStripeUnitsAccessed != 1 && asmap->failedPDAs[0]->numSector != layoutPtr->sectorsPerStripeUnit) + *createFunc = NULL; /* No direct support for + * this case now, like + * that in Raid-5 */ + else + *createFunc = (RF_VoidFuncPtr) rf_EO_100_CreateWriteDAG; + } + } + break; + + case 2: /* two disk faults */ + switch (npfail) { + case 2: /* both p and q dead */ + *createFunc = (RF_VoidFuncPtr) rf_EO_011_CreateWriteDAG; + break; + case 1: /* either p or q and dead data */ + RF_ASSERT(asmap->failedPDAs[0]->type == RF_PDA_TYPE_DATA); + RF_ASSERT((asmap->failedPDAs[1]->type == RF_PDA_TYPE_PARITY) || (asmap->failedPDAs[1]->type == RF_PDA_TYPE_Q)); + if (asmap->failedPDAs[1]->type == RF_PDA_TYPE_Q) { + if (asmap->numStripeUnitsAccessed != 1 && asmap->failedPDAs[0]->numSector != layoutPtr->sectorsPerStripeUnit) + *createFunc = NULL; /* In both PQ and + * EvenOdd, no direct + * support for this case + * now, like that in + * Raid-5 */ + else + *createFunc = (RF_VoidFuncPtr) rf_EO_101_CreateWriteDAG; + } else { + if (asmap->numStripeUnitsAccessed != 1 && asmap->failedPDAs[0]->numSector != layoutPtr->sectorsPerStripeUnit) + *createFunc = NULL; /* No direct support for + * this case, like that + * in Raid-5 */ + else + *createFunc = (RF_VoidFuncPtr) rf_EO_110_CreateWriteDAG; + } + break; + case 0: /* double data loss */ + /* if(asmap->failedPDAs[0]->numSector + + * asmap->failedPDAs[1]->numSector == 2 * + * layoutPtr->sectorsPerStripeUnit ) createFunc = + * rf_EOCreateLargeWriteDAG; else */ + *createFunc = NULL; /* currently, in Evenodd, No + * support for simultaneous + * access of both failed SUs */ + break; + } + break; + + default: /* more than 2 disk faults */ + *createFunc = NULL; + RF_PANIC(); } - break; - - default: /* more than 2 disk faults */ - *createFunc = NULL; - RF_PANIC(); - } - return; + return; } -int rf_VerifyParityEvenOdd(raidPtr, raidAddr, parityPDA, correct_it, flags) - RF_Raid_t *raidPtr; - RF_RaidAddr_t raidAddr; - RF_PhysDiskAddr_t *parityPDA; - int correct_it; - RF_RaidAccessFlags_t flags; +int +rf_VerifyParityEvenOdd(raidPtr, raidAddr, parityPDA, correct_it, flags) + RF_Raid_t *raidPtr; + RF_RaidAddr_t raidAddr; + RF_PhysDiskAddr_t *parityPDA; + int correct_it; + RF_RaidAccessFlags_t flags; { - RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout); - RF_RaidAddr_t startAddr = rf_RaidAddressOfPrevStripeBoundary(layoutPtr, raidAddr); - RF_SectorCount_t numsector = parityPDA->numSector; - int numbytes = rf_RaidAddressToByte(raidPtr, numsector); - int bytesPerStripe = numbytes * layoutPtr->numDataCol; - RF_DagHeader_t *rd_dag_h, *wr_dag_h; /* read, write dag */ - RF_DagNode_t *blockNode, *unblockNode, *wrBlock, *wrUnblock; - RF_AccessStripeMapHeader_t *asm_h; - RF_AccessStripeMap_t *asmap; - RF_AllocListElem_t *alloclist; - RF_PhysDiskAddr_t *pda; - char *pbuf, *buf, *end_p, *p; - char *redundantbuf2; - int redundantTwoErr = 0, redundantOneErr = 0; - int parity_cant_correct = RF_FALSE, red2_cant_correct = RF_FALSE, parity_corrected = RF_FALSE, red2_corrected = RF_FALSE; - int i, retcode; - RF_ReconUnitNum_t which_ru; - RF_StripeNum_t psID = rf_RaidAddressToParityStripeID(layoutPtr, raidAddr, &which_ru); - int stripeWidth = layoutPtr->numDataCol + layoutPtr->numParityCol; - RF_AccTraceEntry_t tracerec; - RF_MCPair_t *mcpair; - - retcode = RF_PARITY_OKAY; - - mcpair = rf_AllocMCPair(); - rf_MakeAllocList(alloclist); - RF_MallocAndAdd(buf, numbytes * (layoutPtr->numDataCol + layoutPtr->numParityCol), (char *), alloclist); - RF_CallocAndAdd(pbuf, 1, numbytes, (char *), alloclist); /* use calloc to make sure buffer is zeroed */ - end_p = buf + bytesPerStripe; - RF_CallocAndAdd(redundantbuf2, 1, numbytes, (char *), alloclist); /* use calloc to make sure buffer is zeroed */ - - rd_dag_h = rf_MakeSimpleDAG(raidPtr, stripeWidth, numbytes, buf, rf_DiskReadFunc, rf_DiskReadUndoFunc, - "Rod", alloclist, flags, RF_IO_NORMAL_PRIORITY); - blockNode = rd_dag_h->succedents[0]; - unblockNode = blockNode->succedents[0]->succedents[0]; - - /* map the stripe and fill in the PDAs in the dag */ - asm_h = rf_MapAccess(raidPtr, startAddr, layoutPtr->dataSectorsPerStripe, buf, RF_DONT_REMAP); - asmap = asm_h->stripeMap; - - for (pda=asmap->physInfo,i=0; i<layoutPtr->numDataCol; i++,pda=pda->next) { - RF_ASSERT(pda); - rf_RangeRestrictPDA(raidPtr, parityPDA, pda, 0, 1); - RF_ASSERT(pda->numSector != 0); - if (rf_TryToRedirectPDA(raidPtr, pda, 0)) goto out; /* no way to verify parity if disk is dead. return w/ good status */ - blockNode->succedents[i]->params[0].p = pda; - blockNode->succedents[i]->params[2].v = psID; - blockNode->succedents[i]->params[3].v = RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY, 0, 0, which_ru); - } - - RF_ASSERT(!asmap->parityInfo->next); - rf_RangeRestrictPDA(raidPtr, parityPDA, asmap->parityInfo, 0, 1); - RF_ASSERT(asmap->parityInfo->numSector != 0); - if (rf_TryToRedirectPDA(raidPtr, asmap->parityInfo, 1)) - goto out; - blockNode->succedents[ layoutPtr->numDataCol ]->params[0].p = asmap->parityInfo; - - RF_ASSERT(!asmap->qInfo->next); - rf_RangeRestrictPDA(raidPtr, parityPDA, asmap->qInfo, 0, 1); - RF_ASSERT(asmap->qInfo->numSector != 0); - if (rf_TryToRedirectPDA(raidPtr, asmap->qInfo, 1)) goto out; - /* - * if disk is dead, b/c no reconstruction is implemented right now, - * the function "rf_TryToRedirectPDA" always return one, which cause - * go to out and return w/ good status - */ - blockNode->succedents[ layoutPtr->numDataCol +1 ]->params[0].p = asmap->qInfo; - - /* fire off the DAG */ - bzero((char *)&tracerec,sizeof(tracerec)); - rd_dag_h->tracerec = &tracerec; - - if (rf_verifyParityDebug) { - printf("Parity verify read dag:\n"); - rf_PrintDAGList(rd_dag_h); - } - - RF_LOCK_MUTEX(mcpair->mutex); - mcpair->flag = 0; - rf_DispatchDAG(rd_dag_h, (void (*)(void *))rf_MCPairWakeupFunc, - (void *) mcpair); - while (!mcpair->flag) RF_WAIT_COND(mcpair->cond, mcpair->mutex); - RF_UNLOCK_MUTEX(mcpair->mutex); - if (rd_dag_h->status != rf_enable) { - RF_ERRORMSG("Unable to verify parity: can't read the stripe\n"); - retcode = RF_PARITY_COULD_NOT_VERIFY; - goto out; - } - - for (p=buf, i=0; p<end_p; p+=numbytes, i++) { - rf_e_encToBuf(raidPtr, i, p, RF_EO_MATRIX_DIM - 2, redundantbuf2, numsector); - /* - * the corresponding columes in EvenOdd encoding Matrix for these p pointers which point - * to the databuffer in a full stripe are sequentially from 0 to layoutPtr->numDataCol-1 - */ - rf_bxor(p, pbuf, numbytes, NULL); - } - RF_ASSERT(i==layoutPtr->numDataCol); - - for (i=0; i<numbytes; i++) { - if (pbuf[i] != buf[bytesPerStripe+i]) { - if (!correct_it) { - RF_ERRORMSG3("Parity verify error: byte %d of parity is 0x%x should be 0x%x\n", - i,(u_char) buf[bytesPerStripe+i],(u_char) pbuf[i]); - } - } - redundantOneErr = 1; - break; - } - - for (i=0; i<numbytes; i++) { - if (redundantbuf2[i] != buf[bytesPerStripe+numbytes+i]) { - if (!correct_it) { - RF_ERRORMSG3("Parity verify error: byte %d of second redundant information is 0x%x should be 0x%x\n", - i,(u_char) buf[bytesPerStripe+numbytes+i],(u_char) redundantbuf2[i]); - } - redundantTwoErr = 1; - break; - } - } - if (redundantOneErr || redundantTwoErr ) - retcode = RF_PARITY_BAD; - - /* correct the first redundant disk, ie parity if it is error */ - if (redundantOneErr && correct_it) { - wr_dag_h = rf_MakeSimpleDAG(raidPtr, 1, numbytes, pbuf, rf_DiskWriteFunc, rf_DiskWriteUndoFunc, - "Wnp", alloclist, flags, RF_IO_NORMAL_PRIORITY); - wrBlock = wr_dag_h->succedents[0]; wrUnblock = wrBlock->succedents[0]->succedents[0]; - wrBlock->succedents[0]->params[0].p = asmap->parityInfo; - wrBlock->succedents[0]->params[2].v = psID; - wrBlock->succedents[0]->params[3].v = RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY, 0, 0, which_ru); - bzero((char *)&tracerec,sizeof(tracerec)); - wr_dag_h->tracerec = &tracerec; - if (rf_verifyParityDebug) { - printf("Parity verify write dag:\n"); - rf_PrintDAGList(wr_dag_h); - } - RF_LOCK_MUTEX(mcpair->mutex); - mcpair->flag = 0; - rf_DispatchDAG(wr_dag_h, (void (*)(void *))rf_MCPairWakeupFunc, - (void *) mcpair); - while (!mcpair->flag) - RF_WAIT_COND(mcpair->cond, mcpair->mutex); - RF_UNLOCK_MUTEX(mcpair->mutex); - if (wr_dag_h->status != rf_enable) { - RF_ERRORMSG("Unable to correct parity in VerifyParity: can't write the stripe\n"); - parity_cant_correct = RF_TRUE; - } else { - parity_corrected = RF_TRUE; - } - rf_FreeDAG(wr_dag_h); - } - - if (redundantTwoErr && correct_it) { - wr_dag_h = rf_MakeSimpleDAG(raidPtr, 1, numbytes, redundantbuf2, rf_DiskWriteFunc, rf_DiskWriteUndoFunc, - "Wnred2", alloclist, flags, RF_IO_NORMAL_PRIORITY); - wrBlock = wr_dag_h->succedents[0]; wrUnblock = wrBlock->succedents[0]->succedents[0]; - wrBlock->succedents[0]->params[0].p = asmap->qInfo; - wrBlock->succedents[0]->params[2].v = psID; - wrBlock->succedents[0]->params[3].v = RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY, 0, 0, which_ru); - bzero((char *)&tracerec,sizeof(tracerec)); - wr_dag_h->tracerec = &tracerec; - if (rf_verifyParityDebug) { - printf("Dag of write new second redundant information in parity verify :\n"); - rf_PrintDAGList(wr_dag_h); - } - RF_LOCK_MUTEX(mcpair->mutex); - mcpair->flag = 0; - rf_DispatchDAG(wr_dag_h, (void (*)(void *))rf_MCPairWakeupFunc, - (void *) mcpair); - while (!mcpair->flag) - RF_WAIT_COND(mcpair->cond, mcpair->mutex); - RF_UNLOCK_MUTEX(mcpair->mutex); - if (wr_dag_h->status != rf_enable) { - RF_ERRORMSG("Unable to correct second redundant information in VerifyParity: can't write the stripe\n"); - red2_cant_correct = RF_TRUE; - } else { - red2_corrected = RF_TRUE; - } - rf_FreeDAG(wr_dag_h); - } - if ( (redundantOneErr && parity_cant_correct) || - (redundantTwoErr && red2_cant_correct )) - retcode = RF_PARITY_COULD_NOT_CORRECT; - if ( (retcode = RF_PARITY_BAD) && parity_corrected && red2_corrected ) - retcode = RF_PARITY_CORRECTED; + RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout); + RF_RaidAddr_t startAddr = rf_RaidAddressOfPrevStripeBoundary(layoutPtr, raidAddr); + RF_SectorCount_t numsector = parityPDA->numSector; + int numbytes = rf_RaidAddressToByte(raidPtr, numsector); + int bytesPerStripe = numbytes * layoutPtr->numDataCol; + RF_DagHeader_t *rd_dag_h, *wr_dag_h; /* read, write dag */ + RF_DagNode_t *blockNode, *unblockNode, *wrBlock, *wrUnblock; + RF_AccessStripeMapHeader_t *asm_h; + RF_AccessStripeMap_t *asmap; + RF_AllocListElem_t *alloclist; + RF_PhysDiskAddr_t *pda; + char *pbuf, *buf, *end_p, *p; + char *redundantbuf2; + int redundantTwoErr = 0, redundantOneErr = 0; + int parity_cant_correct = RF_FALSE, red2_cant_correct = RF_FALSE, + parity_corrected = RF_FALSE, red2_corrected = RF_FALSE; + int i, retcode; + RF_ReconUnitNum_t which_ru; + RF_StripeNum_t psID = rf_RaidAddressToParityStripeID(layoutPtr, raidAddr, &which_ru); + int stripeWidth = layoutPtr->numDataCol + layoutPtr->numParityCol; + RF_AccTraceEntry_t tracerec; + RF_MCPair_t *mcpair; + + retcode = RF_PARITY_OKAY; + + mcpair = rf_AllocMCPair(); + rf_MakeAllocList(alloclist); + RF_MallocAndAdd(buf, numbytes * (layoutPtr->numDataCol + layoutPtr->numParityCol), (char *), alloclist); + RF_CallocAndAdd(pbuf, 1, numbytes, (char *), alloclist); /* use calloc to make + * sure buffer is zeroed */ + end_p = buf + bytesPerStripe; + RF_CallocAndAdd(redundantbuf2, 1, numbytes, (char *), alloclist); /* use calloc to make + * sure buffer is zeroed */ + + rd_dag_h = rf_MakeSimpleDAG(raidPtr, stripeWidth, numbytes, buf, rf_DiskReadFunc, rf_DiskReadUndoFunc, + "Rod", alloclist, flags, RF_IO_NORMAL_PRIORITY); + blockNode = rd_dag_h->succedents[0]; + unblockNode = blockNode->succedents[0]->succedents[0]; + + /* map the stripe and fill in the PDAs in the dag */ + asm_h = rf_MapAccess(raidPtr, startAddr, layoutPtr->dataSectorsPerStripe, buf, RF_DONT_REMAP); + asmap = asm_h->stripeMap; + + for (pda = asmap->physInfo, i = 0; i < layoutPtr->numDataCol; i++, pda = pda->next) { + RF_ASSERT(pda); + rf_RangeRestrictPDA(raidPtr, parityPDA, pda, 0, 1); + RF_ASSERT(pda->numSector != 0); + if (rf_TryToRedirectPDA(raidPtr, pda, 0)) + goto out; /* no way to verify parity if disk is + * dead. return w/ good status */ + blockNode->succedents[i]->params[0].p = pda; + blockNode->succedents[i]->params[2].v = psID; + blockNode->succedents[i]->params[3].v = RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY, 0, 0, which_ru); + } + + RF_ASSERT(!asmap->parityInfo->next); + rf_RangeRestrictPDA(raidPtr, parityPDA, asmap->parityInfo, 0, 1); + RF_ASSERT(asmap->parityInfo->numSector != 0); + if (rf_TryToRedirectPDA(raidPtr, asmap->parityInfo, 1)) + goto out; + blockNode->succedents[layoutPtr->numDataCol]->params[0].p = asmap->parityInfo; + + RF_ASSERT(!asmap->qInfo->next); + rf_RangeRestrictPDA(raidPtr, parityPDA, asmap->qInfo, 0, 1); + RF_ASSERT(asmap->qInfo->numSector != 0); + if (rf_TryToRedirectPDA(raidPtr, asmap->qInfo, 1)) + goto out; + /* if disk is dead, b/c no reconstruction is implemented right now, + * the function "rf_TryToRedirectPDA" always return one, which cause + * go to out and return w/ good status */ + blockNode->succedents[layoutPtr->numDataCol + 1]->params[0].p = asmap->qInfo; + + /* fire off the DAG */ + bzero((char *) &tracerec, sizeof(tracerec)); + rd_dag_h->tracerec = &tracerec; + + if (rf_verifyParityDebug) { + printf("Parity verify read dag:\n"); + rf_PrintDAGList(rd_dag_h); + } + RF_LOCK_MUTEX(mcpair->mutex); + mcpair->flag = 0; + rf_DispatchDAG(rd_dag_h, (void (*) (void *)) rf_MCPairWakeupFunc, + (void *) mcpair); + while (!mcpair->flag) + RF_WAIT_COND(mcpair->cond, mcpair->mutex); + RF_UNLOCK_MUTEX(mcpair->mutex); + if (rd_dag_h->status != rf_enable) { + RF_ERRORMSG("Unable to verify parity: can't read the stripe\n"); + retcode = RF_PARITY_COULD_NOT_VERIFY; + goto out; + } + for (p = buf, i = 0; p < end_p; p += numbytes, i++) { + rf_e_encToBuf(raidPtr, i, p, RF_EO_MATRIX_DIM - 2, redundantbuf2, numsector); + /* the corresponding columes in EvenOdd encoding Matrix for + * these p pointers which point to the databuffer in a full + * stripe are sequentially from 0 to layoutPtr->numDataCol-1 */ + rf_bxor(p, pbuf, numbytes, NULL); + } + RF_ASSERT(i == layoutPtr->numDataCol); + + for (i = 0; i < numbytes; i++) { + if (pbuf[i] != buf[bytesPerStripe + i]) { + if (!correct_it) { + RF_ERRORMSG3("Parity verify error: byte %d of parity is 0x%x should be 0x%x\n", + i, (u_char) buf[bytesPerStripe + i], (u_char) pbuf[i]); + } + } + redundantOneErr = 1; + break; + } + + for (i = 0; i < numbytes; i++) { + if (redundantbuf2[i] != buf[bytesPerStripe + numbytes + i]) { + if (!correct_it) { + RF_ERRORMSG3("Parity verify error: byte %d of second redundant information is 0x%x should be 0x%x\n", + i, (u_char) buf[bytesPerStripe + numbytes + i], (u_char) redundantbuf2[i]); + } + redundantTwoErr = 1; + break; + } + } + if (redundantOneErr || redundantTwoErr) + retcode = RF_PARITY_BAD; + + /* correct the first redundant disk, ie parity if it is error */ + if (redundantOneErr && correct_it) { + wr_dag_h = rf_MakeSimpleDAG(raidPtr, 1, numbytes, pbuf, rf_DiskWriteFunc, rf_DiskWriteUndoFunc, + "Wnp", alloclist, flags, RF_IO_NORMAL_PRIORITY); + wrBlock = wr_dag_h->succedents[0]; + wrUnblock = wrBlock->succedents[0]->succedents[0]; + wrBlock->succedents[0]->params[0].p = asmap->parityInfo; + wrBlock->succedents[0]->params[2].v = psID; + wrBlock->succedents[0]->params[3].v = RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY, 0, 0, which_ru); + bzero((char *) &tracerec, sizeof(tracerec)); + wr_dag_h->tracerec = &tracerec; + if (rf_verifyParityDebug) { + printf("Parity verify write dag:\n"); + rf_PrintDAGList(wr_dag_h); + } + RF_LOCK_MUTEX(mcpair->mutex); + mcpair->flag = 0; + rf_DispatchDAG(wr_dag_h, (void (*) (void *)) rf_MCPairWakeupFunc, + (void *) mcpair); + while (!mcpair->flag) + RF_WAIT_COND(mcpair->cond, mcpair->mutex); + RF_UNLOCK_MUTEX(mcpair->mutex); + if (wr_dag_h->status != rf_enable) { + RF_ERRORMSG("Unable to correct parity in VerifyParity: can't write the stripe\n"); + parity_cant_correct = RF_TRUE; + } else { + parity_corrected = RF_TRUE; + } + rf_FreeDAG(wr_dag_h); + } + if (redundantTwoErr && correct_it) { + wr_dag_h = rf_MakeSimpleDAG(raidPtr, 1, numbytes, redundantbuf2, rf_DiskWriteFunc, rf_DiskWriteUndoFunc, + "Wnred2", alloclist, flags, RF_IO_NORMAL_PRIORITY); + wrBlock = wr_dag_h->succedents[0]; + wrUnblock = wrBlock->succedents[0]->succedents[0]; + wrBlock->succedents[0]->params[0].p = asmap->qInfo; + wrBlock->succedents[0]->params[2].v = psID; + wrBlock->succedents[0]->params[3].v = RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY, 0, 0, which_ru); + bzero((char *) &tracerec, sizeof(tracerec)); + wr_dag_h->tracerec = &tracerec; + if (rf_verifyParityDebug) { + printf("Dag of write new second redundant information in parity verify :\n"); + rf_PrintDAGList(wr_dag_h); + } + RF_LOCK_MUTEX(mcpair->mutex); + mcpair->flag = 0; + rf_DispatchDAG(wr_dag_h, (void (*) (void *)) rf_MCPairWakeupFunc, + (void *) mcpair); + while (!mcpair->flag) + RF_WAIT_COND(mcpair->cond, mcpair->mutex); + RF_UNLOCK_MUTEX(mcpair->mutex); + if (wr_dag_h->status != rf_enable) { + RF_ERRORMSG("Unable to correct second redundant information in VerifyParity: can't write the stripe\n"); + red2_cant_correct = RF_TRUE; + } else { + red2_corrected = RF_TRUE; + } + rf_FreeDAG(wr_dag_h); + } + if ((redundantOneErr && parity_cant_correct) || + (redundantTwoErr && red2_cant_correct)) + retcode = RF_PARITY_COULD_NOT_CORRECT; + if ((retcode = RF_PARITY_BAD) && parity_corrected && red2_corrected) + retcode = RF_PARITY_CORRECTED; out: - rf_FreeAccessStripeMap(asm_h); - rf_FreeAllocList(alloclist); - rf_FreeDAG(rd_dag_h); - rf_FreeMCPair(mcpair); - return(retcode); + rf_FreeAccessStripeMap(asm_h); + rf_FreeAllocList(alloclist); + rf_FreeDAG(rd_dag_h); + rf_FreeMCPair(mcpair); + return (retcode); } - -#endif /* RF_INCLUDE_EVENODD > 0 */ +#endif /* RF_INCLUDE_EVENODD > 0 */ |