📄 rf_declusterpq.c
字号:
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 = (int *) 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-2); /* strange evaluation order below to try and minimize overflow problems */ layoutPtr->dataSectorsPerStripe = (k-2) * layoutPtr->sectorsPerStripeUnit; layoutPtr->bytesPerStripeUnit = layoutPtr->sectorsPerStripeUnit << raidPtr->logBytesPerSector; layoutPtr->numDataCol = k-2; layoutPtr->numParityCol = 2; return(0);}int rf_GetDefaultNumFloatingReconBuffersPQ(RF_Raid_t *raidPtr){ int def_decl; def_decl = rf_GetDefaultNumFloatingReconBuffersDeclustered(raidPtr); return(RF_MAX(3 * raidPtr->numCol, def_decl));}void rf_MapSectorDeclusteredPQ( 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, 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) */ *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; RF_ASSERT(BlockOffset < info->groupSize-2 ); /* TableIDs go from 0 .. GroupSize-1 inclusive. PUsPerBlock is k-2. We want the tableIDs to rotate from the right, so use GroupSize */ RepIndex = info->groupSize - 1 - TableID; RF_ASSERT(RepIndex >= 0); if (!raidPtr->noRotate) { if (TableID==0) BlockOffset++; /* P on last drive, Q on first */ else BlockOffset += ((BlockOffset >= RepIndex) ? 2 : 0); /* skip over PQ */ RF_ASSERT(BlockOffset < info->groupSize); *col = info->LayoutTable[BlockID][BlockOffset]; } /* remap to distributed spare space if indicated */ if (remap) { 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);}void rf_MapParityDeclusteredPQ( 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, 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; *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; BlockID = 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->groupSize - 1 - TableID; *col = info->LayoutTable[BlockID][RepIndex]; if (remap) RF_PANIC(); /* 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);}void rf_MapQDeclusteredPQ( 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, RepIndexQ; 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, 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; *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; BlockID = TableOffset / info->PUsPerBlock; BlockOffset = TableOffset - BlockID * info->PUsPerBlock; BlockID %= info->BlocksPerTable; /* the q block is in the position indicated by RepIndex */ RepIndex = (raidPtr->noRotate) ? info->PUsPerBlock : info->groupSize - 1 - TableID; RepIndexQ = ((RepIndex == (info->groupSize-1)) ? 0 : RepIndex+1); *col = info->LayoutTable[BlockID][RepIndexQ]; if (remap) RF_PANIC(); /* 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 += TableOffset / (info->BlocksPerTable * info->PUsPerBlock); outSU += info->OffsetTable[BlockID][RepIndexQ] * layoutPtr->SUsPerPU; *diskSector = outSU*layoutPtr->sectorsPerStripeUnit + (raidSector % layoutPtr->sectorsPerStripeUnit);}/* 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_IdentifyStripeDeclusteredPQ( 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];}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -