root/dev/raidframe/rf_layout.c

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

DEFINITIONS

This source file includes following definitions.
  1. rf_GetLayout
  2. rf_ConfigureLayout
  3. rf_MapStripeIDToParityStripeID

    1 /*      $OpenBSD: rf_layout.c,v 1.7 2007/04/10 17:47:55 miod Exp $      */
    2 /*      $NetBSD: rf_layout.c,v 1.6 2000/04/17 19:35:12 oster Exp $      */
    3 
    4 /*
    5  * Copyright (c) 1995 Carnegie-Mellon University.
    6  * All rights reserved.
    7  *
    8  * Author: Mark Holland
    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_layout.c -- Driver code dealing with layout and mapping issues.
   33  */
   34 
   35 #include "rf_types.h"
   36 #include "rf_archs.h"
   37 #include "rf_raid.h"
   38 #include "rf_configure.h"
   39 #include "rf_dag.h"
   40 #include "rf_desc.h"
   41 #include "rf_decluster.h"
   42 #include "rf_pq.h"
   43 #include "rf_declusterPQ.h"
   44 #include "rf_raid0.h"
   45 #include "rf_raid1.h"
   46 #include "rf_raid4.h"
   47 #include "rf_raid5.h"
   48 #include "rf_states.h"
   49 #if     RF_INCLUDE_RAID5_RS > 0
   50 #include "rf_raid5_rotatedspare.h"
   51 #endif  /* RF_INCLUDE_RAID5_RS > 0 */
   52 #if     RF_INCLUDE_CHAINDECLUSTER > 0
   53 #include "rf_chaindecluster.h"
   54 #endif  /* RF_INCLUDE_CHAINDECLUSTER > 0 */
   55 #if     RF_INCLUDE_INTERDECLUSTER > 0
   56 #include "rf_interdecluster.h"
   57 #endif  /* RF_INCLUDE_INTERDECLUSTER > 0 */
   58 #if     RF_INCLUDE_PARITYLOGGING > 0
   59 #include "rf_paritylogging.h"
   60 #endif  /* RF_INCLUDE_PARITYLOGGING > 0 */
   61 #if     RF_INCLUDE_EVENODD > 0
   62 #include "rf_evenodd.h"
   63 #endif  /* RF_INCLUDE_EVENODD > 0 */
   64 #include "rf_general.h"
   65 #include "rf_driver.h"
   66 #include "rf_parityscan.h"
   67 #include "rf_reconbuffer.h"
   68 #include "rf_reconutil.h"
   69 
   70 /*****************************************************************************
   71  *
   72  * The layout switch defines all the layouts that are supported.
   73  * Fields are:  layout ID, init routine, shutdown routine, map sector,
   74  *              map parity, identify stripe, dag selection, map stripeid
   75  *              to parity stripe id (optional), num faults tolerated,
   76  *              special flags.
   77  *
   78  *****************************************************************************/
   79 
   80 static RF_AccessState_t DefaultStates[] = {
   81         rf_QuiesceState, rf_IncrAccessesCountState, rf_MapState,
   82         rf_LockState, rf_CreateDAGState, rf_ExecuteDAGState,
   83         rf_ProcessDAGState, rf_DecrAccessesCountState,
   84         rf_CleanupState, rf_LastState
   85 };
   86 
   87 #if     (defined(__NetBSD__) || defined(__OpenBSD__)) && !defined(_KERNEL)
   88 /*
   89  * XXX Gross hack to shutup gcc -- It complains that DefaultStates is not
   90  * used when compiling this in userland... I hate to burst its bubble, but
   91  * DefaultStates is used all over the place here in the initialization of
   92  * lots of data structures. GO
   93  */
   94 RF_AccessState_t *NothingAtAll = DefaultStates;
   95 #endif
   96 
   97 #if     (defined(__NetBSD__) || defined(__OpenBSD__)) && defined(_KERNEL)
   98 /* XXX Remove static so GCC doesn't complain about these being unused ! */
   99 int distSpareYes = 1;
  100 int distSpareNo = 0;
  101 #else
  102 static int distSpareYes = 1;
  103 static int distSpareNo = 0;
  104 #endif
  105 
  106 #ifdef  _KERNEL
  107 #define RF_NK2(a,b)
  108 #else   /* _KERNEL */
  109 #define RF_NK2(a,b)     a,b,
  110 #endif  /* !_KERNEL */
  111 
  112 #if     RF_UTILITY > 0
  113 #define RF_NU(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)
  114 #else   /* RF_UTILITY > 0 */
  115 #define RF_NU(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)  a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p
  116 #endif  /* RF_UTILITY > 0 */
  117 
  118 static RF_LayoutSW_t mapsw[] = {
  119         /* Parity declustering. */
  120         {'T', "Parity declustering",
  121                 RF_NK2(rf_MakeLayoutSpecificDeclustered, &distSpareNo)
  122                 RF_NU(
  123                     rf_ConfigureDeclustered,
  124                     rf_MapSectorDeclustered, rf_MapParityDeclustered, NULL,
  125                     rf_IdentifyStripeDeclustered,
  126                     rf_RaidFiveDagSelect,
  127                     rf_MapSIDToPSIDDeclustered,
  128                     rf_GetDefaultHeadSepLimitDeclustered,
  129                     rf_GetDefaultNumFloatingReconBuffersDeclustered,
  130                     NULL, NULL,
  131                     rf_SubmitReconBufferBasic,
  132                     rf_VerifyParityBasic,
  133                     1,
  134                     DefaultStates,
  135                     0)
  136         },
  137 
  138         /* Parity declustering with distributed sparing. */
  139         {'D', "Distributed sparing parity declustering",
  140                 RF_NK2(rf_MakeLayoutSpecificDeclustered, &distSpareYes)
  141                 RF_NU(
  142                     rf_ConfigureDeclusteredDS,
  143                     rf_MapSectorDeclustered, rf_MapParityDeclustered, NULL,
  144                     rf_IdentifyStripeDeclustered,
  145                     rf_RaidFiveDagSelect,
  146                     rf_MapSIDToPSIDDeclustered,
  147                     rf_GetDefaultHeadSepLimitDeclustered,
  148                     rf_GetDefaultNumFloatingReconBuffersDeclustered,
  149                     rf_GetNumSpareRUsDeclustered, rf_InstallSpareTable,
  150                     rf_SubmitReconBufferBasic,
  151                     rf_VerifyParityBasic,
  152                     1,
  153                     DefaultStates,
  154                     RF_DISTRIBUTE_SPARE | RF_BD_DECLUSTERED)
  155         },
  156 
  157 #if     RF_INCLUDE_DECL_PQ > 0
  158         /* Declustered P+Q. */
  159         {'Q', "Declustered P+Q",
  160                 RF_NK2(rf_MakeLayoutSpecificDeclustered, &distSpareNo)
  161                 RF_NU(
  162                     rf_ConfigureDeclusteredPQ,
  163                     rf_MapSectorDeclusteredPQ, rf_MapParityDeclusteredPQ,
  164                     rf_MapQDeclusteredPQ,
  165                     rf_IdentifyStripeDeclusteredPQ,
  166                     rf_PQDagSelect,
  167                     rf_MapSIDToPSIDDeclustered,
  168                     rf_GetDefaultHeadSepLimitDeclustered,
  169                     rf_GetDefaultNumFloatingReconBuffersPQ,
  170                     NULL, NULL,
  171                     NULL,
  172                     rf_VerifyParityBasic,
  173                     2,
  174                     DefaultStates,
  175                     0)
  176         },
  177 #endif  /* RF_INCLUDE_DECL_PQ > 0 */
  178 
  179 #if     RF_INCLUDE_RAID5_RS > 0
  180         /* RAID 5 with rotated sparing. */
  181         {'R', "RAID Level 5 rotated sparing",
  182                 RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
  183                 RF_NU(
  184                     rf_ConfigureRAID5_RS,
  185                     rf_MapSectorRAID5_RS, rf_MapParityRAID5_RS, NULL,
  186                     rf_IdentifyStripeRAID5_RS,
  187                     rf_RaidFiveDagSelect,
  188                     rf_MapSIDToPSIDRAID5_RS,
  189                     rf_GetDefaultHeadSepLimitRAID5,
  190                     rf_GetDefaultNumFloatingReconBuffersRAID5,
  191                     rf_GetNumSpareRUsRAID5_RS, NULL,
  192                     rf_SubmitReconBufferBasic,
  193                     rf_VerifyParityBasic,
  194                     1,
  195                     DefaultStates,
  196                     RF_DISTRIBUTE_SPARE)
  197         },
  198 #endif  /* RF_INCLUDE_RAID5_RS > 0 */
  199 
  200 #if     RF_INCLUDE_CHAINDECLUSTER > 0
  201         /* Chained Declustering. */
  202         {'C', "Chained Declustering",
  203                 RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
  204                 RF_NU(
  205                     rf_ConfigureChainDecluster,
  206                     rf_MapSectorChainDecluster, rf_MapParityChainDecluster,
  207                     NULL,
  208                     rf_IdentifyStripeChainDecluster,
  209                     rf_RAIDCDagSelect,
  210                     rf_MapSIDToPSIDChainDecluster,
  211                     NULL,
  212                     NULL,
  213                     rf_GetNumSpareRUsChainDecluster, NULL,
  214                     rf_SubmitReconBufferBasic,
  215                     rf_VerifyParityBasic,
  216                     1,
  217                     DefaultStates,
  218                     0)
  219         },
  220 #endif  /* RF_INCLUDE_CHAINDECLUSTER > 0 */
  221 
  222 #if     RF_INCLUDE_INTERDECLUSTER > 0
  223         /* Interleaved Declustering. */
  224         {'I', "Interleaved Declustering",
  225                 RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
  226                 RF_NU(
  227                     rf_ConfigureInterDecluster,
  228                     rf_MapSectorInterDecluster, rf_MapParityInterDecluster,
  229                     NULL,
  230                     rf_IdentifyStripeInterDecluster,
  231                     rf_RAIDIDagSelect,
  232                     rf_MapSIDToPSIDInterDecluster,
  233                     rf_GetDefaultHeadSepLimitInterDecluster,
  234                     rf_GetDefaultNumFloatingReconBuffersInterDecluster,
  235                     rf_GetNumSpareRUsInterDecluster, NULL,
  236                     rf_SubmitReconBufferBasic,
  237                     rf_VerifyParityBasic,
  238                     1,
  239                     DefaultStates,
  240                     RF_DISTRIBUTE_SPARE)
  241         },
  242 #endif  /* RF_INCLUDE_INTERDECLUSTER > 0 */
  243 
  244 #if     RF_INCLUDE_RAID0 > 0
  245         /* RAID level 0. */
  246         {'0', "RAID Level 0",
  247                 RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
  248                 RF_NU(
  249                     rf_ConfigureRAID0,
  250                     rf_MapSectorRAID0, rf_MapParityRAID0, NULL,
  251                     rf_IdentifyStripeRAID0,
  252                     rf_RAID0DagSelect,
  253                     rf_MapSIDToPSIDRAID0,
  254                     NULL,
  255                     NULL,
  256                     NULL, NULL,
  257                     NULL,
  258                     rf_VerifyParityRAID0,
  259                     0,
  260                     DefaultStates,
  261                     0)
  262         },
  263 #endif  /* RF_INCLUDE_RAID0 > 0 */
  264 
  265 #if     RF_INCLUDE_RAID1 > 0
  266         /* RAID level 1. */
  267         {'1', "RAID Level 1",
  268                 RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
  269                 RF_NU(
  270                     rf_ConfigureRAID1,
  271                     rf_MapSectorRAID1, rf_MapParityRAID1, NULL,
  272                     rf_IdentifyStripeRAID1,
  273                     rf_RAID1DagSelect,
  274                     rf_MapSIDToPSIDRAID1,
  275                     NULL,
  276                     NULL,
  277                     NULL, NULL,
  278                     rf_SubmitReconBufferRAID1,
  279                     rf_VerifyParityRAID1,
  280                     1,
  281                     DefaultStates,
  282                     0)
  283         },
  284 #endif  /* RF_INCLUDE_RAID1 > 0 */
  285 
  286 #if     RF_INCLUDE_RAID4 > 0
  287         /* RAID level 4. */
  288         {'4', "RAID Level 4",
  289                 RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
  290                 RF_NU(
  291                     rf_ConfigureRAID4,
  292                     rf_MapSectorRAID4, rf_MapParityRAID4, NULL,
  293                     rf_IdentifyStripeRAID4,
  294                     rf_RaidFiveDagSelect,
  295                     rf_MapSIDToPSIDRAID4,
  296                     rf_GetDefaultHeadSepLimitRAID4,
  297                     rf_GetDefaultNumFloatingReconBuffersRAID4,
  298                     NULL, NULL,
  299                     rf_SubmitReconBufferBasic,
  300                     rf_VerifyParityBasic,
  301                     1,
  302                     DefaultStates,
  303                     0)
  304         },
  305 #endif  /* RF_INCLUDE_RAID4 > 0 */
  306 
  307 #if     RF_INCLUDE_RAID5 > 0
  308         /* RAID level 5. */
  309         {'5', "RAID Level 5",
  310                 RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
  311                 RF_NU(
  312                     rf_ConfigureRAID5,
  313                     rf_MapSectorRAID5, rf_MapParityRAID5, NULL,
  314                     rf_IdentifyStripeRAID5,
  315                     rf_RaidFiveDagSelect,
  316                     rf_MapSIDToPSIDRAID5,
  317                     rf_GetDefaultHeadSepLimitRAID5,
  318                     rf_GetDefaultNumFloatingReconBuffersRAID5,
  319                     NULL, NULL,
  320                     rf_SubmitReconBufferBasic,
  321                     rf_VerifyParityBasic,
  322                     1,
  323                     DefaultStates,
  324                     0)
  325         },
  326 #endif  /* RF_INCLUDE_RAID5 > 0 */
  327 
  328 #if     RF_INCLUDE_EVENODD > 0
  329         /* Evenodd. */
  330         {'E', "EvenOdd",
  331                 RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
  332                 RF_NU(
  333                     rf_ConfigureEvenOdd,
  334                     rf_MapSectorRAID5, rf_MapParityEvenOdd, rf_MapEEvenOdd,
  335                     rf_IdentifyStripeEvenOdd,
  336                     rf_EODagSelect,
  337                     rf_MapSIDToPSIDRAID5,
  338                     NULL,
  339                     NULL,
  340                     NULL, NULL,
  341                     NULL,       /* No reconstruction, yet. */
  342                     rf_VerifyParityEvenOdd,
  343                     2,
  344                     DefaultStates,
  345                     0)
  346         },
  347 #endif  /* RF_INCLUDE_EVENODD > 0 */
  348 
  349 #if     RF_INCLUDE_EVENODD > 0
  350         /* Declustered Evenodd. */
  351         {'e', "Declustered EvenOdd",
  352                 RF_NK2(rf_MakeLayoutSpecificDeclustered, &distSpareNo)
  353                 RF_NU(
  354                     rf_ConfigureDeclusteredPQ,
  355                     rf_MapSectorDeclusteredPQ, rf_MapParityDeclusteredPQ,
  356                     rf_MapQDeclusteredPQ,
  357                     rf_IdentifyStripeDeclusteredPQ,
  358                     rf_EODagSelect,
  359                     rf_MapSIDToPSIDRAID5,
  360                     rf_GetDefaultHeadSepLimitDeclustered,
  361                     rf_GetDefaultNumFloatingReconBuffersPQ,
  362                     NULL, NULL,
  363                     NULL,       /* No reconstruction, yet. */
  364                     rf_VerifyParityEvenOdd,
  365                     2,
  366                     DefaultStates,
  367                     0)
  368         },
  369 #endif  /* RF_INCLUDE_EVENODD > 0 */
  370 
  371 #if     RF_INCLUDE_PARITYLOGGING > 0
  372         /* Parity logging. */
  373         {'L', "Parity logging",
  374                 RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
  375                 RF_NU(
  376                     rf_ConfigureParityLogging,
  377                     rf_MapSectorParityLogging, rf_MapParityParityLogging, NULL,
  378                     rf_IdentifyStripeParityLogging,
  379                     rf_ParityLoggingDagSelect,
  380                     rf_MapSIDToPSIDParityLogging,
  381                     rf_GetDefaultHeadSepLimitParityLogging,
  382                     rf_GetDefaultNumFloatingReconBuffersParityLogging,
  383                     NULL, NULL,
  384                     rf_SubmitReconBufferBasic,
  385                     NULL,
  386                     1,
  387                     DefaultStates,
  388                     0)
  389         },
  390 #endif  /* RF_INCLUDE_PARITYLOGGING > 0 */
  391 
  392         /* End-of-list marker. */
  393         {'\0', NULL,
  394                 RF_NK2(NULL, NULL)
  395                 RF_NU(
  396                     NULL,
  397                     NULL, NULL, NULL,
  398                     NULL,
  399                     NULL,
  400                     NULL,
  401                     NULL,
  402                     NULL,
  403                     NULL, NULL,
  404                     NULL,
  405                     NULL,
  406                     0,
  407                     NULL,
  408                     0)
  409         }
  410 };
  411 
  412 RF_LayoutSW_t *
  413 rf_GetLayout(RF_ParityConfig_t parityConfig)
  414 {
  415         RF_LayoutSW_t *p;
  416 
  417         /* Look up the specific layout. */
  418         for (p = &mapsw[0]; p->parityConfig; p++)
  419                 if (p->parityConfig == parityConfig)
  420                         break;
  421         if (!p->parityConfig)
  422                 return (NULL);
  423         RF_ASSERT(p->parityConfig == parityConfig);
  424         return (p);
  425 }
  426 
  427 #if     RF_UTILITY == 0
  428 /*****************************************************************************
  429  *
  430  * ConfigureLayout
  431  *
  432  * Read the configuration file and set up the RAID layout parameters.
  433  * After reading common params, invokes the layout-specific configuration
  434  * routine to finish the configuration.
  435  *
  436  *****************************************************************************/
  437 int
  438 rf_ConfigureLayout(RF_ShutdownList_t **listp, RF_Raid_t *raidPtr,
  439     RF_Config_t *cfgPtr)
  440 {
  441         RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout);
  442         RF_ParityConfig_t parityConfig;
  443         RF_LayoutSW_t *p;
  444         int retval;
  445 
  446         layoutPtr->sectorsPerStripeUnit = cfgPtr->sectPerSU;
  447         layoutPtr->SUsPerPU = cfgPtr->SUsPerPU;
  448         layoutPtr->SUsPerRU = cfgPtr->SUsPerRU;
  449         parityConfig = cfgPtr->parityConfig;
  450 
  451         if (layoutPtr->sectorsPerStripeUnit <= 0) {
  452                 RF_ERRORMSG2("raid%d: Invalid sectorsPerStripeUnit: %d.\n",
  453                     raidPtr->raidid, (int)layoutPtr->sectorsPerStripeUnit);
  454                 return (EINVAL);
  455         }
  456 
  457         layoutPtr->stripeUnitsPerDisk = raidPtr->sectorsPerDisk /
  458             layoutPtr->sectorsPerStripeUnit;
  459 
  460         p = rf_GetLayout(parityConfig);
  461         if (p == NULL) {
  462                 RF_ERRORMSG1("Unknown parity configuration '%c'", parityConfig);
  463                 return (EINVAL);
  464         }
  465         RF_ASSERT(p->parityConfig == parityConfig);
  466         layoutPtr->map = p;
  467 
  468         /* Initialize the specific layout. */
  469 
  470         retval = (p->Configure) (listp, raidPtr, cfgPtr);
  471 
  472         if (retval)
  473                 return (retval);
  474 
  475         layoutPtr->dataBytesPerStripe = layoutPtr->dataSectorsPerStripe <<
  476             raidPtr->logBytesPerSector;
  477         raidPtr->sectorsPerDisk = layoutPtr->stripeUnitsPerDisk *
  478             layoutPtr->sectorsPerStripeUnit;
  479 
  480         if (rf_forceNumFloatingReconBufs >= 0) {
  481                 raidPtr->numFloatingReconBufs = rf_forceNumFloatingReconBufs;
  482         } else {
  483                 raidPtr->numFloatingReconBufs =
  484                     rf_GetDefaultNumFloatingReconBuffers(raidPtr);
  485         }
  486 
  487         if (rf_forceHeadSepLimit >= 0) {
  488                 raidPtr->headSepLimit = rf_forceHeadSepLimit;
  489         } else {
  490                 raidPtr->headSepLimit = rf_GetDefaultHeadSepLimit(raidPtr);
  491         }
  492 
  493 #ifdef  RAIDDEBUG
  494         if (raidPtr->headSepLimit >= 0) {
  495                 printf("RAIDFRAME(%s): Using %ld floating recon bufs"
  496                     " with head sep limit %ld.\n", layoutPtr->map->configName,
  497                     (long) raidPtr->numFloatingReconBufs,
  498                     (long) raidPtr->headSepLimit);
  499         } else {
  500                 printf("RAIDFRAME(%s): Using %ld floating recon bufs"
  501                     " with no head sep limit.\n", layoutPtr->map->configName,
  502                     (long) raidPtr->numFloatingReconBufs);
  503         }
  504 #endif  /* RAIDDEBUG */
  505 
  506         return (0);
  507 }
  508 
  509 /*
  510  * Typically there is a 1-1 mapping between stripes and parity stripes.
  511  * However, the declustering code supports packing multiple stripes into
  512  * a single parity stripe, so as to increase the size of the reconstruction
  513  * unit without affecting the size of the stripe unit. This routine finds
  514  * the parity stripe identifier associated with a stripe ID. There is also
  515  * a RaidAddressToParityStripeID macro in layout.h
  516  */
  517 RF_StripeNum_t
  518 rf_MapStripeIDToParityStripeID(RF_RaidLayout_t *layoutPtr,
  519     RF_StripeNum_t stripeID, RF_ReconUnitNum_t *which_ru)
  520 {
  521         RF_StripeNum_t parityStripeID;
  522 
  523         /* Quick exit in the common case of SUsPerPU == 1. */
  524         if ((layoutPtr->SUsPerPU == 1) || !layoutPtr->map->MapSIDToPSID) {
  525                 *which_ru = 0;
  526                 return (stripeID);
  527         } else {
  528                 (layoutPtr->map->MapSIDToPSID) (layoutPtr, stripeID,
  529                     &parityStripeID, which_ru);
  530         }
  531         return (parityStripeID);
  532 }
  533 #endif  /* RF_UTILITY == 0 */

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