root/dev/raidframe/rf_declusterPQ.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rf_ConfigureDeclusteredPQ
  2. rf_GetDefaultNumFloatingReconBuffersPQ
  3. rf_MapSectorDeclusteredPQ
  4. rf_MapParityDeclusteredPQ
  5. rf_MapQDeclusteredPQ
  6. rf_IdentifyStripeDeclusteredPQ

    1 /*      $OpenBSD: rf_declusterPQ.c,v 1.4 2002/12/16 07:01:03 tdeval Exp $       */
    2 /*      $NetBSD: rf_declusterPQ.c,v 1.3 1999/02/05 00:06:09 oster Exp $ */
    3 
    4 /*
    5  * Copyright (c) 1995 Carnegie-Mellon University.
    6  * All rights reserved.
    7  *
    8  * Authors: Daniel Stodolsky, Mark Holland, Jim Zelenka
    9  *
   10  * Permission to use, copy, modify and distribute this software and
   11  * its documentation is hereby granted, provided that both the copyright
   12  * notice and this permission notice appear in all copies of the
   13  * software, derivative works or modified versions, and any portions
   14  * thereof, and that both notices appear in supporting documentation.
   15  *
   16  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   17  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
   18  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   19  *
   20  * Carnegie Mellon requests users of this software to return to
   21  *
   22  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   23  *  School of Computer Science
   24  *  Carnegie Mellon University
   25  *  Pittsburgh PA 15213-3890
   26  *
   27  * any improvements or extensions that they make and grant Carnegie the
   28  * rights to redistribute these changes.
   29  */
   30 
   31 /*****************************************************************************
   32  * rf_declusterPQ.c
   33  *
   34  * Mapping code for declustered P & Q or declustered EvenOdd.
   35  * Much code borrowed from rf_decluster.c
   36  *
   37  *****************************************************************************/
   38 
   39 
   40 #include "rf_types.h"
   41 #include "rf_raid.h"
   42 #include "rf_configure.h"
   43 #include "rf_decluster.h"
   44 #include "rf_declusterPQ.h"
   45 #include "rf_debugMem.h"
   46 #include "rf_utils.h"
   47 #include "rf_alloclist.h"
   48 #include "rf_general.h"
   49 
   50 /* Configuration code. */
   51 
   52 int
   53 rf_ConfigureDeclusteredPQ(RF_ShutdownList_t **listp, RF_Raid_t *raidPtr,
   54     RF_Config_t *cfgPtr)
   55 {
   56         RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout);
   57         int b, v, k, r, lambda; /* block design params */
   58         int i, j, l;
   59         int *first_avail_slot;
   60         int complete_FT_count, SUID;
   61         RF_DeclusteredConfigInfo_t *info;
   62         int numCompleteFullTablesPerDisk;
   63         int PUsPerDisk, spareRegionDepthInPUs, extraPUsPerDisk;
   64         int numCompleteSpareRegionsPerDisk = 0;
   65         int totSparePUsPerDisk;
   66         int diskOffsetOfLastFullTableInSUs, SpareSpaceInSUs;
   67         char *cfgBuf = (char *)(cfgPtr->layoutSpecific);
   68 
   69         cfgBuf += RF_SPAREMAP_NAME_LEN;
   70 
   71         b = *((int *) cfgBuf);
   72         cfgBuf += sizeof(int);
   73         v = *((int *) cfgBuf);
   74         cfgBuf += sizeof(int);
   75         k = *((int *) cfgBuf);
   76         cfgBuf += sizeof(int);
   77         r = *((int *) cfgBuf);
   78         cfgBuf += sizeof(int);
   79         lambda = *((int *) cfgBuf);
   80         cfgBuf += sizeof(int);
   81         raidPtr->noRotate = *((int *) cfgBuf);
   82         cfgBuf += sizeof(int);
   83 
   84         if (k <= 2) {
   85 #ifdef  RAIDDEBUG
   86                 printf("RAIDFRAME: k=%d, minimum value 2\n", k);
   87 #endif  /* RAIDDEBUG */
   88                 return (EINVAL);
   89         }
   90         /* 1. Create layout specific structure. */
   91         RF_MallocAndAdd(info, sizeof(RF_DeclusteredConfigInfo_t),
   92             (RF_DeclusteredConfigInfo_t *), raidPtr->cleanupList);
   93         if (info == NULL)
   94                 return (ENOMEM);
   95         layoutPtr->layoutSpecificInfo = (void *) info;
   96 
   97         /*
   98          * 2. The sparemaps are generated assuming that parity is rotated, so
   99          * we issue a warning if both distributed sparing and no-rotate are on
  100          * at the same time.
  101          */
  102         if ((raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE) &&
  103             raidPtr->noRotate) {
  104                 RF_ERRORMSG("Warning:  distributed sparing specified without"
  105                     " parity rotation.\n");
  106         }
  107         if (raidPtr->numCol != v) {
  108                 RF_ERRORMSG2("RAID: config error: table element count (%d)"
  109                     " not equal to no. of cols (%d).\n", v, raidPtr->numCol);
  110                 return (EINVAL);
  111         }
  112         /* 3. Set up the values used in devRaidMap. */
  113         info->BlocksPerTable = b;
  114         info->NumParityReps = info->groupSize = k;
  115         info->PUsPerBlock = k - 2;      /* PQ */
  116         info->SUsPerTable = b * info->PUsPerBlock * layoutPtr->SUsPerPU;
  117                 /* b blks, k-1 SUs each. */
  118         info->SUsPerFullTable = k * info->SUsPerTable;  /* Rot k times. */
  119         info->SUsPerBlock = info->PUsPerBlock * layoutPtr->SUsPerPU;
  120         info->TableDepthInPUs = (b * k) / v;
  121         info->FullTableDepthInPUs = info->TableDepthInPUs * k;
  122                 /* k repetitions. */
  123 
  124         /* Used only in distributed sparing case. */
  125         info->FullTablesPerSpareRegion = (v - 1) / rf_gcd(r, v - 1);
  126                 /* (v-1)/gcd fulltables. */
  127         info->TablesPerSpareRegion = k * info->FullTablesPerSpareRegion;
  128         info->SpareSpaceDepthPerRegionInSUs = (r * info->TablesPerSpareRegion
  129             / (v - 1)) * layoutPtr->SUsPerPU;
  130 
  131         /* Check to make sure the block design is sufficiently small. */
  132         if ((raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE)) {
  133                 if (info->FullTableDepthInPUs * layoutPtr->SUsPerPU +
  134                     info->SpareSpaceDepthPerRegionInSUs >
  135                     layoutPtr->stripeUnitsPerDisk) {
  136                         RF_ERRORMSG3("RAID: config error: Full Table depth"
  137                             " (%d) + Spare Space (%d) larger than disk size"
  138                             " (%d) (BD too big).\n",
  139                             (int)info->FullTableDepthInPUs,
  140                             (int)info->SpareSpaceDepthPerRegionInSUs,
  141                             (int)layoutPtr->stripeUnitsPerDisk);
  142                         return (EINVAL);
  143                 }
  144         } else {
  145                 if (info->TableDepthInPUs * layoutPtr->SUsPerPU >
  146                     layoutPtr->stripeUnitsPerDisk) {
  147                         RF_ERRORMSG2("RAID: config error: Table depth (%d)"
  148                             " larger than disk size (%d) (BD too big).\n",
  149                             (int) (info->TableDepthInPUs * layoutPtr->SUsPerPU),
  150                             (int) layoutPtr->stripeUnitsPerDisk);
  151                         return (EINVAL);
  152                 }
  153         }
  154 
  155         /*
  156          * Compute the size of each disk, and the number of tables in the last
  157          * fulltable (which need not be complete).
  158          */
  159         if ((raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE)) {
  160 
  161                 PUsPerDisk = layoutPtr->stripeUnitsPerDisk /
  162                     layoutPtr->SUsPerPU;
  163                 spareRegionDepthInPUs = (info->TablesPerSpareRegion *
  164                     info->TableDepthInPUs + (info->TablesPerSpareRegion *
  165                     info->TableDepthInPUs) / (v - 1));
  166                 info->SpareRegionDepthInSUs = spareRegionDepthInPUs *
  167                     layoutPtr->SUsPerPU;
  168 
  169                 numCompleteSpareRegionsPerDisk = PUsPerDisk /
  170                     spareRegionDepthInPUs;
  171                 info->NumCompleteSRs = numCompleteSpareRegionsPerDisk;
  172                 extraPUsPerDisk = PUsPerDisk % spareRegionDepthInPUs;
  173 
  174                 /*
  175                  * Assume conservatively that we need the full amount of spare
  176                  * space in one region in order to provide spares for the
  177                  * partial spare region at the end of the array.  We set "i"
  178                  * to the number of tables in the partial spare region.  This
  179                  * may actually include some fulltables.
  180                  */
  181                 extraPUsPerDisk -= (info->SpareSpaceDepthPerRegionInSUs /
  182                     layoutPtr->SUsPerPU);
  183                 if (extraPUsPerDisk <= 0)
  184                         i = 0;
  185                 else
  186                         i = extraPUsPerDisk / info->TableDepthInPUs;
  187 
  188                 complete_FT_count = raidPtr->numRow *
  189                     (numCompleteSpareRegionsPerDisk *
  190                     (info->TablesPerSpareRegion / k) + i / k);
  191                 info->FullTableLimitSUID = complete_FT_count *
  192                     info->SUsPerFullTable;
  193                 info->ExtraTablesPerDisk = i % k;
  194 
  195                 /*
  196                  * Note that in the last spare region, the spare space is
  197                  * complete even though data/parity space is not.
  198                  */
  199                 totSparePUsPerDisk = (numCompleteSpareRegionsPerDisk + 1) *
  200                     (info->SpareSpaceDepthPerRegionInSUs / layoutPtr->SUsPerPU);
  201                 info->TotSparePUsPerDisk = totSparePUsPerDisk;
  202 
  203                 layoutPtr->stripeUnitsPerDisk =
  204                     ((complete_FT_count / raidPtr->numRow) *
  205                     info->FullTableDepthInPUs + /* data & parity space */
  206                     info->ExtraTablesPerDisk * info->TableDepthInPUs +
  207                     totSparePUsPerDisk  /* spare space */
  208                     ) * layoutPtr->SUsPerPU;
  209                 layoutPtr->dataStripeUnitsPerDisk =
  210                     (complete_FT_count * info->FullTableDepthInPUs +
  211                     info->ExtraTablesPerDisk * info->TableDepthInPUs)
  212                     * layoutPtr->SUsPerPU * (k - 1) / k;
  213 
  214         } else {
  215                 /*
  216                  * Non-dist spare case:  force each disk to contain an
  217                  * integral number of tables.
  218                  */
  219                 layoutPtr->stripeUnitsPerDisk /=
  220                     (info->TableDepthInPUs * layoutPtr->SUsPerPU);
  221                 layoutPtr->stripeUnitsPerDisk *=
  222                     (info->TableDepthInPUs * layoutPtr->SUsPerPU);
  223 
  224                 /*
  225                  * Compute the number of tables in the last fulltable, which
  226                  * need not be complete.
  227                  */
  228                 complete_FT_count = ((layoutPtr->stripeUnitsPerDisk /
  229                     layoutPtr->SUsPerPU) / info->FullTableDepthInPUs) *
  230                     raidPtr->numRow;
  231 
  232                 info->FullTableLimitSUID = complete_FT_count *
  233                     info->SUsPerFullTable;
  234                 info->ExtraTablesPerDisk = ((layoutPtr->stripeUnitsPerDisk /
  235                     layoutPtr->SUsPerPU) / info->TableDepthInPUs) % k;
  236         }
  237 
  238         raidPtr->sectorsPerDisk = layoutPtr->stripeUnitsPerDisk *
  239             layoutPtr->sectorsPerStripeUnit;
  240 
  241         /*
  242          * Find the disk offset of the stripe unit where the last
  243          * fulltable starts.
  244          */
  245         numCompleteFullTablesPerDisk = complete_FT_count / raidPtr->numRow;
  246         diskOffsetOfLastFullTableInSUs = numCompleteFullTablesPerDisk *
  247             info->FullTableDepthInPUs * layoutPtr->SUsPerPU;
  248         if ((raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE)) {
  249                 SpareSpaceInSUs = numCompleteSpareRegionsPerDisk *
  250                     info->SpareSpaceDepthPerRegionInSUs;
  251                 diskOffsetOfLastFullTableInSUs += SpareSpaceInSUs;
  252                 info->DiskOffsetOfLastSpareSpaceChunkInSUs =
  253                     diskOffsetOfLastFullTableInSUs + info->ExtraTablesPerDisk *
  254                     info->TableDepthInPUs * layoutPtr->SUsPerPU;
  255         }
  256         info->DiskOffsetOfLastFullTableInSUs = diskOffsetOfLastFullTableInSUs;
  257         info->numCompleteFullTablesPerDisk = numCompleteFullTablesPerDisk;
  258 
  259         /* 4. Create and initialize the lookup tables. */
  260         info->LayoutTable = rf_make_2d_array(b, k, raidPtr->cleanupList);
  261         if (info->LayoutTable == NULL)
  262                 return (ENOMEM);
  263 
  264         info->OffsetTable = rf_make_2d_array(b, k, raidPtr->cleanupList);
  265         if (info->OffsetTable == NULL)
  266                 return (ENOMEM);
  267 
  268         info->BlockTable = rf_make_2d_array(info->TableDepthInPUs *
  269             layoutPtr->SUsPerPU, raidPtr->numCol, raidPtr->cleanupList);
  270         if (info->BlockTable == NULL)
  271                 return (ENOMEM);
  272 
  273         first_avail_slot = (int *) rf_make_1d_array(v, NULL);
  274         if (first_avail_slot == NULL)
  275                 return (ENOMEM);
  276 
  277         for (i = 0; i < b; i++)
  278                 for (j = 0; j < k; j++)
  279                         info->LayoutTable[i][j] = *cfgBuf++;
  280 
  281         /* Initialize offset table. */
  282         for (i = 0; i < b; i++)
  283                 for (j = 0; j < k; j++) {
  284                         info->OffsetTable[i][j] =
  285                             first_avail_slot[info->LayoutTable[i][j]];
  286                         first_avail_slot[info->LayoutTable[i][j]]++;
  287                 }
  288 
  289         /* Initialize block table. */
  290         for (SUID = l = 0; l < layoutPtr->SUsPerPU; l++) {
  291                 for (i = 0; i < b; i++) {
  292                         for (j = 0; j < k; j++) {
  293                                 info->BlockTable[(info->OffsetTable[i][j] *
  294                                      layoutPtr->SUsPerPU) + l]
  295                                     [info->LayoutTable[i][j]] = SUID;
  296                         }
  297                         SUID++;
  298                 }
  299         }
  300 
  301         rf_free_1d_array(first_avail_slot, v);
  302 
  303         /* 5. Set up the remaining redundant-but-useful parameters. */
  304 
  305         raidPtr->totalSectors = (k * complete_FT_count + raidPtr->numRow *
  306             info->ExtraTablesPerDisk) * info->SUsPerTable *
  307             layoutPtr->sectorsPerStripeUnit;
  308         layoutPtr->numStripe = (raidPtr->totalSectors /
  309             layoutPtr->sectorsPerStripeUnit) / (k - 2);
  310 
  311         /*
  312          * Strange evaluation order below to try and minimize overflow
  313          * problems.
  314          */
  315 
  316         layoutPtr->dataSectorsPerStripe = (k - 2) *
  317             layoutPtr->sectorsPerStripeUnit;
  318         layoutPtr->bytesPerStripeUnit = layoutPtr->sectorsPerStripeUnit <<
  319             raidPtr->logBytesPerSector;
  320         layoutPtr->numDataCol = k - 2;
  321         layoutPtr->numParityCol = 2;
  322 
  323         return (0);
  324 }
  325 
  326 int
  327 rf_GetDefaultNumFloatingReconBuffersPQ(RF_Raid_t *raidPtr)
  328 {
  329         int def_decl;
  330 
  331         def_decl = rf_GetDefaultNumFloatingReconBuffersDeclustered(raidPtr);
  332         return (RF_MAX(3 * raidPtr->numCol, def_decl));
  333 }
  334 
  335 void
  336 rf_MapSectorDeclusteredPQ(RF_Raid_t *raidPtr, RF_RaidAddr_t raidSector,
  337     RF_RowCol_t *row, RF_RowCol_t *col, RF_SectorNum_t *diskSector, int remap)
  338 {
  339         RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout);
  340         RF_DeclusteredConfigInfo_t *info =
  341             (RF_DeclusteredConfigInfo_t *) layoutPtr->layoutSpecificInfo;
  342         RF_StripeNum_t SUID = raidSector / layoutPtr->sectorsPerStripeUnit;
  343         RF_StripeNum_t FullTableID, FullTableOffset, TableID, TableOffset;
  344         RF_StripeNum_t BlockID, BlockOffset, RepIndex;
  345         RF_StripeCount_t sus_per_fulltable = info->SUsPerFullTable;
  346         RF_StripeCount_t fulltable_depth = info->FullTableDepthInPUs *
  347             layoutPtr->SUsPerPU;
  348         RF_StripeNum_t base_suid = 0, outSU, SpareRegion = 0, SpareSpace = 0;
  349 
  350         rf_decluster_adjust_params(layoutPtr, &SUID, &sus_per_fulltable,
  351             &fulltable_depth, &base_suid);
  352 
  353         /* Fulltable ID within array (across rows). */
  354         FullTableID = SUID / sus_per_fulltable;
  355         *row = FullTableID % raidPtr->numRow;
  356 
  357         /* Convert to fulltable ID on this disk. */
  358         FullTableID /= raidPtr->numRow;
  359 
  360         if ((raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE)) {
  361                 SpareRegion = FullTableID / info->FullTablesPerSpareRegion;
  362                 SpareSpace = SpareRegion * info->SpareSpaceDepthPerRegionInSUs;
  363         }
  364         FullTableOffset = SUID % sus_per_fulltable;
  365         TableID = FullTableOffset / info->SUsPerTable;
  366         TableOffset = FullTableOffset - TableID * info->SUsPerTable;
  367         BlockID = TableOffset / info->PUsPerBlock;
  368         BlockOffset = TableOffset - BlockID * info->PUsPerBlock;
  369         BlockID %= info->BlocksPerTable;
  370         RF_ASSERT(BlockOffset < info->groupSize - 2);
  371         /*
  372          * TableIDs go from 0 .. GroupSize-1 inclusive.
  373          * PUsPerBlock is k-2.
  374          * We want the tableIDs to rotate from the
  375          * right, so use GroupSize.
  376          */
  377         RepIndex = info->groupSize - 1 - TableID;
  378         RF_ASSERT(RepIndex >= 0);
  379         if (!raidPtr->noRotate) {
  380                 if (TableID == 0)
  381                         /* P on last drive, Q on first. */
  382                         BlockOffset++;
  383                 else
  384                         /* Skip over PQ. */
  385                         BlockOffset += ((BlockOffset >= RepIndex) ? 2 : 0);
  386 
  387                 RF_ASSERT(BlockOffset < info->groupSize);
  388                 *col = info->LayoutTable[BlockID][BlockOffset];
  389         }
  390         /* Remap to distributed spare space if indicated. */
  391         if (remap) {
  392                 rf_remap_to_spare_space(layoutPtr, info, *row, FullTableID,
  393                     TableID, BlockID, (base_suid) ? 1 : 0, SpareRegion, col,
  394                     &outSU);
  395         } else {
  396 
  397                 outSU = base_suid;
  398                 outSU += FullTableID * fulltable_depth;
  399                         /* Offset to strt of FT. */
  400                 outSU += SpareSpace;
  401                         /* Skip reserved spare space. */
  402                 outSU += TableID * info->TableDepthInPUs * layoutPtr->SUsPerPU;
  403                         /* Offset to start of table. */
  404                 outSU += info->OffsetTable[BlockID][BlockOffset] *
  405                     layoutPtr->SUsPerPU;
  406                         /* Offset to the PU. */
  407         }
  408         outSU += TableOffset / (info->BlocksPerTable * info->PUsPerBlock);
  409                 /* Offset to the SU within a PU. */
  410 
  411         /*
  412          * Convert SUs to sectors, and, if not aligned to SU boundary, add in
  413          * offset to sector.
  414          */
  415         *diskSector = outSU * layoutPtr->sectorsPerStripeUnit +
  416             (raidSector % layoutPtr->sectorsPerStripeUnit);
  417 }
  418 
  419 
  420 void
  421 rf_MapParityDeclusteredPQ(RF_Raid_t *raidPtr, RF_RaidAddr_t raidSector,
  422     RF_RowCol_t *row, RF_RowCol_t *col, RF_SectorNum_t *diskSector, int remap)
  423 {
  424         RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout);
  425         RF_DeclusteredConfigInfo_t *info =
  426             (RF_DeclusteredConfigInfo_t *) layoutPtr->layoutSpecificInfo;
  427         RF_StripeNum_t SUID = raidSector / layoutPtr->sectorsPerStripeUnit;
  428         RF_StripeNum_t FullTableID, FullTableOffset, TableID, TableOffset;
  429         RF_StripeNum_t BlockID, BlockOffset, RepIndex;
  430         RF_StripeCount_t sus_per_fulltable = info->SUsPerFullTable;
  431         RF_StripeCount_t fulltable_depth = info->FullTableDepthInPUs *
  432             layoutPtr->SUsPerPU;
  433         RF_StripeNum_t base_suid = 0, outSU, SpareRegion, SpareSpace = 0;
  434 
  435         rf_decluster_adjust_params(layoutPtr, &SUID, &sus_per_fulltable,
  436             &fulltable_depth, &base_suid);
  437 
  438         /* Compute row & (possibly) spare space exactly as before. */
  439         FullTableID = SUID / sus_per_fulltable;
  440         *row = FullTableID % raidPtr->numRow;
  441         /* Convert to fulltable ID on this disk. */
  442         FullTableID /= raidPtr->numRow;
  443         if ((raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE)) {
  444                 SpareRegion = FullTableID / info->FullTablesPerSpareRegion;
  445                 SpareSpace = SpareRegion * info->SpareSpaceDepthPerRegionInSUs;
  446         }
  447         /* Compute BlockID and RepIndex exactly as before. */
  448         FullTableOffset = SUID % sus_per_fulltable;
  449         TableID = FullTableOffset / info->SUsPerTable;
  450         TableOffset = FullTableOffset - TableID * info->SUsPerTable;
  451         BlockID = TableOffset / info->PUsPerBlock;
  452         BlockOffset = TableOffset - BlockID * info->PUsPerBlock;
  453         BlockID %= info->BlocksPerTable;
  454 
  455         /* The parity block is in the position indicated by RepIndex. */
  456         RepIndex = (raidPtr->noRotate) ?
  457             info->PUsPerBlock : info->groupSize - 1 - TableID;
  458         *col = info->LayoutTable[BlockID][RepIndex];
  459 
  460         if (remap)
  461                 RF_PANIC();
  462 
  463         /*
  464          * Compute sector as before, except use RepIndex instead of
  465          * BlockOffset.
  466          */
  467         outSU = base_suid;
  468         outSU += FullTableID * fulltable_depth;
  469         outSU += SpareSpace;    /* skip rsvd spare space */
  470         outSU += TableID * info->TableDepthInPUs * layoutPtr->SUsPerPU;
  471         outSU += info->OffsetTable[BlockID][RepIndex] * layoutPtr->SUsPerPU;
  472         outSU += TableOffset / (info->BlocksPerTable * info->PUsPerBlock);
  473 
  474         *diskSector = outSU * layoutPtr->sectorsPerStripeUnit +
  475             (raidSector % layoutPtr->sectorsPerStripeUnit);
  476 }
  477 
  478 void
  479 rf_MapQDeclusteredPQ(RF_Raid_t *raidPtr, RF_RaidAddr_t raidSector,
  480     RF_RowCol_t *row, RF_RowCol_t *col, RF_SectorNum_t *diskSector, int remap)
  481 {
  482         RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout);
  483         RF_DeclusteredConfigInfo_t *info =
  484             (RF_DeclusteredConfigInfo_t *) layoutPtr->layoutSpecificInfo;
  485         RF_StripeNum_t SUID = raidSector / layoutPtr->sectorsPerStripeUnit;
  486         RF_StripeNum_t FullTableID, FullTableOffset, TableID, TableOffset;
  487         RF_StripeNum_t BlockID, BlockOffset, RepIndex, RepIndexQ;
  488         RF_StripeCount_t sus_per_fulltable = info->SUsPerFullTable;
  489         RF_StripeCount_t fulltable_depth = info->FullTableDepthInPUs *
  490             layoutPtr->SUsPerPU;
  491         RF_StripeNum_t base_suid = 0, outSU, SpareRegion, SpareSpace = 0;
  492 
  493         rf_decluster_adjust_params(layoutPtr, &SUID, &sus_per_fulltable,
  494             &fulltable_depth, &base_suid);
  495 
  496         /* Compute row & (possibly) spare space exactly as before. */
  497         FullTableID = SUID / sus_per_fulltable;
  498         *row = FullTableID % raidPtr->numRow;
  499         /* Convert to fulltable ID on this disk. */
  500         FullTableID /= raidPtr->numRow;
  501         if ((raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE)) {
  502                 SpareRegion = FullTableID / info->FullTablesPerSpareRegion;
  503                 SpareSpace = SpareRegion * info->SpareSpaceDepthPerRegionInSUs;
  504         }
  505         /* Compute BlockID and RepIndex exactly as before. */
  506         FullTableOffset = SUID % sus_per_fulltable;
  507         TableID = FullTableOffset / info->SUsPerTable;
  508         TableOffset = FullTableOffset - TableID * info->SUsPerTable;
  509         BlockID = TableOffset / info->PUsPerBlock;
  510         BlockOffset = TableOffset - BlockID * info->PUsPerBlock;
  511         BlockID %= info->BlocksPerTable;
  512 
  513         /* The q block is in the position indicated by RepIndex. */
  514         RepIndex = (raidPtr->noRotate) ?
  515             info->PUsPerBlock : info->groupSize - 1 - TableID;
  516         RepIndexQ = ((RepIndex == (info->groupSize - 1)) ? 0 : RepIndex + 1);
  517         *col = info->LayoutTable[BlockID][RepIndexQ];
  518 
  519         if (remap)
  520                 RF_PANIC();
  521 
  522         /*
  523          * Compute sector as before, except use RepIndex instead of
  524          * BlockOffset.
  525          */
  526         outSU = base_suid;
  527         outSU += FullTableID * fulltable_depth;
  528         outSU += SpareSpace;    /* skip rsvd spare space */
  529         outSU += TableID * info->TableDepthInPUs * layoutPtr->SUsPerPU;
  530         outSU += TableOffset / (info->BlocksPerTable * info->PUsPerBlock);
  531 
  532         outSU += info->OffsetTable[BlockID][RepIndexQ] * layoutPtr->SUsPerPU;
  533         *diskSector = outSU * layoutPtr->sectorsPerStripeUnit +
  534             (raidSector % layoutPtr->sectorsPerStripeUnit);
  535 }
  536 
  537 /*
  538  * Returns an array of ints identifying the disks that comprise the stripe
  539  * containing the indicated address.
  540  * The caller must _never_ attempt to modify this array.
  541  */
  542 void
  543 rf_IdentifyStripeDeclusteredPQ(RF_Raid_t *raidPtr, RF_RaidAddr_t addr,
  544     RF_RowCol_t **diskids, RF_RowCol_t *outRow)
  545 {
  546         RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout);
  547         RF_DeclusteredConfigInfo_t *info =
  548             (RF_DeclusteredConfigInfo_t *) layoutPtr->layoutSpecificInfo;
  549         RF_StripeCount_t sus_per_fulltable = info->SUsPerFullTable;
  550         RF_StripeCount_t fulltable_depth = info->FullTableDepthInPUs *
  551             layoutPtr->SUsPerPU;
  552         RF_StripeNum_t base_suid = 0;
  553         RF_StripeNum_t SUID = rf_RaidAddressToStripeUnitID(layoutPtr, addr);
  554         RF_StripeNum_t stripeID, FullTableID;
  555         int tableOffset;
  556 
  557         rf_decluster_adjust_params(layoutPtr, &SUID, &sus_per_fulltable,
  558             &fulltable_depth, &base_suid);
  559         /* Fulltable ID within array (across rows). */
  560         FullTableID = SUID / sus_per_fulltable;
  561         *outRow = FullTableID % raidPtr->numRow;
  562         /* Find stripe offset into array. */
  563         stripeID = rf_StripeUnitIDToStripeID(layoutPtr, SUID);
  564         /* Find offset into block design table. */
  565         tableOffset = (stripeID % info->BlocksPerTable);
  566         *diskids = info->LayoutTable[tableOffset];
  567 }

/* [<][>][^][v][top][bottom][index][help] */