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