The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/raidframe/rf_declusterPQ.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: a6f1433f6addc02ed7ca7f53d49a6ca5


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.