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

📄 rf_map.c

📁 RAIDFrame是个非常好的磁盘阵列RAID仿真工具
💻 C
📖 第 1 页 / 共 3 页
字号:
  int                    count;{	RF_FREELIST_FREE_N(rf_asm_freelist,l_start,next,(RF_AccessStripeMap_t *),count);}void rf_FreeAccessStripeMap(hdr)  RF_AccessStripeMapHeader_t  *hdr;{  RF_AccessStripeMap_t *p, *pt;  RF_PhysDiskAddr_t *pdp, *trailer, *pdaList = NULL, *pdaEnd;  int count = 0, t, asm_count = 0;  for (p = hdr->stripeMap; p; p=p->next) {        /* link the 3 pda lists into the accumulating pda list */        if (!pdaList) pdaList = p->qInfo; else pdaEnd->next = p->qInfo;    for (trailer=NULL,pdp=p->qInfo; pdp; ) {trailer = pdp; pdp=pdp->next; count++;}    if (trailer) pdaEnd = trailer;        if (!pdaList) pdaList = p->parityInfo; else pdaEnd->next = p->parityInfo;    for (trailer=NULL,pdp=p->parityInfo; pdp; ) {trailer = pdp; pdp=pdp->next; count++;}    if (trailer) pdaEnd = trailer;    if (!pdaList) pdaList = p->physInfo; else pdaEnd->next = p->physInfo;    for (trailer=NULL,pdp=p->physInfo; pdp; ) {trailer = pdp; pdp=pdp->next; count++;}    if (trailer) pdaEnd = trailer;    pt = p;    asm_count++;  }    /* debug only */  for (t=0,pdp=pdaList; pdp; pdp=pdp->next)    t++;  RF_ASSERT(t == count);  if (pdaList)    rf_FreePDAList(pdaList, pdaEnd, count);  rf_FreeASMList(hdr->stripeMap, pt, asm_count);  rf_FreeAccessStripeMapHeader(hdr);}/* We can't use the large write optimization if there are any failures in the stripe. * In the declustered layout, there is no way to immediately determine what disks * constitute a stripe, so we actually have to hunt through the stripe looking for failures. * The reason we map the parity instead of just using asm->parityInfo->col is because * the latter may have been already redirected to a spare drive, which would * mess up the computation of the stripe offset. * * ASSUMES AT MOST ONE FAILURE IN THE STRIPE. */int rf_CheckStripeForFailures(raidPtr, asmap)  RF_Raid_t             *raidPtr;  RF_AccessStripeMap_t  *asmap;{  RF_RowCol_t trow, tcol, prow, pcol, *diskids, row, i;  RF_RaidLayout_t *layoutPtr = &raidPtr->Layout;  RF_StripeCount_t stripeOffset;  int numFailures;  RF_RaidAddr_t sosAddr;  RF_SectorNum_t diskOffset, poffset;  RF_RowCol_t testrow;  /* quick out in the fault-free case.  */  RF_LOCK_MUTEX(raidPtr->mutex);  numFailures = raidPtr->numFailures;  RF_UNLOCK_MUTEX(raidPtr->mutex);  if (numFailures == 0) return(0);  sosAddr = rf_RaidAddressOfPrevStripeBoundary(layoutPtr, asmap->raidAddress);  row = asmap->physInfo->row;  (layoutPtr->map->IdentifyStripe)(raidPtr, asmap->raidAddress, &diskids, &testrow);  (layoutPtr->map->MapParity)(raidPtr, asmap->raidAddress, &prow, &pcol, &poffset, 0);  /* get pcol */    /* this need not be true if we've redirected the access to a spare in another row   RF_ASSERT(row == testrow);  */  stripeOffset = 0;  for (i=0; i<layoutPtr->numDataCol+layoutPtr->numParityCol; i++) {    if (diskids[i] != pcol) {      if (RF_DEAD_DISK(raidPtr->Disks[testrow][diskids[i]].status)) {        if (raidPtr->status[testrow] != rf_rs_reconstructing)          return(1);        RF_ASSERT(raidPtr->reconControl[testrow]->fcol == diskids[i]);        layoutPtr->map->MapSector(raidPtr,          sosAddr + stripeOffset * layoutPtr->sectorsPerStripeUnit,          &trow, &tcol, &diskOffset, 0);        RF_ASSERT( (trow == testrow) && (tcol == diskids[i]) );        if (!rf_CheckRUReconstructed(raidPtr->reconControl[testrow]->reconMap, diskOffset))          return(1);        asmap->flags |= RF_ASM_REDIR_LARGE_WRITE;        return(0);      }      stripeOffset++;    }  }  return(0);}/*   return the number of failed data units in the stripe.*/int rf_NumFailedDataUnitsInStripe(raidPtr, asmap)  RF_Raid_t             *raidPtr;  RF_AccessStripeMap_t  *asmap;{  RF_RaidLayout_t *layoutPtr = &raidPtr->Layout;  RF_RowCol_t trow, tcol, row, i;  RF_SectorNum_t diskOffset;  RF_RaidAddr_t sosAddr;  int numFailures;  /* quick out in the fault-free case.  */  RF_LOCK_MUTEX(raidPtr->mutex);  numFailures = raidPtr->numFailures;  RF_UNLOCK_MUTEX(raidPtr->mutex);  if (numFailures == 0) return(0);  numFailures = 0;  sosAddr = rf_RaidAddressOfPrevStripeBoundary(layoutPtr, asmap->raidAddress);  row = asmap->physInfo->row;  for (i=0; i<layoutPtr->numDataCol; i++)     {      (layoutPtr->map->MapSector)(raidPtr, sosAddr + i * layoutPtr->sectorsPerStripeUnit, 				  &trow, &tcol, &diskOffset, 0);      if (RF_DEAD_DISK(raidPtr->Disks[trow][tcol].status)) 	numFailures++;    }  return numFailures;}/***************************************************************************************** * * debug routines * ****************************************************************************************/void rf_PrintAccessStripeMap(asm_h)  RF_AccessStripeMapHeader_t  *asm_h;{  rf_PrintFullAccessStripeMap(asm_h, 0);}void rf_PrintFullAccessStripeMap(asm_h, prbuf)  RF_AccessStripeMapHeader_t  *asm_h;  int                          prbuf; /* flag to print buffer pointers */{  int i;  RF_AccessStripeMap_t *asmap = asm_h->stripeMap;  RF_PhysDiskAddr_t *p;  printf("%d stripes total\n", asm_h->numStripes);  for (; asmap; asmap = asmap->next) {    printf("Stripe %ld (%d sectors), failures: %d data, %d parity: ",	   asmap->stripeID,asmap->totalSectorsAccessed,asmap->numDataFailed,asmap->numParityFailed);    if (asmap->parityInfo) {      printf("Parity [r%d c%d s%d-%d", asmap->parityInfo->row, asmap->parityInfo->col,	     asmap->parityInfo->startSector, asmap->parityInfo->startSector + asmap->parityInfo->numSector - 1);      if (prbuf) printf(" b0x%lx",(unsigned long) asmap->parityInfo->bufPtr);      if (asmap->parityInfo->next) {	printf(", r%d c%d s%d-%d", asmap->parityInfo->next->row, asmap->parityInfo->next->col,	       asmap->parityInfo->next->startSector, asmap->parityInfo->next->startSector + asmap->parityInfo->next->numSector - 1);	if (prbuf) printf(" b0x%lx",(unsigned long) asmap->parityInfo->next->bufPtr);	RF_ASSERT(asmap->parityInfo->next->next == NULL);      }      printf("]\n\t");    }    for (i=0,p=asmap->physInfo; p; p=p->next,i++) {      printf("SU r%d c%d s%d-%d ", p->row, p->col, p->startSector, p->startSector + p->numSector - 1);      if (prbuf) printf("b0x%lx ", (unsigned long) p->bufPtr);      if (i && !(i&1)) printf("\n\t");    }    printf("\n");    p = asm_h->stripeMap->failedPDA;    if (asm_h->stripeMap->numDataFailed + asm_h->stripeMap->numParityFailed > 1) printf("[multiple failures]\n");    else if (asm_h->stripeMap->numDataFailed + asm_h->stripeMap->numParityFailed > 0)      printf("\t[Failed PDA: r%d c%d s%d-%d]\n",p->row, p->col, p->startSector, p->startSector + p->numSector-1);  }}void rf_PrintRaidAddressInfo(raidPtr, raidAddr, numBlocks)  RF_Raid_t         *raidPtr;  RF_RaidAddr_t      raidAddr;  RF_SectorCount_t   numBlocks;{  RF_RaidLayout_t *layoutPtr = &raidPtr->Layout;  RF_RaidAddr_t ra, sosAddr  = rf_RaidAddressOfPrevStripeBoundary(layoutPtr, raidAddr);  printf("Raid addrs of SU boundaries from start of stripe to end of access:\n\t");  for (ra = sosAddr; ra <= raidAddr + numBlocks; ra += layoutPtr->sectorsPerStripeUnit) {    printf("%ld (0x%lx), ",ra, ra);  }  printf("\n");  printf("Offset into stripe unit: %ld (0x%lx)\n",	raidAddr % layoutPtr->sectorsPerStripeUnit,raidAddr % layoutPtr->sectorsPerStripeUnit);}/*   given a parity descriptor and the starting address within a stripe,   range restrict the parity descriptor to touch only the correct stuff.*/void rf_ASMParityAdjust(  RF_PhysDiskAddr_t     *toAdjust,   RF_StripeNum_t         startAddrWithinStripe,   RF_SectorNum_t         endAddress,   RF_RaidLayout_t       *layoutPtr,   RF_AccessStripeMap_t  *asm_p){  RF_PhysDiskAddr_t *new_pda;  /* when we're accessing only a portion of one stripe unit, we want the parity descriptor   * to identify only the chunk of parity associated with the data.  When the access spans   * exactly one stripe unit boundary and is less than a stripe unit in size, it uses two disjoint   * regions of the parity unit.  When an access spans more than one stripe unit boundary, it   * uses all of the parity unit.   *   * To better handle the case where stripe units are small, we may eventually want to change   * the 2nd case so that if the SU size is below some threshold, we just read/write the whole   * thing instead of breaking it up into two accesses.   */  if (asm_p->numStripeUnitsAccessed == 1)     {      int x = (startAddrWithinStripe % layoutPtr->sectorsPerStripeUnit);      toAdjust->startSector += x;      toAdjust->raidAddress += x;      toAdjust->numSector = asm_p->physInfo->numSector;      RF_ASSERT(toAdjust->numSector != 0);    }   else     if (asm_p->numStripeUnitsAccessed == 2 && asm_p->totalSectorsAccessed < layoutPtr->sectorsPerStripeUnit)       {	int x = (startAddrWithinStripe % layoutPtr->sectorsPerStripeUnit);		/* create a second pda and copy the parity map info into it */	RF_ASSERT(toAdjust->next == NULL);	new_pda = toAdjust->next = rf_AllocPhysDiskAddr();	*new_pda = *toAdjust; /* structure assignment */	new_pda->next = NULL;	  	/* adjust the start sector & number of blocks for the first parity pda */	toAdjust->startSector += x;	toAdjust->raidAddress += x;	toAdjust->numSector = rf_RaidAddressOfNextStripeUnitBoundary(layoutPtr, startAddrWithinStripe) - startAddrWithinStripe;	RF_ASSERT(toAdjust->numSector != 0);	/* adjust the second pda */	new_pda->numSector = endAddress - rf_RaidAddressOfPrevStripeUnitBoundary(layoutPtr, endAddress);	/*new_pda->raidAddress = rf_RaidAddressOfNextStripeUnitBoundary(layoutPtr, toAdjust->raidAddress);*/	RF_ASSERT(new_pda->numSector != 0);      }}/*   Check if a disk has been spared or failed. If spared,   redirect the I/O.    If it has been failed, record it in the asm pointer.   Fourth arg is whether data or parity.*/void rf_ASMCheckStatus(  RF_Raid_t              *raidPtr,  RF_PhysDiskAddr_t      *pda_p,  RF_AccessStripeMap_t   *asm_p,  RF_RaidDisk_t         **disks,  int                     parity){  RF_DiskStatus_t dstatus;  RF_RowCol_t frow, fcol;  dstatus = disks[pda_p->row][pda_p->col].status;  if (dstatus == rf_ds_spared) {        /* if the disk has been spared, redirect access to the spare */    frow = pda_p->row; fcol = pda_p->col;    pda_p->row = disks[frow][fcol].spareRow;    pda_p->col = disks[frow][fcol].spareCol;  } else if (dstatus == rf_ds_dist_spared) {   /* ditto if disk has been spared to dist spare space */    RF_RowCol_t or = pda_p->row, oc=pda_p->col;    RF_SectorNum_t oo = pda_p->startSector;    if (pda_p -> type == RF_PDA_TYPE_DATA)      raidPtr->Layout.map->MapSector(raidPtr, pda_p->raidAddress, &pda_p->row, &pda_p->col, &pda_p->startSector, RF_REMAP);    else      raidPtr->Layout.map->MapParity(raidPtr, pda_p->raidAddress, &pda_p->row, &pda_p->col, &pda_p->startSector, RF_REMAP);    if (rf_mapDebug) printf("Redirected r %d c %d o %ld -> r%d c %d o %ld\n",or,oc,oo,			 pda_p->row,pda_p->col,pda_p->startSector);  } else if (RF_DEAD_DISK(dstatus)) {   /* if the disk is inaccessible, mark the failure */    if (parity)      asm_p->numParityFailed++;    else      asm_p->numDataFailed++;    switch (asm_p->numParityFailed + asm_p->numDataFailed)      {      case 1:	asm_p->failedPDA = pda_p;	break;      case 2:	asm_p->failedPDAtwo = pda_p;      default:	break;      }  }  /* the redirected access should never span a stripe unit boundary */  RF_ASSERT(rf_RaidAddressToStripeUnitID(&raidPtr->Layout,pda_p->raidAddress) ==	 rf_RaidAddressToStripeUnitID(&raidPtr->Layout,pda_p->raidAddress + pda_p->numSector -1));  RF_ASSERT(pda_p->col != -1);}

⌨️ 快捷键说明

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