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

📄 rf_decluster.c

📁 RAIDFrame是个非常好的磁盘阵列RAID仿真工具
💻 C
📖 第 1 页 / 共 3 页
字号:
        RF_ASSERT( *col != -1 );}/* returns an array of ints identifying the disks that comprise the stripe containing the indicated address. * the caller must _never_ attempt to modify this array. */void rf_IdentifyStripeDeclustered(  RF_Raid_t        *raidPtr,  RF_RaidAddr_t     addr,  RF_RowCol_t     **diskids,  RF_RowCol_t      *outRow){  RF_RaidLayout_t *layoutPtr           = &(raidPtr->Layout);  RF_DeclusteredConfigInfo_t *info     = (RF_DeclusteredConfigInfo_t *) layoutPtr->layoutSpecificInfo;  RF_StripeCount_t sus_per_fulltable   = info->SUsPerFullTable;  RF_StripeCount_t fulltable_depth     = info->FullTableDepthInPUs * layoutPtr->SUsPerPU;  RF_StripeNum_t  base_suid            = 0;  RF_StripeNum_t SUID                  = rf_RaidAddressToStripeUnitID(layoutPtr, addr);  RF_StripeNum_t stripeID, FullTableID;  int tableOffset;  rf_decluster_adjust_params(layoutPtr, &SUID, &sus_per_fulltable, &fulltable_depth, &base_suid);  FullTableID     = SUID / sus_per_fulltable;		/* fulltable ID within array (across rows) */  *outRow         = FullTableID % raidPtr->numRow;  stripeID        = rf_StripeUnitIDToStripeID(layoutPtr, SUID);                     /* find stripe offset into array */  tableOffset     = (stripeID % info->BlocksPerTable);                        /* find offset into block design table */  *diskids        = info->LayoutTable[tableOffset];}/* This returns the default head-separation limit, which is measured * in "required units for reconstruction".  Each time a disk fetches * a unit, it bumps a counter.  The head-sep code prohibits any disk * from getting more than headSepLimit counter values ahead of any  * other. * * We assume here that the number of floating recon buffers is already * set.  There are r stripes to be reconstructed in each table, and so * if we have a total of B buffers, we can have at most B/r tables * under recon at any one time.  In each table, lambda units are required * from each disk, so given B buffers, the head sep limit has to be * (lambda*B)/r units.  We subtract one to avoid weird boundary cases. *  * for example, suppose were given 50 buffers, r=19, and lambda=4 as in * the 20.5 design.  There are 19 stripes/table to be reconstructed, so * we can have 50/19 tables concurrently under reconstruction, which means * we can allow the fastest disk to get 50/19 tables ahead of the slower * disk.  There are lambda "required units" for each disk, so the fastest * disk can get 4*50/19 = 10 counter values ahead of the slowest. * * If numBufsToAccumulate is not 1, we need to limit the head sep further * because multiple bufs will be required for each stripe under recon. */RF_HeadSepLimit_t rf_GetDefaultHeadSepLimitDeclustered(  RF_Raid_t  *raidPtr){  RF_DeclusteredConfigInfo_t *info = (RF_DeclusteredConfigInfo_t *) raidPtr->Layout.layoutSpecificInfo;  return(info->Lambda * raidPtr->numFloatingReconBufs / info->TableDepthInPUs / rf_numBufsToAccumulate);}/* returns the default number of recon buffers to use.  The value * is somewhat arbitrary...it's intended to be large enough to allow * for a reasonably large head-sep limit, but small enough that you * don't use up all your system memory with buffers. */int rf_GetDefaultNumFloatingReconBuffersDeclustered(RF_Raid_t *raidPtr){  return(100 * rf_numBufsToAccumulate);}/* sectors in the last fulltable of the array need to be handled * specially since this fulltable can be incomplete.  this function * changes the values of certain params to handle this. * * the idea here is that MapSector et. al. figure out which disk the * addressed unit lives on by computing the modulos of the unit number * with the number of units per fulltable, table, etc.  In the last * fulltable, there are fewer units per fulltable, so we need to adjust * the number of user data units per fulltable to reflect this. * * so, we (1) convert the fulltable size and depth parameters to * the size of the partial fulltable at the end, (2) compute the * disk sector offset where this fulltable starts, and (3) convert * the users stripe unit number from an offset into the array to * an offset into the last fulltable. */void rf_decluster_adjust_params(  RF_RaidLayout_t   *layoutPtr,  RF_StripeNum_t    *SUID,  RF_StripeCount_t  *sus_per_fulltable,  RF_StripeCount_t  *fulltable_depth,  RF_StripeNum_t    *base_suid){    RF_DeclusteredConfigInfo_t *info = (RF_DeclusteredConfigInfo_t *) layoutPtr->layoutSpecificInfo;    char pc = layoutPtr->map->parityConfig;    if (*SUID >= info->FullTableLimitSUID) {	/* new full table size is size of last full table on disk */	*sus_per_fulltable = info->ExtraTablesPerDisk * info->SUsPerTable;	/* new full table depth is corresponding depth */	*fulltable_depth = info->ExtraTablesPerDisk * info->TableDepthInPUs * layoutPtr->SUsPerPU;	/* set up the new base offset */	*base_suid = info->DiskOffsetOfLastFullTableInSUs;	/* convert users array address to an offset into the last fulltable */	*SUID -= info->FullTableLimitSUID;    }}/* * map a stripe ID to a parity stripe ID. * See comment above RaidAddressToParityStripeID in layout.c. */void rf_MapSIDToPSIDDeclustered(  RF_RaidLayout_t    *layoutPtr,  RF_StripeNum_t      stripeID,  RF_StripeNum_t     *psID,  RF_ReconUnitNum_t  *which_ru){    RF_DeclusteredConfigInfo_t *info;    info = (RF_DeclusteredConfigInfo_t *) layoutPtr->layoutSpecificInfo;        *psID = (stripeID / (layoutPtr->SUsPerPU * info->BlocksPerTable))        * info->BlocksPerTable + (stripeID % info->BlocksPerTable);    *which_ru = (stripeID % (info->BlocksPerTable * layoutPtr->SUsPerPU))        / info->BlocksPerTable;    RF_ASSERT( (*which_ru) < layoutPtr->SUsPerPU/layoutPtr->SUsPerRU);}/* * Called from MapSector and MapParity to retarget an access at the spare unit. * Modifies the "col" and "outSU" parameters only. */void rf_remap_to_spare_space(  RF_RaidLayout_t             *layoutPtr,  RF_DeclusteredConfigInfo_t  *info,  RF_RowCol_t                  row,  RF_StripeNum_t               FullTableID,  RF_StripeNum_t               TableID,  RF_SectorNum_t               BlockID,  RF_StripeNum_t               base_suid,  RF_StripeNum_t               SpareRegion,  RF_RowCol_t                 *outCol,  RF_StripeNum_t              *outSU){    RF_StripeNum_t ftID, spareTableStartSU, TableInSpareRegion, lastSROffset, which_ft;    /*     * note that FullTableID and hence SpareRegion may have gotten     * tweaked by rf_decluster_adjust_params. We detect this by     * noticing that base_suid is not 0.     */    if (base_suid == 0) {      ftID = FullTableID;    }    else {      /*       * There may be > 1.0 full tables in the last (i.e. partial)       * spare region.  find out which of these we're in.       */      lastSROffset = info->NumCompleteSRs * info->SpareRegionDepthInSUs;      which_ft = (info->DiskOffsetOfLastFullTableInSUs - lastSROffset) / (info->FullTableDepthInPUs * layoutPtr->SUsPerPU);      /* compute the actual full table ID */      ftID = info->DiskOffsetOfLastFullTableInSUs / (info->FullTableDepthInPUs * layoutPtr->SUsPerPU) + which_ft;      SpareRegion = info->NumCompleteSRs;    }    TableInSpareRegion = (ftID * info->NumParityReps + TableID) % info->TablesPerSpareRegion;	    *outCol = info->SpareTable[TableInSpareRegion][BlockID].spareDisk;    RF_ASSERT( *outCol != -1);	    spareTableStartSU = (SpareRegion == info->NumCompleteSRs) ?	    info->DiskOffsetOfLastFullTableInSUs + info->ExtraTablesPerDisk * info->TableDepthInPUs * layoutPtr->SUsPerPU :	    (SpareRegion+1) * info->SpareRegionDepthInSUs - info->SpareSpaceDepthPerRegionInSUs;    *outSU = spareTableStartSU + info->SpareTable[TableInSpareRegion][BlockID].spareBlockOffsetInSUs;    if (*outSU >= layoutPtr->stripeUnitsPerDisk) {	printf("rf_remap_to_spare_space: invalid remapped disk SU offset %ld\n",*outSU);    }}int rf_InstallSpareTable(  RF_Raid_t    *raidPtr,  RF_RowCol_t   frow,  RF_RowCol_t   fcol){  RF_DeclusteredConfigInfo_t *info = (RF_DeclusteredConfigInfo_t *) raidPtr->Layout.layoutSpecificInfo;  RF_SparetWait_t *req;  int retcode;  RF_Malloc(req, sizeof(*req), (RF_SparetWait_t *));  req->C                             = raidPtr->numCol;  req->G                             = raidPtr->Layout.numDataCol + raidPtr->Layout.numParityCol;  req->fcol                          = fcol;  req->SUsPerPU                      = raidPtr->Layout.SUsPerPU;  req->TablesPerSpareRegion          = info->TablesPerSpareRegion;  req->BlocksPerTable                = info->BlocksPerTable;  req->TableDepthInPUs               = info->TableDepthInPUs;  req->SpareSpaceDepthPerRegionInSUs = info->SpareSpaceDepthPerRegionInSUs;#ifndef KERNEL  info->SpareTable = rf_ReadSpareTable(req, info->sparemap_fname);  RF_Free(req, sizeof(*req));  retcode = (info->SpareTable) ? 0 : 1;#else /* !KERNEL */  retcode = rf_GetSpareTableFromDaemon(req);  RF_ASSERT(!retcode);                                     /* XXX -- fix this to recover gracefully -- XXX */#endif /* !KERNEL */  return(retcode);}#ifdef KERNEL/* * Invoked via ioctl to install a spare table in the kernel. */int rf_SetSpareTable(raidPtr, data)  RF_Raid_t  *raidPtr;  void       *data;{  RF_DeclusteredConfigInfo_t *info = (RF_DeclusteredConfigInfo_t *) raidPtr->Layout.layoutSpecificInfo;  RF_SpareTableEntry_t **ptrs;  int i, retcode;  /* what we need to copyin is a 2-d array, so first copyin the user pointers to the rows in the table */  RF_Malloc(ptrs, info->TablesPerSpareRegion * sizeof(RF_SpareTableEntry_t *), (RF_SpareTableEntry_t **));  retcode = copyin((caddr_t) data, (caddr_t) ptrs, info->TablesPerSpareRegion * sizeof(RF_SpareTableEntry_t *));  if (retcode) return(retcode);  /* now allocate kernel space for the row pointers */  RF_Malloc(info->SpareTable, info->TablesPerSpareRegion * sizeof(RF_SpareTableEntry_t *), (RF_SpareTableEntry_t **));  /* now allocate kernel space for each row in the table, and copy it in from user space */  for (i=0; i<info->TablesPerSpareRegion; i++) {    RF_Malloc(info->SpareTable[i], info->BlocksPerTable * sizeof(RF_SpareTableEntry_t), (RF_SpareTableEntry_t *));    retcode = copyin(ptrs[i], info->SpareTable[i], info->BlocksPerTable * sizeof(RF_SpareTableEntry_t));    if (retcode) {      info->SpareTable = NULL;             /* blow off the memory we've allocated */      return(retcode);    }  }  /* free up the temporary array we used */  RF_Free(ptrs, info->TablesPerSpareRegion * sizeof(RF_SpareTableEntry_t *));  return(0);}#endif /* KERNEL */RF_ReconUnitCount_t rf_GetNumSpareRUsDeclustered(raidPtr)  RF_Raid_t *raidPtr;{  RF_RaidLayout_t *layoutPtr = &raidPtr->Layout;  return( ((RF_DeclusteredConfigInfo_t *) layoutPtr->layoutSpecificInfo)->TotSparePUsPerDisk );}void rf_FreeSpareTable(raidPtr)  RF_Raid_t  *raidPtr;{  long i;  RF_RaidLayout_t *layoutPtr = &raidPtr->Layout;  RF_DeclusteredConfigInfo_t *info = (RF_DeclusteredConfigInfo_t *) layoutPtr->layoutSpecificInfo;  RF_SpareTableEntry_t **table = info->SpareTable;  for (i=0; i<info->TablesPerSpareRegion; i++) {RF_Free(table[i], info->BlocksPerTable * sizeof(RF_SpareTableEntry_t));}  RF_Free(table, info->TablesPerSpareRegion * sizeof(RF_SpareTableEntry_t *));  info->SpareTable = (RF_SpareTableEntry_t **) NULL;}

⌨️ 快捷键说明

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