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

📄 rf_decluster.c

📁 RAIDFrame是个非常好的磁盘阵列RAID仿真工具
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* compute the size of each disk, and the number of tables in the last fulltable (which     * need not be complete)     */    if (raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE) {		PUsPerDisk = layoutPtr->stripeUnitsPerDisk / layoutPtr->SUsPerPU;	spareRegionDepthInPUs = (info->TablesPerSpareRegion * info->TableDepthInPUs +				 (info->TablesPerSpareRegion * info->TableDepthInPUs) / (v-1));	info->SpareRegionDepthInSUs = spareRegionDepthInPUs * layoutPtr->SUsPerPU;		numCompleteSpareRegionsPerDisk = PUsPerDisk / spareRegionDepthInPUs;	info->NumCompleteSRs = numCompleteSpareRegionsPerDisk;	extraPUsPerDisk = PUsPerDisk % spareRegionDepthInPUs;	/* assume conservatively that we need the full amount of spare space in one region in order	 * to provide spares for the partial spare region at the end of the array.  We set "i" to	 * the number of tables in the partial spare region.  This may actually include some fulltables.	 */	extraPUsPerDisk -= (info->SpareSpaceDepthPerRegionInSUs / layoutPtr->SUsPerPU);	if (extraPUsPerDisk <= 0) i = 0;	else i = extraPUsPerDisk/info->TableDepthInPUs;	complete_FT_count = raidPtr->numRow * (numCompleteSpareRegionsPerDisk * (info->TablesPerSpareRegion/k) + i/k);        info->FullTableLimitSUID = complete_FT_count * info->SUsPerFullTable;	info->ExtraTablesPerDisk = i % k;	/* note that in the last spare region, the spare space is complete even though data/parity space is not */	totSparePUsPerDisk = (numCompleteSpareRegionsPerDisk+1) * (info->SpareSpaceDepthPerRegionInSUs / layoutPtr->SUsPerPU);	info->TotSparePUsPerDisk = totSparePUsPerDisk;		layoutPtr->stripeUnitsPerDisk =	    ((complete_FT_count/raidPtr->numRow) * info->FullTableDepthInPUs +	 	/* data & parity space */	     info->ExtraTablesPerDisk * info->TableDepthInPUs +	     totSparePUsPerDisk								/* spare space */	    ) * layoutPtr->SUsPerPU;	layoutPtr->dataStripeUnitsPerDisk = 	    (complete_FT_count * info->FullTableDepthInPUs + info->ExtraTablesPerDisk * info->TableDepthInPUs)	    * layoutPtr->SUsPerPU * (k-1) / k;    } else {        /* non-dist spare case:  force each disk to contain an integral number of tables */        layoutPtr->stripeUnitsPerDisk /= (info->TableDepthInPUs * layoutPtr->SUsPerPU);        layoutPtr->stripeUnitsPerDisk *= (info->TableDepthInPUs * layoutPtr->SUsPerPU);	/* compute the number of tables in the last fulltable, which need not be complete */        complete_FT_count =            ((layoutPtr->stripeUnitsPerDisk/layoutPtr->SUsPerPU) / info->FullTableDepthInPUs) * raidPtr->numRow;	            info->FullTableLimitSUID = complete_FT_count * info->SUsPerFullTable;        info->ExtraTablesPerDisk =		((layoutPtr->stripeUnitsPerDisk/layoutPtr->SUsPerPU) / info->TableDepthInPUs) % k;    }    raidPtr->sectorsPerDisk = layoutPtr->stripeUnitsPerDisk * layoutPtr->sectorsPerStripeUnit;    /* find the disk offset of the stripe unit where the last fulltable starts */    numCompleteFullTablesPerDisk = complete_FT_count / raidPtr->numRow;    diskOffsetOfLastFullTableInSUs = numCompleteFullTablesPerDisk * info->FullTableDepthInPUs * layoutPtr->SUsPerPU;    if (raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE) {        SpareSpaceInSUs  = numCompleteSpareRegionsPerDisk * info->SpareSpaceDepthPerRegionInSUs;        diskOffsetOfLastFullTableInSUs += SpareSpaceInSUs;        info->DiskOffsetOfLastSpareSpaceChunkInSUs =	    diskOffsetOfLastFullTableInSUs + info->ExtraTablesPerDisk * info->TableDepthInPUs * layoutPtr->SUsPerPU;    }    info->DiskOffsetOfLastFullTableInSUs = diskOffsetOfLastFullTableInSUs;    info->numCompleteFullTablesPerDisk = numCompleteFullTablesPerDisk;	    /* 4.  create and initialize the lookup tables */    info->LayoutTable = rf_make_2d_array(b, k, raidPtr->cleanupList);    if (info->LayoutTable == NULL)      return(ENOMEM);    info->OffsetTable = rf_make_2d_array(b, k, raidPtr->cleanupList);    if (info->OffsetTable == NULL)      return(ENOMEM);    info->BlockTable  =	rf_make_2d_array(info->TableDepthInPUs*layoutPtr->SUsPerPU, raidPtr->numCol, raidPtr->cleanupList);    if (info->BlockTable == NULL)      return(ENOMEM);    first_avail_slot = rf_make_1d_array(v, NULL);    if (first_avail_slot == NULL)      return(ENOMEM);    for (i=0; i<b; i++)      for (j=0; j<k; j++)        info->LayoutTable[i][j] = *cfgBuf++;    /* initialize offset table */    for (i=0; i<b; i++) for (j=0; j<k; j++) {        info->OffsetTable[i][j] = first_avail_slot[ info->LayoutTable[i][j] ];        first_avail_slot[ info->LayoutTable[i][j] ]++;    }    /* initialize block table */    for (SUID=l=0; l<layoutPtr->SUsPerPU; l++) {        for (i=0; i<b; i++) {            for (j=0; j<k; j++) {                info->BlockTable[ (info->OffsetTable[i][j] * layoutPtr->SUsPerPU) + l ]		                [ info->LayoutTable[i][j] ] = SUID;            }            SUID++;        }    }    rf_free_1d_array(first_avail_slot, v);    /* 5.  set up the remaining redundant-but-useful parameters */    raidPtr->totalSectors = (k*complete_FT_count + raidPtr->numRow*info->ExtraTablesPerDisk) *    			  info->SUsPerTable * layoutPtr->sectorsPerStripeUnit;    layoutPtr->numStripe = (raidPtr->totalSectors / layoutPtr->sectorsPerStripeUnit) / (k-1);    /* strange evaluation order below to try and minimize overflow problems */        layoutPtr->dataSectorsPerStripe = (k-1) * layoutPtr->sectorsPerStripeUnit;    layoutPtr->bytesPerStripeUnit = layoutPtr->sectorsPerStripeUnit << raidPtr->logBytesPerSector;    layoutPtr->numDataCol = k-1;    layoutPtr->numParityCol = 1;    return(0);}/* declustering with distributed sparing */static void rf_ShutdownDeclusteredDS(arg)  RF_ThreadArg_t  arg;{  RF_DeclusteredConfigInfo_t *info;  RF_Raid_t *raidPtr;  raidPtr = (RF_Raid_t *)arg;  info = (RF_DeclusteredConfigInfo_t *) raidPtr->Layout.layoutSpecificInfo;  if (info->SpareTable)    rf_FreeSpareTable(raidPtr);}int rf_ConfigureDeclusteredDS(  RF_ShutdownList_t  **listp,  RF_Raid_t           *raidPtr,  RF_Config_t         *cfgPtr){  int rc;  rc = rf_ConfigureDeclustered(listp, raidPtr, cfgPtr);  if (rc)    return(rc);  rc = rf_ShutdownCreate(listp, rf_ShutdownDeclusteredDS, raidPtr);  if (rc) {    RF_ERRORMSG1("Got %d adding shutdown event for DeclusteredDS\n", rc);    rf_ShutdownDeclusteredDS(raidPtr);    return(rc);  }  return(0);}void rf_MapSectorDeclustered(raidPtr, raidSector, row, col, diskSector, remap)  RF_Raid_t       *raidPtr;  RF_RaidAddr_t    raidSector;  RF_RowCol_t     *row;  RF_RowCol_t     *col;  RF_SectorNum_t  *diskSector;  int              remap;{    RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout);    RF_DeclusteredConfigInfo_t *info = (RF_DeclusteredConfigInfo_t *) layoutPtr->layoutSpecificInfo;    RF_StripeNum_t SUID = raidSector / layoutPtr->sectorsPerStripeUnit;    RF_StripeNum_t FullTableID, FullTableOffset, TableID, TableOffset;     RF_StripeNum_t BlockID, BlockOffset, RepIndex;    RF_StripeCount_t sus_per_fulltable = info->SUsPerFullTable;    RF_StripeCount_t fulltable_depth  = info->FullTableDepthInPUs * layoutPtr->SUsPerPU;    RF_StripeNum_t base_suid = 0, outSU, SpareRegion=0, SpareSpace=0;    rf_decluster_adjust_params(layoutPtr, &SUID, &sus_per_fulltable, &fulltable_depth, &base_suid);	        FullTableID     = SUID / sus_per_fulltable;		/* fulltable ID within array (across rows) */    if (raidPtr->numRow == 1) *row = 0;                 /* avoid a mod and a div in the common case */    else {      *row            = FullTableID % raidPtr->numRow;      FullTableID    /= raidPtr->numRow;			/* convert to fulltable ID on this disk */    }    if (raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE) {	SpareRegion = FullTableID / info->FullTablesPerSpareRegion;        SpareSpace  = SpareRegion * info->SpareSpaceDepthPerRegionInSUs;    }    FullTableOffset = SUID % sus_per_fulltable;    TableID         = FullTableOffset / info->SUsPerTable;    TableOffset     = FullTableOffset - TableID * info->SUsPerTable;    BlockID         = TableOffset / info->PUsPerBlock;    BlockOffset     = TableOffset - BlockID * info->PUsPerBlock;    BlockID        %= info->BlocksPerTable;    RepIndex        = info->PUsPerBlock - TableID;    if (!raidPtr->noRotate) BlockOffset    += ((BlockOffset >= RepIndex) ? 1 : 0);    *col            = info->LayoutTable[BlockID][BlockOffset];    /* remap to distributed spare space if indicated */    if (remap) {      RF_ASSERT( raidPtr->Disks[*row][*col].status == rf_ds_reconstructing || raidPtr->Disks[*row][*col].status == rf_ds_dist_spared ||	     (rf_copyback_in_progress && raidPtr->Disks[*row][*col].status == rf_ds_optimal));      rf_remap_to_spare_space(layoutPtr, info, *row, FullTableID, TableID, BlockID, (base_suid) ? 1 : 0, SpareRegion, col, &outSU);    } else {            outSU	    = base_suid;        outSU      += FullTableID * fulltable_depth;  				        /* offs to strt of FT */        outSU	   += SpareSpace;						        /* skip rsvd spare space */        outSU      += TableID * info->TableDepthInPUs * layoutPtr->SUsPerPU;   	        /* offs to strt of tble */        outSU      += info->OffsetTable[BlockID][BlockOffset] * layoutPtr->SUsPerPU;	/* offs to the PU */    }    outSU          += TableOffset / (info->BlocksPerTable * info->PUsPerBlock);	        /* offs to the SU within a PU */        /* convert SUs to sectors, and, if not aligned to SU boundary, add in offset to sector.  */    *diskSector     = outSU*layoutPtr->sectorsPerStripeUnit + (raidSector % layoutPtr->sectorsPerStripeUnit);    RF_ASSERT( *col != -1 );}/* prototyping this inexplicably causes the compile of the layout table (rf_layout.c) to fail */void rf_MapParityDeclustered(  RF_Raid_t       *raidPtr,  RF_RaidAddr_t    raidSector,  RF_RowCol_t     *row,  RF_RowCol_t     *col,  RF_SectorNum_t  *diskSector,  int              remap){    RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout);    RF_DeclusteredConfigInfo_t *info = (RF_DeclusteredConfigInfo_t *) layoutPtr->layoutSpecificInfo;    RF_StripeNum_t SUID = raidSector / layoutPtr->sectorsPerStripeUnit;    RF_StripeNum_t FullTableID, FullTableOffset, TableID, TableOffset;     RF_StripeNum_t BlockID, BlockOffset, RepIndex;    RF_StripeCount_t sus_per_fulltable = info->SUsPerFullTable;    RF_StripeCount_t fulltable_depth  = info->FullTableDepthInPUs * layoutPtr->SUsPerPU;    RF_StripeNum_t base_suid = 0, outSU, SpareRegion=0, SpareSpace=0;    rf_decluster_adjust_params(layoutPtr, &SUID, &sus_per_fulltable, &fulltable_depth, &base_suid);        /* compute row & (possibly) spare space exactly as before */    FullTableID     = SUID / sus_per_fulltable;    if (raidPtr->numRow == 1) *row = 0;                         /* avoid a mod and a div in the common case */    else {      *row            = FullTableID % raidPtr->numRow;      FullTableID    /= raidPtr->numRow;			/* convert to fulltable ID on this disk */    }    if ((raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE)) {	SpareRegion = FullTableID / info->FullTablesPerSpareRegion;        SpareSpace  = SpareRegion * info->SpareSpaceDepthPerRegionInSUs;    }    /* compute BlockID and RepIndex exactly as before */    FullTableOffset = SUID % sus_per_fulltable;    TableID         = FullTableOffset / info->SUsPerTable;    TableOffset     = FullTableOffset - TableID * info->SUsPerTable;    /*TableOffset     = FullTableOffset % info->SUsPerTable;*/    /*BlockID         = (TableOffset / info->PUsPerBlock) % info->BlocksPerTable;*/    BlockID         = TableOffset / info->PUsPerBlock;    /*BlockOffset     = TableOffset % info->PUsPerBlock;*/    BlockOffset     = TableOffset - BlockID * info->PUsPerBlock;    BlockID        %= info->BlocksPerTable;    /* the parity block is in the position indicated by RepIndex */    RepIndex        = (raidPtr->noRotate) ? info->PUsPerBlock : info->PUsPerBlock - TableID;    *col	    = info->LayoutTable[BlockID][RepIndex];        if (remap) {      RF_ASSERT( raidPtr->Disks[*row][*col].status == rf_ds_reconstructing || raidPtr->Disks[*row][*col].status == rf_ds_dist_spared ||	     (rf_copyback_in_progress && raidPtr->Disks[*row][*col].status == rf_ds_optimal));      rf_remap_to_spare_space(layoutPtr, info, *row, FullTableID, TableID, BlockID, (base_suid) ? 1 : 0, SpareRegion, col, &outSU);    } else {        /* compute sector as before, except use RepIndex instead of BlockOffset */        outSU        = base_suid;        outSU       += FullTableID * fulltable_depth;        outSU	    += SpareSpace;						/* skip rsvd spare space */        outSU       += TableID * info->TableDepthInPUs * layoutPtr->SUsPerPU;        outSU       += info->OffsetTable[BlockID][RepIndex] * layoutPtr->SUsPerPU;    }        outSU       += TableOffset / (info->BlocksPerTable * info->PUsPerBlock);    *diskSector  = outSU*layoutPtr->sectorsPerStripeUnit + (raidSector % layoutPtr->sectorsPerStripeUnit);

⌨️ 快捷键说明

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