📄 rf_decluster.c
字号:
/* 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 + -