⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rf_evenodd.c

📁 RAIDFrame是个非常好的磁盘阵列RAID仿真工具
💻 C
📖 第 1 页 / 共 2 页
字号:
	      else		*createFunc = 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_EO_010_CreateSmallWriteDAG;	      else		*createFunc = 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_EO_200_CreateWriteDAG;            else              *createFunc = NULL;  /* No direct support for this case now, like that in Raid-5  */          }	  else          {            if (asmap->numStripeUnitsAccessed != 1 && asmap->failedPDA->numSector != layoutPtr->sectorsPerStripeUnit)                   *createFunc = NULL; /* No direct support for this case now, like that in Raid-5  */            else   *createFunc = rf_EO_100_CreateWriteDAG;          }	}      break;    case 2: /* two disk faults */      switch (npfail)	{	case 2: /* both p and q dead */	  *createFunc = rf_EO_011_CreateWriteDAG;	  break;	case 1: /* either p or q and dead data */	  RF_ASSERT(asmap->failedPDA->type == RF_PDA_TYPE_DATA);	  RF_ASSERT ((asmap->failedPDAtwo->type == RF_PDA_TYPE_PARITY) ||  (asmap->failedPDAtwo->type == RF_PDA_TYPE_Q));	  if (asmap->failedPDAtwo->type == RF_PDA_TYPE_Q)          {	    if(asmap->numStripeUnitsAccessed != 1 && asmap->failedPDA->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_EO_101_CreateWriteDAG;          }	  else          {            if (asmap->numStripeUnitsAccessed != 1 && asmap->failedPDA->numSector != layoutPtr->sectorsPerStripeUnit)                *createFunc = NULL; /* No direct support for this case, like that in Raid-5  */            else	        *createFunc = rf_EO_110_CreateWriteDAG;	  }	  break;	case 0: /* double data loss */        /*  if(asmap->failedPDA->numSector + asmap->failedPDAtwo->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();    }  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;{  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, 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, 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, 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);}#endif /* RF_INCLUDE_EVENODD > 0 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -