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_layout.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_layout.c,v 1.16 2004/01/04 06:37:16 oster Exp $     */
    2 /*
    3  * Copyright (c) 1995 Carnegie-Mellon University.
    4  * All rights reserved.
    5  *
    6  * Author: Mark Holland
    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 /* rf_layout.c -- driver code dealing with layout and mapping issues
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __KERNEL_RCSID(0, "$NetBSD: rf_layout.c,v 1.16 2004/01/04 06:37:16 oster Exp $");
   34 
   35 #include <dev/raidframe/raidframevar.h>
   36 
   37 #include "rf_archs.h"
   38 #include "rf_raid.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
   74  *    sector, map parity, identify stripe, dag selection, map stripeid
   75  *    to parity stripe id (optional), num faults tolerated, special
   76  *    flags.
   77  *
   78  ***********************************************************************/
   79 
   80 static const RF_AccessState_t DefaultStates[] = {
   81                                            rf_QuiesceState,
   82                                            rf_IncrAccessesCountState, 
   83                                            rf_MapState, 
   84                                            rf_LockState, 
   85                                            rf_CreateDAGState,
   86                                            rf_ExecuteDAGState, 
   87                                            rf_ProcessDAGState, 
   88                                            rf_CleanupState, 
   89                                            rf_DecrAccessesCountState,
   90                                            rf_LastState};
   91 
   92 #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
   93 
   94 /* Note that if you add any new RAID types to this list, that you must
   95    also update the mapsw[] table in the raidctl sources */
   96 
   97 static const RF_LayoutSW_t mapsw[] = {
   98 #if RF_INCLUDE_PARITY_DECLUSTERING > 0
   99         /* parity declustering */
  100         {'T', "Parity declustering",
  101                 RF_NU(
  102                     rf_ConfigureDeclustered,
  103                     rf_MapSectorDeclustered, rf_MapParityDeclustered, NULL,
  104                     rf_IdentifyStripeDeclustered,
  105                     rf_RaidFiveDagSelect,
  106                     rf_MapSIDToPSIDDeclustered,
  107                     rf_GetDefaultHeadSepLimitDeclustered,
  108                     rf_GetDefaultNumFloatingReconBuffersDeclustered,
  109                     NULL, NULL,
  110                     rf_SubmitReconBufferBasic,
  111                     rf_VerifyParityBasic,
  112                     1,
  113                     DefaultStates,
  114                     0)
  115         },
  116 #endif
  117 
  118 #if RF_INCLUDE_PARITY_DECLUSTERING_DS > 0
  119         /* parity declustering with distributed sparing */
  120         {'D', "Distributed sparing parity declustering",
  121                 RF_NU(
  122                     rf_ConfigureDeclusteredDS,
  123                     rf_MapSectorDeclustered, rf_MapParityDeclustered, NULL,
  124                     rf_IdentifyStripeDeclustered,
  125                     rf_RaidFiveDagSelect,
  126                     rf_MapSIDToPSIDDeclustered,
  127                     rf_GetDefaultHeadSepLimitDeclustered,
  128                     rf_GetDefaultNumFloatingReconBuffersDeclustered,
  129                     rf_GetNumSpareRUsDeclustered, rf_InstallSpareTable,
  130                     rf_SubmitReconBufferBasic,
  131                     rf_VerifyParityBasic,
  132                     1,
  133                     DefaultStates,
  134                     RF_DISTRIBUTE_SPARE | RF_BD_DECLUSTERED)
  135         },
  136 #endif
  137 
  138 #if RF_INCLUDE_DECL_PQ > 0
  139         /* declustered P+Q */
  140         {'Q', "Declustered P+Q",
  141                 RF_NU(
  142                     rf_ConfigureDeclusteredPQ,
  143                     rf_MapSectorDeclusteredPQ, rf_MapParityDeclusteredPQ, rf_MapQDeclusteredPQ,
  144                     rf_IdentifyStripeDeclusteredPQ,
  145                     rf_PQDagSelect,
  146                     rf_MapSIDToPSIDDeclustered,
  147                     rf_GetDefaultHeadSepLimitDeclustered,
  148                     rf_GetDefaultNumFloatingReconBuffersPQ,
  149                     NULL, NULL,
  150                     NULL,
  151                     rf_VerifyParityBasic,
  152                     2,
  153                     DefaultStates,
  154                     0)
  155         },
  156 #endif                          /* RF_INCLUDE_DECL_PQ > 0 */
  157 
  158 #if RF_INCLUDE_RAID5_RS > 0
  159         /* RAID 5 with rotated sparing */
  160         {'R', "RAID Level 5 rotated sparing",
  161                 RF_NU(
  162                     rf_ConfigureRAID5_RS,
  163                     rf_MapSectorRAID5_RS, rf_MapParityRAID5_RS, NULL,
  164                     rf_IdentifyStripeRAID5_RS,
  165                     rf_RaidFiveDagSelect,
  166                     rf_MapSIDToPSIDRAID5_RS,
  167                     rf_GetDefaultHeadSepLimitRAID5,
  168                     rf_GetDefaultNumFloatingReconBuffersRAID5,
  169                     rf_GetNumSpareRUsRAID5_RS, NULL,
  170                     rf_SubmitReconBufferBasic,
  171                     rf_VerifyParityBasic,
  172                     1,
  173                     DefaultStates,
  174                     RF_DISTRIBUTE_SPARE)
  175         },
  176 #endif                          /* RF_INCLUDE_RAID5_RS > 0 */
  177 
  178 #if RF_INCLUDE_CHAINDECLUSTER > 0
  179         /* Chained Declustering */
  180         {'C', "Chained Declustering",
  181                 RF_NU(
  182                     rf_ConfigureChainDecluster,
  183                     rf_MapSectorChainDecluster, rf_MapParityChainDecluster, NULL,
  184                     rf_IdentifyStripeChainDecluster,
  185                     rf_RAIDCDagSelect,
  186                     rf_MapSIDToPSIDChainDecluster,
  187                     NULL,
  188                     NULL,
  189                     rf_GetNumSpareRUsChainDecluster, NULL,
  190                     rf_SubmitReconBufferBasic,
  191                     rf_VerifyParityBasic,
  192                     1,
  193                     DefaultStates,
  194                     0)
  195         },
  196 #endif                          /* RF_INCLUDE_CHAINDECLUSTER > 0 */
  197 
  198 #if RF_INCLUDE_INTERDECLUSTER > 0
  199         /* Interleaved Declustering */
  200         {'I', "Interleaved Declustering",
  201                 RF_NU(
  202                     rf_ConfigureInterDecluster,
  203                     rf_MapSectorInterDecluster, rf_MapParityInterDecluster, NULL,
  204                     rf_IdentifyStripeInterDecluster,
  205                     rf_RAIDIDagSelect,
  206                     rf_MapSIDToPSIDInterDecluster,
  207                     rf_GetDefaultHeadSepLimitInterDecluster,
  208                     rf_GetDefaultNumFloatingReconBuffersInterDecluster,
  209                     rf_GetNumSpareRUsInterDecluster, NULL,
  210                     rf_SubmitReconBufferBasic,
  211                     rf_VerifyParityBasic,
  212                     1,
  213                     DefaultStates,
  214                     RF_DISTRIBUTE_SPARE)
  215         },
  216 #endif                          /* RF_INCLUDE_INTERDECLUSTER > 0 */
  217 
  218 #if RF_INCLUDE_RAID0 > 0
  219         /* RAID level 0 */
  220         {'', "RAID Level 0",
  221                 RF_NU(
  222                     rf_ConfigureRAID0,
  223                     rf_MapSectorRAID0, rf_MapParityRAID0, NULL,
  224                     rf_IdentifyStripeRAID0,
  225                     rf_RAID0DagSelect,
  226                     rf_MapSIDToPSIDRAID0,
  227                     NULL,
  228                     NULL,
  229                     NULL, NULL,
  230                     NULL,
  231                     rf_VerifyParityRAID0,
  232                     0,
  233                     DefaultStates,
  234                     0)
  235         },
  236 #endif                          /* RF_INCLUDE_RAID0 > 0 */
  237 
  238 #if RF_INCLUDE_RAID1 > 0
  239         /* RAID level 1 */
  240         {'1', "RAID Level 1",
  241                 RF_NU(
  242                     rf_ConfigureRAID1,
  243                     rf_MapSectorRAID1, rf_MapParityRAID1, NULL,
  244                     rf_IdentifyStripeRAID1,
  245                     rf_RAID1DagSelect,
  246                     rf_MapSIDToPSIDRAID1,
  247                     NULL,
  248                     NULL,
  249                     NULL, NULL,
  250                     rf_SubmitReconBufferRAID1,
  251                     rf_VerifyParityRAID1,
  252                     1,
  253                     DefaultStates,
  254                     0)
  255         },
  256 #endif                          /* RF_INCLUDE_RAID1 > 0 */
  257 
  258 #if RF_INCLUDE_RAID4 > 0
  259         /* RAID level 4 */
  260         {'4', "RAID Level 4",
  261                 RF_NU(
  262                     rf_ConfigureRAID4,
  263                     rf_MapSectorRAID4, rf_MapParityRAID4, NULL,
  264                     rf_IdentifyStripeRAID4,
  265                     rf_RaidFiveDagSelect,
  266                     rf_MapSIDToPSIDRAID4,
  267                     rf_GetDefaultHeadSepLimitRAID4,
  268                     rf_GetDefaultNumFloatingReconBuffersRAID4,
  269                     NULL, NULL,
  270                     rf_SubmitReconBufferBasic,
  271                     rf_VerifyParityBasic,
  272                     1,
  273                     DefaultStates,
  274                     0)
  275         },
  276 #endif                          /* RF_INCLUDE_RAID4 > 0 */
  277 
  278 #if RF_INCLUDE_RAID5 > 0
  279         /* RAID level 5 */
  280         {'5', "RAID Level 5",
  281                 RF_NU(
  282                     rf_ConfigureRAID5,
  283                     rf_MapSectorRAID5, rf_MapParityRAID5, NULL,
  284                     rf_IdentifyStripeRAID5,
  285                     rf_RaidFiveDagSelect,
  286                     rf_MapSIDToPSIDRAID5,
  287                     rf_GetDefaultHeadSepLimitRAID5,
  288                     rf_GetDefaultNumFloatingReconBuffersRAID5,
  289                     NULL, NULL,
  290                     rf_SubmitReconBufferBasic,
  291                     rf_VerifyParityBasic,
  292                     1,
  293                     DefaultStates,
  294                     0)
  295         },
  296 #endif                          /* RF_INCLUDE_RAID5 > 0 */
  297 
  298 #if RF_INCLUDE_EVENODD > 0
  299         /* Evenodd */
  300         {'E', "EvenOdd",
  301                 RF_NU(
  302                     rf_ConfigureEvenOdd,
  303                     rf_MapSectorRAID5, rf_MapParityEvenOdd, rf_MapEEvenOdd,
  304                     rf_IdentifyStripeEvenOdd,
  305                     rf_EODagSelect,
  306                     rf_MapSIDToPSIDRAID5,
  307                     NULL,
  308                     NULL,
  309                     NULL, NULL,
  310                     NULL,       /* no reconstruction, yet */
  311                     rf_VerifyParityEvenOdd,
  312                     2,
  313                     DefaultStates,
  314                     0)
  315         },
  316 #endif                          /* RF_INCLUDE_EVENODD > 0 */
  317 
  318 #if RF_INCLUDE_EVENODD > 0
  319         /* Declustered Evenodd */
  320         {'e', "Declustered EvenOdd",
  321                 RF_NU(
  322                     rf_ConfigureDeclusteredPQ,
  323                     rf_MapSectorDeclusteredPQ, rf_MapParityDeclusteredPQ, rf_MapQDeclusteredPQ,
  324                     rf_IdentifyStripeDeclusteredPQ,
  325                     rf_EODagSelect,
  326                     rf_MapSIDToPSIDRAID5,
  327                     rf_GetDefaultHeadSepLimitDeclustered,
  328                     rf_GetDefaultNumFloatingReconBuffersPQ,
  329                     NULL, NULL,
  330                     NULL,       /* no reconstruction, yet */
  331                     rf_VerifyParityEvenOdd,
  332                     2,
  333                     DefaultStates,
  334                     0)
  335         },
  336 #endif                          /* RF_INCLUDE_EVENODD > 0 */
  337 
  338 #if RF_INCLUDE_PARITYLOGGING > 0
  339         /* parity logging */
  340         {'L', "Parity logging",
  341                 RF_NU(
  342                     rf_ConfigureParityLogging,
  343                     rf_MapSectorParityLogging, rf_MapParityParityLogging, NULL,
  344                     rf_IdentifyStripeParityLogging,
  345                     rf_ParityLoggingDagSelect,
  346                     rf_MapSIDToPSIDParityLogging,
  347                     rf_GetDefaultHeadSepLimitParityLogging,
  348                     rf_GetDefaultNumFloatingReconBuffersParityLogging,
  349                     NULL, NULL,
  350                     rf_SubmitReconBufferBasic,
  351                     NULL,
  352                     1,
  353                     DefaultStates,
  354                     0)
  355         },
  356 #endif                          /* RF_INCLUDE_PARITYLOGGING > 0 */
  357 
  358         /* end-of-list marker */
  359         {'\0', NULL,
  360                 RF_NU(
  361                     NULL,
  362                     NULL, NULL, NULL,
  363                     NULL,
  364                     NULL,
  365                     NULL,
  366                     NULL,
  367                     NULL,
  368                     NULL, NULL,
  369                     NULL,
  370                     NULL,
  371                     0,
  372                     NULL,
  373                     0)
  374         }
  375 };
  376 
  377 const RF_LayoutSW_t *
  378 rf_GetLayout(RF_ParityConfig_t parityConfig)
  379 {
  380         const RF_LayoutSW_t *p;
  381 
  382         /* look up the specific layout */
  383         for (p = &mapsw[0]; p->parityConfig; p++)
  384                 if (p->parityConfig == parityConfig)
  385                         break;
  386         if (!p->parityConfig)
  387                 return (NULL);
  388         RF_ASSERT(p->parityConfig == parityConfig);
  389         return (p);
  390 }
  391 
  392 /*****************************************************************************
  393  *
  394  * ConfigureLayout --
  395  *
  396  * read the configuration file and set up the RAID layout parameters.
  397  * After reading common params, invokes the layout-specific
  398  * configuration routine to finish the configuration.
  399  *
  400  ****************************************************************************/
  401 int 
  402 rf_ConfigureLayout(RF_ShutdownList_t **listp, RF_Raid_t *raidPtr,
  403                    RF_Config_t *cfgPtr)
  404 {
  405         RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout);
  406         RF_ParityConfig_t parityConfig;
  407         const RF_LayoutSW_t *p;
  408         int     retval;
  409 
  410         layoutPtr->sectorsPerStripeUnit = cfgPtr->sectPerSU;
  411         layoutPtr->SUsPerPU = cfgPtr->SUsPerPU;
  412         layoutPtr->SUsPerRU = cfgPtr->SUsPerRU;
  413         parityConfig = cfgPtr->parityConfig;
  414 
  415         if (layoutPtr->sectorsPerStripeUnit <= 0) {
  416                 RF_ERRORMSG2("raid%d: Invalid sectorsPerStripeUnit: %d\n",
  417                              raidPtr->raidid, 
  418                              (int)layoutPtr->sectorsPerStripeUnit );
  419                 return (EINVAL); 
  420         }
  421 
  422         layoutPtr->stripeUnitsPerDisk = raidPtr->sectorsPerDisk / layoutPtr->sectorsPerStripeUnit;
  423 
  424         p = rf_GetLayout(parityConfig);
  425         if (p == NULL) {
  426                 RF_ERRORMSG1("Unknown parity configuration '%c'", parityConfig);
  427                 return (EINVAL);
  428         }
  429         RF_ASSERT(p->parityConfig == parityConfig);
  430         layoutPtr->map = p;
  431 
  432         /* initialize the specific layout */
  433 
  434         retval = (p->Configure) (listp, raidPtr, cfgPtr);
  435 
  436         if (retval)
  437                 return (retval);
  438 
  439         raidPtr->sectorsPerDisk = layoutPtr->stripeUnitsPerDisk * layoutPtr->sectorsPerStripeUnit;
  440 
  441         if (rf_forceNumFloatingReconBufs >= 0) {
  442                 raidPtr->numFloatingReconBufs = rf_forceNumFloatingReconBufs;
  443         } else {
  444                 raidPtr->numFloatingReconBufs = rf_GetDefaultNumFloatingReconBuffers(raidPtr);
  445         }
  446 
  447         if (rf_forceHeadSepLimit >= 0) {
  448                 raidPtr->headSepLimit = rf_forceHeadSepLimit;
  449         } else {
  450                 raidPtr->headSepLimit = rf_GetDefaultHeadSepLimit(raidPtr);
  451         }
  452         return (0);
  453 }
  454 /* typically there is a 1-1 mapping between stripes and parity stripes.
  455  * however, the declustering code supports packing multiple stripes into
  456  * a single parity stripe, so as to increase the size of the reconstruction
  457  * unit without affecting the size of the stripe unit.  This routine finds
  458  * the parity stripe identifier associated with a stripe ID.  There is also
  459  * a RaidAddressToParityStripeID macro in layout.h
  460  */
  461 RF_StripeNum_t 
  462 rf_MapStripeIDToParityStripeID(RF_RaidLayout_t *layoutPtr,
  463                                RF_StripeNum_t stripeID,
  464                                RF_ReconUnitNum_t *which_ru)
  465 {
  466         RF_StripeNum_t parityStripeID;
  467 
  468         /* quick exit in the common case of SUsPerPU==1 */
  469         if ((layoutPtr->SUsPerPU == 1) || !layoutPtr->map->MapSIDToPSID) {
  470                 *which_ru = 0;
  471                 return (stripeID);
  472         } else {
  473                 (layoutPtr->map->MapSIDToPSID) (layoutPtr, stripeID, &parityStripeID, which_ru);
  474         }
  475         return (parityStripeID);
  476 }

Cache object: 7b41f1b4d0c9d09e0214ec4978832641


[ 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.