Home | History | Annotate | Line # | Download | only in raidframe
      1  1.20     oster /*	$NetBSD: rf_layout.c,v 1.20 2008/05/04 20:57:23 oster Exp $	*/
      2   1.1     oster /*
      3   1.1     oster  * Copyright (c) 1995 Carnegie-Mellon University.
      4   1.1     oster  * All rights reserved.
      5   1.1     oster  *
      6   1.1     oster  * Author: Mark Holland
      7   1.1     oster  *
      8   1.1     oster  * Permission to use, copy, modify and distribute this software and
      9   1.1     oster  * its documentation is hereby granted, provided that both the copyright
     10   1.1     oster  * notice and this permission notice appear in all copies of the
     11   1.1     oster  * software, derivative works or modified versions, and any portions
     12   1.1     oster  * thereof, and that both notices appear in supporting documentation.
     13   1.1     oster  *
     14   1.1     oster  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
     15   1.1     oster  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
     16   1.1     oster  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
     17   1.1     oster  *
     18   1.1     oster  * Carnegie Mellon requests users of this software to return to
     19   1.1     oster  *
     20   1.1     oster  *  Software Distribution Coordinator  or  Software.Distribution (at) CS.CMU.EDU
     21   1.1     oster  *  School of Computer Science
     22   1.1     oster  *  Carnegie Mellon University
     23   1.1     oster  *  Pittsburgh PA 15213-3890
     24   1.1     oster  *
     25   1.1     oster  * any improvements or extensions that they make and grant Carnegie the
     26   1.1     oster  * rights to redistribute these changes.
     27   1.1     oster  */
     28   1.1     oster 
     29   1.1     oster /* rf_layout.c -- driver code dealing with layout and mapping issues
     30   1.1     oster  */
     31  1.11     lukem 
     32  1.11     lukem #include <sys/cdefs.h>
     33  1.20     oster __KERNEL_RCSID(0, "$NetBSD: rf_layout.c,v 1.20 2008/05/04 20:57:23 oster Exp $");
     34   1.1     oster 
     35  1.10     oster #include <dev/raidframe/raidframevar.h>
     36  1.10     oster 
     37   1.1     oster #include "rf_archs.h"
     38   1.1     oster #include "rf_raid.h"
     39   1.1     oster #include "rf_dag.h"
     40   1.1     oster #include "rf_desc.h"
     41   1.1     oster #include "rf_decluster.h"
     42   1.1     oster #include "rf_pq.h"
     43   1.1     oster #include "rf_declusterPQ.h"
     44   1.1     oster #include "rf_raid0.h"
     45   1.1     oster #include "rf_raid1.h"
     46   1.1     oster #include "rf_raid4.h"
     47   1.1     oster #include "rf_raid5.h"
     48   1.1     oster #include "rf_states.h"
     49   1.1     oster #if RF_INCLUDE_RAID5_RS > 0
     50   1.1     oster #include "rf_raid5_rotatedspare.h"
     51   1.3     oster #endif				/* RF_INCLUDE_RAID5_RS > 0 */
     52   1.1     oster #if RF_INCLUDE_CHAINDECLUSTER > 0
     53   1.1     oster #include "rf_chaindecluster.h"
     54   1.3     oster #endif				/* RF_INCLUDE_CHAINDECLUSTER > 0 */
     55   1.1     oster #if RF_INCLUDE_INTERDECLUSTER > 0
     56   1.1     oster #include "rf_interdecluster.h"
     57   1.3     oster #endif				/* RF_INCLUDE_INTERDECLUSTER > 0 */
     58   1.1     oster #if RF_INCLUDE_PARITYLOGGING > 0
     59   1.1     oster #include "rf_paritylogging.h"
     60   1.3     oster #endif				/* RF_INCLUDE_PARITYLOGGING > 0 */
     61   1.1     oster #if RF_INCLUDE_EVENODD > 0
     62   1.1     oster #include "rf_evenodd.h"
     63   1.3     oster #endif				/* RF_INCLUDE_EVENODD > 0 */
     64   1.1     oster #include "rf_general.h"
     65   1.1     oster #include "rf_driver.h"
     66   1.1     oster #include "rf_parityscan.h"
     67   1.1     oster #include "rf_reconbuffer.h"
     68   1.1     oster #include "rf_reconutil.h"
     69   1.1     oster 
     70   1.1     oster /***********************************************************************
     71   1.1     oster  *
     72   1.1     oster  * the layout switch defines all the layouts that are supported.
     73   1.1     oster  *    fields are: layout ID, init routine, shutdown routine, map
     74   1.1     oster  *    sector, map parity, identify stripe, dag selection, map stripeid
     75   1.1     oster  *    to parity stripe id (optional), num faults tolerated, special
     76   1.1     oster  *    flags.
     77   1.1     oster  *
     78   1.1     oster  ***********************************************************************/
     79   1.1     oster 
     80  1.14  jdolecek static const RF_AccessState_t DefaultStates[] = {
     81  1.14  jdolecek 					   rf_QuiesceState,
     82  1.17     perry 					   rf_IncrAccessesCountState,
     83  1.17     perry 					   rf_MapState,
     84  1.17     perry 					   rf_LockState,
     85   1.9     oster 					   rf_CreateDAGState,
     86  1.17     perry 					   rf_ExecuteDAGState,
     87  1.17     perry 					   rf_ProcessDAGState,
     88  1.17     perry 					   rf_CleanupState,
     89   1.9     oster 					   rf_DecrAccessesCountState,
     90   1.9     oster 					   rf_LastState};
     91   1.3     oster 
     92   1.9     oster #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   1.8     oster 
     94   1.9     oster /* Note that if you add any new RAID types to this list, that you must
     95   1.9     oster    also update the mapsw[] table in the raidctl sources */
     96   1.1     oster 
     97  1.14  jdolecek static const RF_LayoutSW_t mapsw[] = {
     98   1.7     oster #if RF_INCLUDE_PARITY_DECLUSTERING > 0
     99   1.1     oster 	/* parity declustering */
    100   1.1     oster 	{'T', "Parity declustering",
    101   1.3     oster 		RF_NU(
    102   1.3     oster 		    rf_ConfigureDeclustered,
    103   1.3     oster 		    rf_MapSectorDeclustered, rf_MapParityDeclustered, NULL,
    104   1.3     oster 		    rf_IdentifyStripeDeclustered,
    105   1.3     oster 		    rf_RaidFiveDagSelect,
    106   1.3     oster 		    rf_MapSIDToPSIDDeclustered,
    107   1.3     oster 		    rf_GetDefaultHeadSepLimitDeclustered,
    108   1.3     oster 		    rf_GetDefaultNumFloatingReconBuffersDeclustered,
    109   1.3     oster 		    NULL, NULL,
    110   1.3     oster 		    rf_SubmitReconBufferBasic,
    111   1.3     oster 		    rf_VerifyParityBasic,
    112   1.3     oster 		    1,
    113   1.3     oster 		    DefaultStates,
    114   1.3     oster 		    0)
    115   1.1     oster 	},
    116   1.7     oster #endif
    117   1.1     oster 
    118   1.7     oster #if RF_INCLUDE_PARITY_DECLUSTERING_DS > 0
    119   1.1     oster 	/* parity declustering with distributed sparing */
    120   1.1     oster 	{'D', "Distributed sparing parity declustering",
    121   1.3     oster 		RF_NU(
    122   1.3     oster 		    rf_ConfigureDeclusteredDS,
    123   1.3     oster 		    rf_MapSectorDeclustered, rf_MapParityDeclustered, NULL,
    124   1.3     oster 		    rf_IdentifyStripeDeclustered,
    125   1.3     oster 		    rf_RaidFiveDagSelect,
    126   1.3     oster 		    rf_MapSIDToPSIDDeclustered,
    127   1.3     oster 		    rf_GetDefaultHeadSepLimitDeclustered,
    128   1.3     oster 		    rf_GetDefaultNumFloatingReconBuffersDeclustered,
    129   1.3     oster 		    rf_GetNumSpareRUsDeclustered, rf_InstallSpareTable,
    130   1.3     oster 		    rf_SubmitReconBufferBasic,
    131   1.3     oster 		    rf_VerifyParityBasic,
    132   1.3     oster 		    1,
    133   1.3     oster 		    DefaultStates,
    134   1.3     oster 		    RF_DISTRIBUTE_SPARE | RF_BD_DECLUSTERED)
    135   1.1     oster 	},
    136   1.7     oster #endif
    137   1.1     oster 
    138   1.1     oster #if RF_INCLUDE_DECL_PQ > 0
    139   1.1     oster 	/* declustered P+Q */
    140   1.1     oster 	{'Q', "Declustered P+Q",
    141   1.3     oster 		RF_NU(
    142   1.3     oster 		    rf_ConfigureDeclusteredPQ,
    143   1.3     oster 		    rf_MapSectorDeclusteredPQ, rf_MapParityDeclusteredPQ, rf_MapQDeclusteredPQ,
    144   1.3     oster 		    rf_IdentifyStripeDeclusteredPQ,
    145   1.3     oster 		    rf_PQDagSelect,
    146   1.3     oster 		    rf_MapSIDToPSIDDeclustered,
    147   1.3     oster 		    rf_GetDefaultHeadSepLimitDeclustered,
    148   1.3     oster 		    rf_GetDefaultNumFloatingReconBuffersPQ,
    149   1.3     oster 		    NULL, NULL,
    150   1.3     oster 		    NULL,
    151   1.3     oster 		    rf_VerifyParityBasic,
    152   1.3     oster 		    2,
    153   1.3     oster 		    DefaultStates,
    154   1.3     oster 		    0)
    155   1.1     oster 	},
    156   1.3     oster #endif				/* RF_INCLUDE_DECL_PQ > 0 */
    157   1.1     oster 
    158   1.1     oster #if RF_INCLUDE_RAID5_RS > 0
    159   1.1     oster 	/* RAID 5 with rotated sparing */
    160   1.1     oster 	{'R', "RAID Level 5 rotated sparing",
    161   1.3     oster 		RF_NU(
    162   1.3     oster 		    rf_ConfigureRAID5_RS,
    163   1.3     oster 		    rf_MapSectorRAID5_RS, rf_MapParityRAID5_RS, NULL,
    164   1.3     oster 		    rf_IdentifyStripeRAID5_RS,
    165   1.3     oster 		    rf_RaidFiveDagSelect,
    166   1.3     oster 		    rf_MapSIDToPSIDRAID5_RS,
    167   1.3     oster 		    rf_GetDefaultHeadSepLimitRAID5,
    168   1.3     oster 		    rf_GetDefaultNumFloatingReconBuffersRAID5,
    169   1.3     oster 		    rf_GetNumSpareRUsRAID5_RS, NULL,
    170   1.3     oster 		    rf_SubmitReconBufferBasic,
    171   1.3     oster 		    rf_VerifyParityBasic,
    172   1.3     oster 		    1,
    173   1.3     oster 		    DefaultStates,
    174   1.3     oster 		    RF_DISTRIBUTE_SPARE)
    175   1.1     oster 	},
    176   1.3     oster #endif				/* RF_INCLUDE_RAID5_RS > 0 */
    177   1.1     oster 
    178   1.1     oster #if RF_INCLUDE_CHAINDECLUSTER > 0
    179   1.1     oster 	/* Chained Declustering */
    180   1.1     oster 	{'C', "Chained Declustering",
    181   1.3     oster 		RF_NU(
    182   1.3     oster 		    rf_ConfigureChainDecluster,
    183   1.3     oster 		    rf_MapSectorChainDecluster, rf_MapParityChainDecluster, NULL,
    184   1.3     oster 		    rf_IdentifyStripeChainDecluster,
    185   1.3     oster 		    rf_RAIDCDagSelect,
    186   1.3     oster 		    rf_MapSIDToPSIDChainDecluster,
    187   1.3     oster 		    NULL,
    188   1.3     oster 		    NULL,
    189   1.3     oster 		    rf_GetNumSpareRUsChainDecluster, NULL,
    190   1.3     oster 		    rf_SubmitReconBufferBasic,
    191   1.3     oster 		    rf_VerifyParityBasic,
    192   1.3     oster 		    1,
    193   1.3     oster 		    DefaultStates,
    194   1.3     oster 		    0)
    195   1.1     oster 	},
    196   1.3     oster #endif				/* RF_INCLUDE_CHAINDECLUSTER > 0 */
    197   1.1     oster 
    198   1.1     oster #if RF_INCLUDE_INTERDECLUSTER > 0
    199   1.1     oster 	/* Interleaved Declustering */
    200   1.1     oster 	{'I', "Interleaved Declustering",
    201   1.3     oster 		RF_NU(
    202   1.3     oster 		    rf_ConfigureInterDecluster,
    203   1.3     oster 		    rf_MapSectorInterDecluster, rf_MapParityInterDecluster, NULL,
    204   1.3     oster 		    rf_IdentifyStripeInterDecluster,
    205   1.3     oster 		    rf_RAIDIDagSelect,
    206   1.3     oster 		    rf_MapSIDToPSIDInterDecluster,
    207   1.3     oster 		    rf_GetDefaultHeadSepLimitInterDecluster,
    208   1.3     oster 		    rf_GetDefaultNumFloatingReconBuffersInterDecluster,
    209   1.3     oster 		    rf_GetNumSpareRUsInterDecluster, NULL,
    210   1.3     oster 		    rf_SubmitReconBufferBasic,
    211   1.3     oster 		    rf_VerifyParityBasic,
    212   1.3     oster 		    1,
    213   1.3     oster 		    DefaultStates,
    214   1.3     oster 		    RF_DISTRIBUTE_SPARE)
    215   1.1     oster 	},
    216   1.3     oster #endif				/* RF_INCLUDE_INTERDECLUSTER > 0 */
    217   1.1     oster 
    218   1.1     oster #if RF_INCLUDE_RAID0 > 0
    219   1.1     oster 	/* RAID level 0 */
    220   1.1     oster 	{'0', "RAID Level 0",
    221   1.3     oster 		RF_NU(
    222   1.3     oster 		    rf_ConfigureRAID0,
    223   1.3     oster 		    rf_MapSectorRAID0, rf_MapParityRAID0, NULL,
    224   1.3     oster 		    rf_IdentifyStripeRAID0,
    225   1.3     oster 		    rf_RAID0DagSelect,
    226   1.3     oster 		    rf_MapSIDToPSIDRAID0,
    227   1.3     oster 		    NULL,
    228   1.3     oster 		    NULL,
    229   1.3     oster 		    NULL, NULL,
    230   1.3     oster 		    NULL,
    231   1.3     oster 		    rf_VerifyParityRAID0,
    232   1.3     oster 		    0,
    233   1.3     oster 		    DefaultStates,
    234   1.3     oster 		    0)
    235   1.1     oster 	},
    236   1.3     oster #endif				/* RF_INCLUDE_RAID0 > 0 */
    237   1.1     oster 
    238   1.1     oster #if RF_INCLUDE_RAID1 > 0
    239   1.1     oster 	/* RAID level 1 */
    240   1.1     oster 	{'1', "RAID Level 1",
    241   1.3     oster 		RF_NU(
    242   1.3     oster 		    rf_ConfigureRAID1,
    243   1.3     oster 		    rf_MapSectorRAID1, rf_MapParityRAID1, NULL,
    244   1.3     oster 		    rf_IdentifyStripeRAID1,
    245   1.3     oster 		    rf_RAID1DagSelect,
    246   1.3     oster 		    rf_MapSIDToPSIDRAID1,
    247  1.19     oster 		    rf_GetDefaultHeadSepLimitRAID1,
    248   1.3     oster 		    NULL,
    249   1.3     oster 		    NULL, NULL,
    250   1.3     oster 		    rf_SubmitReconBufferRAID1,
    251   1.3     oster 		    rf_VerifyParityRAID1,
    252   1.3     oster 		    1,
    253   1.3     oster 		    DefaultStates,
    254   1.3     oster 		    0)
    255   1.1     oster 	},
    256   1.3     oster #endif				/* RF_INCLUDE_RAID1 > 0 */
    257   1.1     oster 
    258   1.1     oster #if RF_INCLUDE_RAID4 > 0
    259   1.1     oster 	/* RAID level 4 */
    260   1.1     oster 	{'4', "RAID Level 4",
    261   1.3     oster 		RF_NU(
    262   1.3     oster 		    rf_ConfigureRAID4,
    263   1.3     oster 		    rf_MapSectorRAID4, rf_MapParityRAID4, NULL,
    264   1.3     oster 		    rf_IdentifyStripeRAID4,
    265   1.3     oster 		    rf_RaidFiveDagSelect,
    266   1.3     oster 		    rf_MapSIDToPSIDRAID4,
    267   1.3     oster 		    rf_GetDefaultHeadSepLimitRAID4,
    268   1.3     oster 		    rf_GetDefaultNumFloatingReconBuffersRAID4,
    269   1.3     oster 		    NULL, NULL,
    270   1.3     oster 		    rf_SubmitReconBufferBasic,
    271   1.3     oster 		    rf_VerifyParityBasic,
    272   1.3     oster 		    1,
    273   1.3     oster 		    DefaultStates,
    274   1.3     oster 		    0)
    275   1.1     oster 	},
    276   1.3     oster #endif				/* RF_INCLUDE_RAID4 > 0 */
    277   1.1     oster 
    278   1.1     oster #if RF_INCLUDE_RAID5 > 0
    279   1.1     oster 	/* RAID level 5 */
    280   1.1     oster 	{'5', "RAID Level 5",
    281   1.3     oster 		RF_NU(
    282   1.3     oster 		    rf_ConfigureRAID5,
    283   1.3     oster 		    rf_MapSectorRAID5, rf_MapParityRAID5, NULL,
    284   1.3     oster 		    rf_IdentifyStripeRAID5,
    285   1.3     oster 		    rf_RaidFiveDagSelect,
    286   1.3     oster 		    rf_MapSIDToPSIDRAID5,
    287   1.3     oster 		    rf_GetDefaultHeadSepLimitRAID5,
    288   1.3     oster 		    rf_GetDefaultNumFloatingReconBuffersRAID5,
    289   1.3     oster 		    NULL, NULL,
    290   1.3     oster 		    rf_SubmitReconBufferBasic,
    291   1.3     oster 		    rf_VerifyParityBasic,
    292   1.3     oster 		    1,
    293   1.3     oster 		    DefaultStates,
    294   1.3     oster 		    0)
    295   1.1     oster 	},
    296   1.3     oster #endif				/* RF_INCLUDE_RAID5 > 0 */
    297   1.1     oster 
    298   1.1     oster #if RF_INCLUDE_EVENODD > 0
    299   1.1     oster 	/* Evenodd */
    300   1.1     oster 	{'E', "EvenOdd",
    301   1.3     oster 		RF_NU(
    302   1.3     oster 		    rf_ConfigureEvenOdd,
    303   1.3     oster 		    rf_MapSectorRAID5, rf_MapParityEvenOdd, rf_MapEEvenOdd,
    304   1.3     oster 		    rf_IdentifyStripeEvenOdd,
    305   1.3     oster 		    rf_EODagSelect,
    306   1.3     oster 		    rf_MapSIDToPSIDRAID5,
    307   1.3     oster 		    NULL,
    308   1.3     oster 		    NULL,
    309   1.3     oster 		    NULL, NULL,
    310   1.3     oster 		    NULL,	/* no reconstruction, yet */
    311   1.3     oster 		    rf_VerifyParityEvenOdd,
    312   1.3     oster 		    2,
    313   1.3     oster 		    DefaultStates,
    314   1.3     oster 		    0)
    315   1.1     oster 	},
    316   1.3     oster #endif				/* RF_INCLUDE_EVENODD > 0 */
    317   1.1     oster 
    318   1.1     oster #if RF_INCLUDE_EVENODD > 0
    319   1.1     oster 	/* Declustered Evenodd */
    320   1.1     oster 	{'e', "Declustered EvenOdd",
    321   1.3     oster 		RF_NU(
    322   1.3     oster 		    rf_ConfigureDeclusteredPQ,
    323   1.3     oster 		    rf_MapSectorDeclusteredPQ, rf_MapParityDeclusteredPQ, rf_MapQDeclusteredPQ,
    324   1.3     oster 		    rf_IdentifyStripeDeclusteredPQ,
    325   1.3     oster 		    rf_EODagSelect,
    326   1.3     oster 		    rf_MapSIDToPSIDRAID5,
    327   1.3     oster 		    rf_GetDefaultHeadSepLimitDeclustered,
    328   1.3     oster 		    rf_GetDefaultNumFloatingReconBuffersPQ,
    329   1.3     oster 		    NULL, NULL,
    330   1.3     oster 		    NULL,	/* no reconstruction, yet */
    331   1.3     oster 		    rf_VerifyParityEvenOdd,
    332   1.3     oster 		    2,
    333   1.3     oster 		    DefaultStates,
    334   1.3     oster 		    0)
    335   1.1     oster 	},
    336   1.3     oster #endif				/* RF_INCLUDE_EVENODD > 0 */
    337   1.1     oster 
    338   1.1     oster #if RF_INCLUDE_PARITYLOGGING > 0
    339   1.1     oster 	/* parity logging */
    340   1.1     oster 	{'L', "Parity logging",
    341   1.3     oster 		RF_NU(
    342   1.3     oster 		    rf_ConfigureParityLogging,
    343   1.3     oster 		    rf_MapSectorParityLogging, rf_MapParityParityLogging, NULL,
    344   1.3     oster 		    rf_IdentifyStripeParityLogging,
    345   1.3     oster 		    rf_ParityLoggingDagSelect,
    346   1.3     oster 		    rf_MapSIDToPSIDParityLogging,
    347   1.3     oster 		    rf_GetDefaultHeadSepLimitParityLogging,
    348   1.3     oster 		    rf_GetDefaultNumFloatingReconBuffersParityLogging,
    349   1.3     oster 		    NULL, NULL,
    350   1.3     oster 		    rf_SubmitReconBufferBasic,
    351   1.3     oster 		    NULL,
    352   1.3     oster 		    1,
    353   1.3     oster 		    DefaultStates,
    354   1.3     oster 		    0)
    355   1.1     oster 	},
    356   1.3     oster #endif				/* RF_INCLUDE_PARITYLOGGING > 0 */
    357   1.1     oster 
    358   1.1     oster 	/* end-of-list marker */
    359   1.3     oster 	{'\0', NULL,
    360   1.3     oster 		RF_NU(
    361   1.3     oster 		    NULL,
    362   1.3     oster 		    NULL, NULL, NULL,
    363   1.3     oster 		    NULL,
    364   1.3     oster 		    NULL,
    365   1.3     oster 		    NULL,
    366   1.3     oster 		    NULL,
    367   1.3     oster 		    NULL,
    368   1.3     oster 		    NULL, NULL,
    369   1.3     oster 		    NULL,
    370   1.3     oster 		    NULL,
    371   1.3     oster 		    0,
    372   1.3     oster 		    NULL,
    373   1.3     oster 		    0)
    374   1.1     oster 	}
    375   1.1     oster };
    376   1.1     oster 
    377  1.14  jdolecek const RF_LayoutSW_t *
    378   1.3     oster rf_GetLayout(RF_ParityConfig_t parityConfig)
    379   1.1     oster {
    380  1.14  jdolecek 	const RF_LayoutSW_t *p;
    381   1.1     oster 
    382   1.3     oster 	/* look up the specific layout */
    383   1.3     oster 	for (p = &mapsw[0]; p->parityConfig; p++)
    384   1.3     oster 		if (p->parityConfig == parityConfig)
    385   1.3     oster 			break;
    386   1.3     oster 	if (!p->parityConfig)
    387   1.3     oster 		return (NULL);
    388   1.3     oster 	RF_ASSERT(p->parityConfig == parityConfig);
    389   1.3     oster 	return (p);
    390   1.1     oster }
    391   1.9     oster 
    392   1.9     oster /*****************************************************************************
    393   1.1     oster  *
    394   1.3     oster  * ConfigureLayout --
    395   1.1     oster  *
    396   1.9     oster  * read the configuration file and set up the RAID layout parameters.
    397   1.9     oster  * After reading common params, invokes the layout-specific
    398   1.9     oster  * configuration routine to finish the configuration.
    399   1.1     oster  *
    400   1.9     oster  ****************************************************************************/
    401  1.17     perry int
    402  1.15     oster rf_ConfigureLayout(RF_ShutdownList_t **listp, RF_Raid_t *raidPtr,
    403  1.15     oster 		   RF_Config_t *cfgPtr)
    404   1.1     oster {
    405   1.3     oster 	RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout);
    406   1.3     oster 	RF_ParityConfig_t parityConfig;
    407  1.14  jdolecek 	const RF_LayoutSW_t *p;
    408   1.3     oster 	int     retval;
    409   1.3     oster 
    410   1.3     oster 	layoutPtr->sectorsPerStripeUnit = cfgPtr->sectPerSU;
    411   1.3     oster 	layoutPtr->SUsPerPU = cfgPtr->SUsPerPU;
    412   1.3     oster 	layoutPtr->SUsPerRU = cfgPtr->SUsPerRU;
    413   1.3     oster 	parityConfig = cfgPtr->parityConfig;
    414   1.4     oster 
    415   1.4     oster 	if (layoutPtr->sectorsPerStripeUnit <= 0) {
    416   1.4     oster 		RF_ERRORMSG2("raid%d: Invalid sectorsPerStripeUnit: %d\n",
    417  1.17     perry 			     raidPtr->raidid,
    418  1.20     oster 			     (int)layoutPtr->sectorsPerStripeUnit);
    419  1.20     oster 		return (EINVAL);
    420  1.20     oster 	}
    421  1.20     oster 
    422  1.20     oster 	if (layoutPtr->SUsPerPU <= 0) {
    423  1.20     oster 		RF_ERRORMSG2("raid%d: Invalid StripeUnitsPerParityUnit: %d\n",
    424  1.20     oster 			     raidPtr->raidid,
    425  1.20     oster 			     (int)layoutPtr->SUsPerPU);
    426  1.20     oster 		return (EINVAL);
    427  1.20     oster 	}
    428  1.20     oster 
    429  1.20     oster 	if (layoutPtr->SUsPerRU <= 0) {
    430  1.20     oster 		RF_ERRORMSG2("raid%d: Invalid StripeUnitsPerReconstructUnit: %d\n",
    431  1.20     oster 			     raidPtr->raidid,
    432  1.20     oster 			     (int)layoutPtr->SUsPerRU);
    433  1.17     perry 		return (EINVAL);
    434   1.4     oster 	}
    435   1.3     oster 
    436   1.3     oster 	layoutPtr->stripeUnitsPerDisk = raidPtr->sectorsPerDisk / layoutPtr->sectorsPerStripeUnit;
    437   1.3     oster 
    438   1.3     oster 	p = rf_GetLayout(parityConfig);
    439   1.3     oster 	if (p == NULL) {
    440   1.3     oster 		RF_ERRORMSG1("Unknown parity configuration '%c'", parityConfig);
    441   1.3     oster 		return (EINVAL);
    442   1.3     oster 	}
    443   1.3     oster 	RF_ASSERT(p->parityConfig == parityConfig);
    444   1.3     oster 	layoutPtr->map = p;
    445   1.3     oster 
    446   1.3     oster 	/* initialize the specific layout */
    447   1.3     oster 
    448   1.3     oster 	retval = (p->Configure) (listp, raidPtr, cfgPtr);
    449   1.3     oster 
    450   1.3     oster 	if (retval)
    451   1.3     oster 		return (retval);
    452   1.3     oster 
    453   1.3     oster 	raidPtr->sectorsPerDisk = layoutPtr->stripeUnitsPerDisk * layoutPtr->sectorsPerStripeUnit;
    454   1.1     oster 
    455   1.3     oster 	if (rf_forceNumFloatingReconBufs >= 0) {
    456   1.3     oster 		raidPtr->numFloatingReconBufs = rf_forceNumFloatingReconBufs;
    457   1.3     oster 	} else {
    458   1.3     oster 		raidPtr->numFloatingReconBufs = rf_GetDefaultNumFloatingReconBuffers(raidPtr);
    459   1.3     oster 	}
    460   1.3     oster 
    461   1.3     oster 	if (rf_forceHeadSepLimit >= 0) {
    462   1.3     oster 		raidPtr->headSepLimit = rf_forceHeadSepLimit;
    463   1.3     oster 	} else {
    464   1.3     oster 		raidPtr->headSepLimit = rf_GetDefaultHeadSepLimit(raidPtr);
    465   1.3     oster 	}
    466   1.3     oster 	return (0);
    467   1.1     oster }
    468   1.1     oster /* typically there is a 1-1 mapping between stripes and parity stripes.
    469   1.1     oster  * however, the declustering code supports packing multiple stripes into
    470   1.1     oster  * a single parity stripe, so as to increase the size of the reconstruction
    471   1.1     oster  * unit without affecting the size of the stripe unit.  This routine finds
    472   1.1     oster  * the parity stripe identifier associated with a stripe ID.  There is also
    473   1.1     oster  * a RaidAddressToParityStripeID macro in layout.h
    474   1.1     oster  */
    475  1.17     perry RF_StripeNum_t
    476  1.15     oster rf_MapStripeIDToParityStripeID(RF_RaidLayout_t *layoutPtr,
    477  1.15     oster 			       RF_StripeNum_t stripeID,
    478  1.15     oster 			       RF_ReconUnitNum_t *which_ru)
    479   1.1     oster {
    480   1.3     oster 	RF_StripeNum_t parityStripeID;
    481   1.1     oster 
    482   1.3     oster 	/* quick exit in the common case of SUsPerPU==1 */
    483   1.3     oster 	if ((layoutPtr->SUsPerPU == 1) || !layoutPtr->map->MapSIDToPSID) {
    484   1.3     oster 		*which_ru = 0;
    485   1.3     oster 		return (stripeID);
    486   1.3     oster 	} else {
    487   1.3     oster 		(layoutPtr->map->MapSIDToPSID) (layoutPtr, stripeID, &parityStripeID, which_ru);
    488   1.3     oster 	}
    489   1.3     oster 	return (parityStripeID);
    490   1.1     oster }
    491