Home | History | Annotate | Line # | Download | only in raidframe
rf_layout.c revision 1.1
      1  1.1  oster /*	$NetBSD: rf_layout.c,v 1.1 1998/11/13 04:20:30 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 /*
     33  1.1  oster  * :
     34  1.1  oster  * Log: rf_layout.c,v
     35  1.1  oster  * Revision 1.71  1996/08/20 22:41:30  jimz
     36  1.1  oster  * add declustered evenodd
     37  1.1  oster  *
     38  1.1  oster  * Revision 1.70  1996/07/31  16:56:18  jimz
     39  1.1  oster  * dataBytesPerStripe, sectorsPerDisk init arch-indep.
     40  1.1  oster  *
     41  1.1  oster  * Revision 1.69  1996/07/31  15:34:46  jimz
     42  1.1  oster  * add EvenOdd
     43  1.1  oster  *
     44  1.1  oster  * Revision 1.68  1996/07/29  14:05:12  jimz
     45  1.1  oster  * fix numPUs/numRUs confusion (everything is now numRUs)
     46  1.1  oster  * clean up some commenting, return values
     47  1.1  oster  *
     48  1.1  oster  * Revision 1.67  1996/07/27  23:36:08  jimz
     49  1.1  oster  * Solaris port of simulator
     50  1.1  oster  *
     51  1.1  oster  * Revision 1.66  1996/07/27  18:40:24  jimz
     52  1.1  oster  * cleanup sweep
     53  1.1  oster  *
     54  1.1  oster  * Revision 1.65  1996/07/18  22:57:14  jimz
     55  1.1  oster  * port simulator to AIX
     56  1.1  oster  *
     57  1.1  oster  * Revision 1.64  1996/07/15  17:22:18  jimz
     58  1.1  oster  * nit-pick code cleanup
     59  1.1  oster  * resolve stdlib problems on DEC OSF
     60  1.1  oster  *
     61  1.1  oster  * Revision 1.63  1996/07/13  00:00:59  jimz
     62  1.1  oster  * sanitized generalized reconstruction architecture
     63  1.1  oster  * cleaned up head sep, rbuf problems
     64  1.1  oster  *
     65  1.1  oster  * Revision 1.62  1996/07/11  19:08:00  jimz
     66  1.1  oster  * generalize reconstruction mechanism
     67  1.1  oster  * allow raid1 reconstructs via copyback (done with array
     68  1.1  oster  * quiesced, not online, therefore not disk-directed)
     69  1.1  oster  *
     70  1.1  oster  * Revision 1.61  1996/06/19  22:23:01  jimz
     71  1.1  oster  * parity verification is now a layout-configurable thing
     72  1.1  oster  * not all layouts currently support it (correctly, anyway)
     73  1.1  oster  *
     74  1.1  oster  * Revision 1.60  1996/06/19  17:53:48  jimz
     75  1.1  oster  * move GetNumSparePUs, InstallSpareTable ops into layout switch
     76  1.1  oster  *
     77  1.1  oster  * Revision 1.59  1996/06/19  14:57:58  jimz
     78  1.1  oster  * move layout-specific config parsing hooks into RF_LayoutSW_t
     79  1.1  oster  * table in rf_layout.c
     80  1.1  oster  *
     81  1.1  oster  * Revision 1.58  1996/06/10  11:55:47  jimz
     82  1.1  oster  * Straightened out some per-array/not-per-array distinctions, fixed
     83  1.1  oster  * a couple bugs related to confusion. Added shutdown lists. Removed
     84  1.1  oster  * layout shutdown function (now subsumed by shutdown lists).
     85  1.1  oster  *
     86  1.1  oster  * Revision 1.57  1996/06/07  22:26:27  jimz
     87  1.1  oster  * type-ify which_ru (RF_ReconUnitNum_t)
     88  1.1  oster  *
     89  1.1  oster  * Revision 1.56  1996/06/07  21:33:04  jimz
     90  1.1  oster  * begin using consistent types for sector numbers,
     91  1.1  oster  * stripe numbers, row+col numbers, recon unit numbers
     92  1.1  oster  *
     93  1.1  oster  * Revision 1.55  1996/06/06  18:41:35  jimz
     94  1.1  oster  * change interleaved declustering dag selection to an
     95  1.1  oster  * interleaved-declustering-specific routine (so we can
     96  1.1  oster  * use the partitioned mirror node)
     97  1.1  oster  *
     98  1.1  oster  * Revision 1.54  1996/06/05  18:06:02  jimz
     99  1.1  oster  * Major code cleanup. The Great Renaming is now done.
    100  1.1  oster  * Better modularity. Better typing. Fixed a bunch of
    101  1.1  oster  * synchronization bugs. Made a lot of global stuff
    102  1.1  oster  * per-desc or per-array. Removed dead code.
    103  1.1  oster  *
    104  1.1  oster  * Revision 1.53  1996/06/03  23:28:26  jimz
    105  1.1  oster  * more bugfixes
    106  1.1  oster  * check in tree to sync for IPDS runs with current bugfixes
    107  1.1  oster  * there still may be a problem with threads in the script test
    108  1.1  oster  * getting I/Os stuck- not trivially reproducible (runs ~50 times
    109  1.1  oster  * in a row without getting stuck)
    110  1.1  oster  *
    111  1.1  oster  * Revision 1.52  1996/06/02  17:31:48  jimz
    112  1.1  oster  * Moved a lot of global stuff into array structure, where it belongs.
    113  1.1  oster  * Fixed up paritylogging, pss modules in this manner. Some general
    114  1.1  oster  * code cleanup. Removed lots of dead code, some dead files.
    115  1.1  oster  *
    116  1.1  oster  * Revision 1.51  1996/05/31  22:26:54  jimz
    117  1.1  oster  * fix a lot of mapping problems, memory allocation problems
    118  1.1  oster  * found some weird lock issues, fixed 'em
    119  1.1  oster  * more code cleanup
    120  1.1  oster  *
    121  1.1  oster  * Revision 1.50  1996/05/30  23:22:16  jimz
    122  1.1  oster  * bugfixes of serialization, timing problems
    123  1.1  oster  * more cleanup
    124  1.1  oster  *
    125  1.1  oster  * Revision 1.49  1996/05/30  11:29:41  jimz
    126  1.1  oster  * Numerous bug fixes. Stripe lock release code disagreed with the taking code
    127  1.1  oster  * about when stripes should be locked (I made it consistent: no parity, no lock)
    128  1.1  oster  * There was a lot of extra serialization of I/Os which I've removed- a lot of
    129  1.1  oster  * it was to calculate values for the cache code, which is no longer with us.
    130  1.1  oster  * More types, function, macro cleanup. Added code to properly quiesce the array
    131  1.1  oster  * on shutdown. Made a lot of stuff array-specific which was (bogusly) general
    132  1.1  oster  * before. Fixed memory allocation, freeing bugs.
    133  1.1  oster  *
    134  1.1  oster  * Revision 1.48  1996/05/27  18:56:37  jimz
    135  1.1  oster  * more code cleanup
    136  1.1  oster  * better typing
    137  1.1  oster  * compiles in all 3 environments
    138  1.1  oster  *
    139  1.1  oster  * Revision 1.47  1996/05/24  22:17:04  jimz
    140  1.1  oster  * continue code + namespace cleanup
    141  1.1  oster  * typed a bunch of flags
    142  1.1  oster  *
    143  1.1  oster  * Revision 1.46  1996/05/24  01:59:45  jimz
    144  1.1  oster  * another checkpoint in code cleanup for release
    145  1.1  oster  * time to sync kernel tree
    146  1.1  oster  *
    147  1.1  oster  * Revision 1.45  1996/05/23  21:46:35  jimz
    148  1.1  oster  * checkpoint in code cleanup (release prep)
    149  1.1  oster  * lots of types, function names have been fixed
    150  1.1  oster  *
    151  1.1  oster  * Revision 1.44  1996/05/18  19:51:34  jimz
    152  1.1  oster  * major code cleanup- fix syntax, make some types consistent,
    153  1.1  oster  * add prototypes, clean out dead code, et cetera
    154  1.1  oster  *
    155  1.1  oster  * Revision 1.43  1996/02/22  16:46:35  amiri
    156  1.1  oster  * modified chained declustering to use a seperate DAG selection routine
    157  1.1  oster  *
    158  1.1  oster  * Revision 1.42  1995/12/01  19:16:11  root
    159  1.1  oster  * added copyright info
    160  1.1  oster  *
    161  1.1  oster  * Revision 1.41  1995/11/28  21:31:02  amiri
    162  1.1  oster  * added Interleaved Declustering to switch table
    163  1.1  oster  *
    164  1.1  oster  * Revision 1.40  1995/11/20  14:35:17  arw
    165  1.1  oster  * moved rf_StartThroughputStats in DefaultWrite and DefaultRead
    166  1.1  oster  *
    167  1.1  oster  * Revision 1.39  1995/11/19  16:28:46  wvcii
    168  1.1  oster  * replaced LaunchDAGState with CreateDAGState, ExecuteDAGState
    169  1.1  oster  *
    170  1.1  oster  * Revision 1.38  1995/11/17  19:00:41  wvcii
    171  1.1  oster  * added MapQ entries to switch table
    172  1.1  oster  *
    173  1.1  oster  * Revision 1.37  1995/11/17  16:58:13  amiri
    174  1.1  oster  * Added the Chained Declustering architecture ('C'),
    175  1.1  oster  * essentially a variant of mirroring.
    176  1.1  oster  *
    177  1.1  oster  * Revision 1.36  1995/11/16  16:16:10  amiri
    178  1.1  oster  * Added RAID5 with rotated sparing ('R' configuration)
    179  1.1  oster  *
    180  1.1  oster  * Revision 1.35  1995/11/07  15:41:17  wvcii
    181  1.1  oster  * modified state lists: DefaultStates, VSReadStates
    182  1.1  oster  * necessary to support new states (LaunchDAGState, ProcessDAGState)
    183  1.1  oster  *
    184  1.1  oster  * Revision 1.34  1995/10/18  01:23:20  amiri
    185  1.1  oster  * added ifndef SIMULATE wrapper around rf_StartThroughputStats()
    186  1.1  oster  *
    187  1.1  oster  * Revision 1.33  1995/10/13  15:05:46  arw
    188  1.1  oster  * added rf_StartThroughputStats to DefaultRead and DefaultWrite
    189  1.1  oster  *
    190  1.1  oster  * Revision 1.32  1995/10/12  16:04:23  jimz
    191  1.1  oster  * added config names to mapsw entires
    192  1.1  oster  *
    193  1.1  oster  * Revision 1.31  1995/10/04  03:57:48  wvcii
    194  1.1  oster  * added raid level 1 to mapsw
    195  1.1  oster  *
    196  1.1  oster  * Revision 1.30  1995/09/07  01:26:55  jimz
    197  1.1  oster  * Achive basic compilation in kernel. Kernel functionality
    198  1.1  oster  * is not guaranteed at all, but it'll compile. Mostly. I hope.
    199  1.1  oster  *
    200  1.1  oster  * Revision 1.29  1995/07/28  21:43:42  robby
    201  1.1  oster  * checkin after leaving for Rice. Bye
    202  1.1  oster  *
    203  1.1  oster  * Revision 1.28  1995/07/26  03:26:14  robby
    204  1.1  oster  * *** empty log message ***
    205  1.1  oster  *
    206  1.1  oster  * Revision 1.27  1995/07/21  19:47:52  rachad
    207  1.1  oster  * Added raid 0 /5 with caching architectures
    208  1.1  oster  *
    209  1.1  oster  * Revision 1.26  1995/07/21  19:29:27  robby
    210  1.1  oster  * added virtual striping states
    211  1.1  oster  *
    212  1.1  oster  * Revision 1.25  1995/07/10  21:41:47  robby
    213  1.1  oster  * switched to have my own virtual stripng write function from the cache
    214  1.1  oster  *
    215  1.1  oster  * Revision 1.24  1995/07/10  20:51:59  robby
    216  1.1  oster  * added virtual striping states
    217  1.1  oster  *
    218  1.1  oster  * Revision 1.23  1995/07/10  16:57:42  robby
    219  1.1  oster  * updated alloclistelem struct to the correct struct name
    220  1.1  oster  *
    221  1.1  oster  * Revision 1.22  1995/07/08  20:06:11  rachad
    222  1.1  oster  * *** empty log message ***
    223  1.1  oster  *
    224  1.1  oster  * Revision 1.21  1995/07/08  19:43:16  cfb
    225  1.1  oster  * *** empty log message ***
    226  1.1  oster  *
    227  1.1  oster  * Revision 1.20  1995/07/08  18:05:39  rachad
    228  1.1  oster  * Linked up Claudsons code with the real cache
    229  1.1  oster  *
    230  1.1  oster  * Revision 1.19  1995/07/06  14:29:36  robby
    231  1.1  oster  * added defaults states list to the layout switch
    232  1.1  oster  *
    233  1.1  oster  * Revision 1.18  1995/06/23  13:40:34  robby
    234  1.1  oster  * updeated to prototypes in rf_layout.h
    235  1.1  oster  *
    236  1.1  oster  */
    237  1.1  oster 
    238  1.1  oster #include "rf_types.h"
    239  1.1  oster #include "rf_archs.h"
    240  1.1  oster #include "rf_raid.h"
    241  1.1  oster #include "rf_configure.h"
    242  1.1  oster #include "rf_dag.h"
    243  1.1  oster #include "rf_desc.h"
    244  1.1  oster #include "rf_decluster.h"
    245  1.1  oster #include "rf_pq.h"
    246  1.1  oster #include "rf_declusterPQ.h"
    247  1.1  oster #include "rf_raid0.h"
    248  1.1  oster #include "rf_raid1.h"
    249  1.1  oster #include "rf_raid4.h"
    250  1.1  oster #include "rf_raid5.h"
    251  1.1  oster #include "rf_states.h"
    252  1.1  oster #if RF_INCLUDE_RAID5_RS > 0
    253  1.1  oster #include "rf_raid5_rotatedspare.h"
    254  1.1  oster #endif /* RF_INCLUDE_RAID5_RS > 0 */
    255  1.1  oster #if RF_INCLUDE_CHAINDECLUSTER > 0
    256  1.1  oster #include "rf_chaindecluster.h"
    257  1.1  oster #endif /* RF_INCLUDE_CHAINDECLUSTER > 0 */
    258  1.1  oster #if RF_INCLUDE_INTERDECLUSTER > 0
    259  1.1  oster #include "rf_interdecluster.h"
    260  1.1  oster #endif /* RF_INCLUDE_INTERDECLUSTER > 0 */
    261  1.1  oster #if RF_INCLUDE_PARITYLOGGING > 0
    262  1.1  oster #include "rf_paritylogging.h"
    263  1.1  oster #endif /* RF_INCLUDE_PARITYLOGGING > 0 */
    264  1.1  oster #if RF_INCLUDE_EVENODD > 0
    265  1.1  oster #include "rf_evenodd.h"
    266  1.1  oster #endif /* RF_INCLUDE_EVENODD > 0 */
    267  1.1  oster #include "rf_general.h"
    268  1.1  oster #include "rf_driver.h"
    269  1.1  oster #include "rf_parityscan.h"
    270  1.1  oster #include "rf_reconbuffer.h"
    271  1.1  oster #include "rf_reconutil.h"
    272  1.1  oster 
    273  1.1  oster /***********************************************************************
    274  1.1  oster  *
    275  1.1  oster  * the layout switch defines all the layouts that are supported.
    276  1.1  oster  *    fields are: layout ID, init routine, shutdown routine, map
    277  1.1  oster  *    sector, map parity, identify stripe, dag selection, map stripeid
    278  1.1  oster  *    to parity stripe id (optional), num faults tolerated, special
    279  1.1  oster  *    flags.
    280  1.1  oster  *
    281  1.1  oster  ***********************************************************************/
    282  1.1  oster 
    283  1.1  oster static RF_AccessState_t DefaultStates[] = {rf_QuiesceState,
    284  1.1  oster 	rf_IncrAccessesCountState, rf_MapState, rf_LockState, rf_CreateDAGState,
    285  1.1  oster 	rf_ExecuteDAGState, rf_ProcessDAGState, rf_DecrAccessesCountState,
    286  1.1  oster 	rf_CleanupState, rf_LastState};
    287  1.1  oster 
    288  1.1  oster #if defined(__NetBSD__) && !defined(_KERNEL)
    289  1.1  oster /* XXX Gross hack to shutup gcc -- it complains that DefaultStates is not
    290  1.1  oster used when compiling this in userland..  I hate to burst it's bubble, but
    291  1.1  oster DefaultStates is used all over the place here in the initialization of
    292  1.1  oster lots of data structures.  GO */
    293  1.1  oster RF_AccessState_t *NothingAtAll = DefaultStates;
    294  1.1  oster #endif
    295  1.1  oster 
    296  1.1  oster #if defined(__NetBSD__) && defined(_KERNEL)
    297  1.1  oster /* XXX Remove static so GCC doesn't complain about these being unused! */
    298  1.1  oster int distSpareYes = 1;
    299  1.1  oster int distSpareNo  = 0;
    300  1.1  oster #else
    301  1.1  oster static int distSpareYes = 1;
    302  1.1  oster static int distSpareNo  = 0;
    303  1.1  oster #endif
    304  1.1  oster #ifdef KERNEL
    305  1.1  oster #define RF_NK2(a,b)
    306  1.1  oster #else /* KERNEL */
    307  1.1  oster #define RF_NK2(a,b) a,b,
    308  1.1  oster #endif /* KERNEL */
    309  1.1  oster 
    310  1.1  oster #if RF_UTILITY > 0
    311  1.1  oster #define RF_NU(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)
    312  1.1  oster #else /* RF_UTILITY > 0 */
    313  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
    314  1.1  oster #endif /* RF_UTILITY > 0 */
    315  1.1  oster 
    316  1.1  oster static RF_LayoutSW_t mapsw[] = {
    317  1.1  oster 	/* parity declustering */
    318  1.1  oster 	{'T', "Parity declustering",
    319  1.1  oster 	RF_NK2(rf_MakeLayoutSpecificDeclustered, &distSpareNo)
    320  1.1  oster 	RF_NU(
    321  1.1  oster 	rf_ConfigureDeclustered,
    322  1.1  oster 	rf_MapSectorDeclustered, rf_MapParityDeclustered, NULL,
    323  1.1  oster 	rf_IdentifyStripeDeclustered,
    324  1.1  oster 	rf_RaidFiveDagSelect,
    325  1.1  oster 	rf_MapSIDToPSIDDeclustered,
    326  1.1  oster 	rf_GetDefaultHeadSepLimitDeclustered,
    327  1.1  oster 	rf_GetDefaultNumFloatingReconBuffersDeclustered,
    328  1.1  oster 	NULL, NULL,
    329  1.1  oster 	rf_SubmitReconBufferBasic,
    330  1.1  oster 	rf_VerifyParityBasic,
    331  1.1  oster 	1,
    332  1.1  oster 	DefaultStates,
    333  1.1  oster 	0)
    334  1.1  oster 	},
    335  1.1  oster 
    336  1.1  oster 	/* parity declustering with distributed sparing */
    337  1.1  oster 	{'D', "Distributed sparing parity declustering",
    338  1.1  oster 	RF_NK2(rf_MakeLayoutSpecificDeclustered, &distSpareYes)
    339  1.1  oster 	RF_NU(
    340  1.1  oster 	rf_ConfigureDeclusteredDS,
    341  1.1  oster 	rf_MapSectorDeclustered, rf_MapParityDeclustered, NULL,
    342  1.1  oster 	rf_IdentifyStripeDeclustered,
    343  1.1  oster 	rf_RaidFiveDagSelect,
    344  1.1  oster 	rf_MapSIDToPSIDDeclustered,
    345  1.1  oster 	rf_GetDefaultHeadSepLimitDeclustered,
    346  1.1  oster 	rf_GetDefaultNumFloatingReconBuffersDeclustered,
    347  1.1  oster 	rf_GetNumSpareRUsDeclustered, rf_InstallSpareTable,
    348  1.1  oster 	rf_SubmitReconBufferBasic,
    349  1.1  oster 	rf_VerifyParityBasic,
    350  1.1  oster 	1,
    351  1.1  oster 	DefaultStates,
    352  1.1  oster 	RF_DISTRIBUTE_SPARE|RF_BD_DECLUSTERED)
    353  1.1  oster 	},
    354  1.1  oster 
    355  1.1  oster #if RF_INCLUDE_DECL_PQ > 0
    356  1.1  oster 	/* declustered P+Q */
    357  1.1  oster 	{'Q', "Declustered P+Q",
    358  1.1  oster 	RF_NK2(rf_MakeLayoutSpecificDeclustered, &distSpareNo)
    359  1.1  oster 	RF_NU(
    360  1.1  oster 	rf_ConfigureDeclusteredPQ,
    361  1.1  oster 	rf_MapSectorDeclusteredPQ, rf_MapParityDeclusteredPQ, rf_MapQDeclusteredPQ,
    362  1.1  oster 	rf_IdentifyStripeDeclusteredPQ,
    363  1.1  oster 	rf_PQDagSelect,
    364  1.1  oster 	rf_MapSIDToPSIDDeclustered,
    365  1.1  oster 	rf_GetDefaultHeadSepLimitDeclustered,
    366  1.1  oster 	rf_GetDefaultNumFloatingReconBuffersPQ,
    367  1.1  oster 	NULL, NULL,
    368  1.1  oster 	NULL,
    369  1.1  oster 	rf_VerifyParityBasic,
    370  1.1  oster 	2,
    371  1.1  oster 	DefaultStates,
    372  1.1  oster 	0)
    373  1.1  oster 	},
    374  1.1  oster #endif /* RF_INCLUDE_DECL_PQ > 0 */
    375  1.1  oster 
    376  1.1  oster #if RF_INCLUDE_RAID5_RS > 0
    377  1.1  oster 	/* RAID 5 with rotated sparing */
    378  1.1  oster 	{'R', "RAID Level 5 rotated sparing",
    379  1.1  oster 	RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
    380  1.1  oster 	RF_NU(
    381  1.1  oster 	rf_ConfigureRAID5_RS,
    382  1.1  oster 	rf_MapSectorRAID5_RS, rf_MapParityRAID5_RS, NULL,
    383  1.1  oster 	rf_IdentifyStripeRAID5_RS,
    384  1.1  oster 	rf_RaidFiveDagSelect,
    385  1.1  oster 	rf_MapSIDToPSIDRAID5_RS,
    386  1.1  oster 	rf_GetDefaultHeadSepLimitRAID5,
    387  1.1  oster 	rf_GetDefaultNumFloatingReconBuffersRAID5,
    388  1.1  oster 	rf_GetNumSpareRUsRAID5_RS, NULL,
    389  1.1  oster 	rf_SubmitReconBufferBasic,
    390  1.1  oster 	rf_VerifyParityBasic,
    391  1.1  oster 	1,
    392  1.1  oster 	DefaultStates,
    393  1.1  oster 	RF_DISTRIBUTE_SPARE)
    394  1.1  oster 	},
    395  1.1  oster #endif /* RF_INCLUDE_RAID5_RS > 0 */
    396  1.1  oster 
    397  1.1  oster #if RF_INCLUDE_CHAINDECLUSTER > 0
    398  1.1  oster 	/* Chained Declustering */
    399  1.1  oster 	{'C', "Chained Declustering",
    400  1.1  oster 	RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
    401  1.1  oster 	RF_NU(
    402  1.1  oster 	rf_ConfigureChainDecluster,
    403  1.1  oster 	rf_MapSectorChainDecluster, rf_MapParityChainDecluster, NULL,
    404  1.1  oster 	rf_IdentifyStripeChainDecluster,
    405  1.1  oster 	rf_RAIDCDagSelect,
    406  1.1  oster 	rf_MapSIDToPSIDChainDecluster,
    407  1.1  oster 	NULL,
    408  1.1  oster 	NULL,
    409  1.1  oster 	rf_GetNumSpareRUsChainDecluster, NULL,
    410  1.1  oster 	rf_SubmitReconBufferBasic,
    411  1.1  oster 	rf_VerifyParityBasic,
    412  1.1  oster 	1,
    413  1.1  oster 	DefaultStates,
    414  1.1  oster 	0)
    415  1.1  oster 	},
    416  1.1  oster #endif /* RF_INCLUDE_CHAINDECLUSTER > 0 */
    417  1.1  oster 
    418  1.1  oster #if RF_INCLUDE_INTERDECLUSTER > 0
    419  1.1  oster 	/* Interleaved Declustering */
    420  1.1  oster 	{'I', "Interleaved Declustering",
    421  1.1  oster 	RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
    422  1.1  oster 	RF_NU(
    423  1.1  oster 	rf_ConfigureInterDecluster,
    424  1.1  oster 	rf_MapSectorInterDecluster, rf_MapParityInterDecluster, NULL,
    425  1.1  oster 	rf_IdentifyStripeInterDecluster,
    426  1.1  oster 	rf_RAIDIDagSelect,
    427  1.1  oster 	rf_MapSIDToPSIDInterDecluster,
    428  1.1  oster 	rf_GetDefaultHeadSepLimitInterDecluster,
    429  1.1  oster 	rf_GetDefaultNumFloatingReconBuffersInterDecluster,
    430  1.1  oster 	rf_GetNumSpareRUsInterDecluster, NULL,
    431  1.1  oster 	rf_SubmitReconBufferBasic,
    432  1.1  oster 	rf_VerifyParityBasic,
    433  1.1  oster 	1,
    434  1.1  oster 	DefaultStates,
    435  1.1  oster 	RF_DISTRIBUTE_SPARE)
    436  1.1  oster 	},
    437  1.1  oster #endif /* RF_INCLUDE_INTERDECLUSTER > 0 */
    438  1.1  oster 
    439  1.1  oster #if RF_INCLUDE_RAID0 > 0
    440  1.1  oster 	/* RAID level 0 */
    441  1.1  oster 	{'0', "RAID Level 0",
    442  1.1  oster 	RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
    443  1.1  oster 	RF_NU(
    444  1.1  oster 	rf_ConfigureRAID0,
    445  1.1  oster 	rf_MapSectorRAID0, rf_MapParityRAID0, NULL,
    446  1.1  oster 	rf_IdentifyStripeRAID0,
    447  1.1  oster 	rf_RAID0DagSelect,
    448  1.1  oster 	rf_MapSIDToPSIDRAID0,
    449  1.1  oster 	NULL,
    450  1.1  oster 	NULL,
    451  1.1  oster 	NULL, NULL,
    452  1.1  oster 	NULL,
    453  1.1  oster 	rf_VerifyParityRAID0,
    454  1.1  oster 	0,
    455  1.1  oster 	DefaultStates,
    456  1.1  oster 	0)
    457  1.1  oster 	},
    458  1.1  oster #endif /* RF_INCLUDE_RAID0 > 0 */
    459  1.1  oster 
    460  1.1  oster #if RF_INCLUDE_RAID1 > 0
    461  1.1  oster 	/* RAID level 1 */
    462  1.1  oster 	{'1', "RAID Level 1",
    463  1.1  oster 	RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
    464  1.1  oster 	RF_NU(
    465  1.1  oster 	rf_ConfigureRAID1,
    466  1.1  oster 	rf_MapSectorRAID1, rf_MapParityRAID1, NULL,
    467  1.1  oster 	rf_IdentifyStripeRAID1,
    468  1.1  oster 	rf_RAID1DagSelect,
    469  1.1  oster 	rf_MapSIDToPSIDRAID1,
    470  1.1  oster 	NULL,
    471  1.1  oster 	NULL,
    472  1.1  oster 	NULL, NULL,
    473  1.1  oster 	rf_SubmitReconBufferRAID1,
    474  1.1  oster 	rf_VerifyParityRAID1,
    475  1.1  oster 	1,
    476  1.1  oster 	DefaultStates,
    477  1.1  oster 	0)
    478  1.1  oster 	},
    479  1.1  oster #endif /* RF_INCLUDE_RAID1 > 0 */
    480  1.1  oster 
    481  1.1  oster #if RF_INCLUDE_RAID4 > 0
    482  1.1  oster 	/* RAID level 4 */
    483  1.1  oster 	{'4', "RAID Level 4",
    484  1.1  oster 	RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
    485  1.1  oster 	RF_NU(
    486  1.1  oster 	rf_ConfigureRAID4,
    487  1.1  oster 	rf_MapSectorRAID4, rf_MapParityRAID4, NULL,
    488  1.1  oster 	rf_IdentifyStripeRAID4,
    489  1.1  oster 	rf_RaidFiveDagSelect,
    490  1.1  oster 	rf_MapSIDToPSIDRAID4,
    491  1.1  oster 	rf_GetDefaultHeadSepLimitRAID4,
    492  1.1  oster 	rf_GetDefaultNumFloatingReconBuffersRAID4,
    493  1.1  oster 	NULL, NULL,
    494  1.1  oster 	rf_SubmitReconBufferBasic,
    495  1.1  oster 	rf_VerifyParityBasic,
    496  1.1  oster 	1,
    497  1.1  oster 	DefaultStates,
    498  1.1  oster 	0)
    499  1.1  oster 	},
    500  1.1  oster #endif /* RF_INCLUDE_RAID4 > 0 */
    501  1.1  oster 
    502  1.1  oster #if RF_INCLUDE_RAID5 > 0
    503  1.1  oster 	/* RAID level 5 */
    504  1.1  oster 	{'5', "RAID Level 5",
    505  1.1  oster 	RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
    506  1.1  oster 	RF_NU(
    507  1.1  oster 	rf_ConfigureRAID5,
    508  1.1  oster 	rf_MapSectorRAID5, rf_MapParityRAID5, NULL,
    509  1.1  oster 	rf_IdentifyStripeRAID5,
    510  1.1  oster 	rf_RaidFiveDagSelect,
    511  1.1  oster 	rf_MapSIDToPSIDRAID5,
    512  1.1  oster 	rf_GetDefaultHeadSepLimitRAID5,
    513  1.1  oster 	rf_GetDefaultNumFloatingReconBuffersRAID5,
    514  1.1  oster 	NULL, NULL,
    515  1.1  oster 	rf_SubmitReconBufferBasic,
    516  1.1  oster 	rf_VerifyParityBasic,
    517  1.1  oster 	1,
    518  1.1  oster 	DefaultStates,
    519  1.1  oster 	0)
    520  1.1  oster 	},
    521  1.1  oster #endif /* RF_INCLUDE_RAID5 > 0 */
    522  1.1  oster 
    523  1.1  oster #if RF_INCLUDE_EVENODD > 0
    524  1.1  oster 	/* Evenodd */
    525  1.1  oster 	{'E', "EvenOdd",
    526  1.1  oster 	RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
    527  1.1  oster 	RF_NU(
    528  1.1  oster 	rf_ConfigureEvenOdd,
    529  1.1  oster 	rf_MapSectorRAID5, rf_MapParityEvenOdd, rf_MapEEvenOdd,
    530  1.1  oster 	rf_IdentifyStripeEvenOdd,
    531  1.1  oster 	rf_EODagSelect,
    532  1.1  oster 	rf_MapSIDToPSIDRAID5,
    533  1.1  oster 	NULL,
    534  1.1  oster 	NULL,
    535  1.1  oster 	NULL, NULL,
    536  1.1  oster 	NULL, /* no reconstruction, yet */
    537  1.1  oster 	rf_VerifyParityEvenOdd,
    538  1.1  oster 	2,
    539  1.1  oster 	DefaultStates,
    540  1.1  oster 	0)
    541  1.1  oster 	},
    542  1.1  oster #endif /* RF_INCLUDE_EVENODD > 0 */
    543  1.1  oster 
    544  1.1  oster #if RF_INCLUDE_EVENODD > 0
    545  1.1  oster 	/* Declustered Evenodd */
    546  1.1  oster 	{'e', "Declustered EvenOdd",
    547  1.1  oster 	RF_NK2(rf_MakeLayoutSpecificDeclustered, &distSpareNo)
    548  1.1  oster 	RF_NU(
    549  1.1  oster 	rf_ConfigureDeclusteredPQ,
    550  1.1  oster 	rf_MapSectorDeclusteredPQ, rf_MapParityDeclusteredPQ, rf_MapQDeclusteredPQ,
    551  1.1  oster 	rf_IdentifyStripeDeclusteredPQ,
    552  1.1  oster 	rf_EODagSelect,
    553  1.1  oster 	rf_MapSIDToPSIDRAID5,
    554  1.1  oster 	rf_GetDefaultHeadSepLimitDeclustered,
    555  1.1  oster 	rf_GetDefaultNumFloatingReconBuffersPQ,
    556  1.1  oster 	NULL, NULL,
    557  1.1  oster 	NULL, /* no reconstruction, yet */
    558  1.1  oster 	rf_VerifyParityEvenOdd,
    559  1.1  oster 	2,
    560  1.1  oster 	DefaultStates,
    561  1.1  oster 	0)
    562  1.1  oster 	},
    563  1.1  oster #endif /* RF_INCLUDE_EVENODD > 0 */
    564  1.1  oster 
    565  1.1  oster #if RF_INCLUDE_PARITYLOGGING > 0
    566  1.1  oster 	/* parity logging */
    567  1.1  oster 	{'L', "Parity logging",
    568  1.1  oster 	RF_NK2(rf_MakeLayoutSpecificNULL, NULL)
    569  1.1  oster 	RF_NU(
    570  1.1  oster 	rf_ConfigureParityLogging,
    571  1.1  oster 	rf_MapSectorParityLogging, rf_MapParityParityLogging, NULL,
    572  1.1  oster 	rf_IdentifyStripeParityLogging,
    573  1.1  oster 	rf_ParityLoggingDagSelect,
    574  1.1  oster 	rf_MapSIDToPSIDParityLogging,
    575  1.1  oster 	rf_GetDefaultHeadSepLimitParityLogging,
    576  1.1  oster 	rf_GetDefaultNumFloatingReconBuffersParityLogging,
    577  1.1  oster 	NULL, NULL,
    578  1.1  oster 	rf_SubmitReconBufferBasic,
    579  1.1  oster 	NULL,
    580  1.1  oster 	1,
    581  1.1  oster 	DefaultStates,
    582  1.1  oster 	0)
    583  1.1  oster 	},
    584  1.1  oster #endif /* RF_INCLUDE_PARITYLOGGING > 0 */
    585  1.1  oster 
    586  1.1  oster 	/* end-of-list marker */
    587  1.1  oster 	{ '\0', NULL,
    588  1.1  oster 	RF_NK2(NULL, NULL)
    589  1.1  oster 	RF_NU(
    590  1.1  oster 	NULL,
    591  1.1  oster 	NULL, NULL, NULL,
    592  1.1  oster 	NULL,
    593  1.1  oster 	NULL,
    594  1.1  oster 	NULL,
    595  1.1  oster 	NULL,
    596  1.1  oster 	NULL,
    597  1.1  oster 	NULL, NULL,
    598  1.1  oster 	NULL,
    599  1.1  oster 	NULL,
    600  1.1  oster 	0,
    601  1.1  oster 	NULL,
    602  1.1  oster 	0)
    603  1.1  oster 	}
    604  1.1  oster };
    605  1.1  oster 
    606  1.1  oster RF_LayoutSW_t *rf_GetLayout(RF_ParityConfig_t parityConfig)
    607  1.1  oster {
    608  1.1  oster   RF_LayoutSW_t *p;
    609  1.1  oster 
    610  1.1  oster   /* look up the specific layout */
    611  1.1  oster   for (p=&mapsw[0]; p->parityConfig; p++)
    612  1.1  oster     if (p->parityConfig == parityConfig)
    613  1.1  oster       break;
    614  1.1  oster   if (!p->parityConfig)
    615  1.1  oster     return(NULL);
    616  1.1  oster   RF_ASSERT(p->parityConfig == parityConfig);
    617  1.1  oster   return(p);
    618  1.1  oster }
    619  1.1  oster 
    620  1.1  oster #if RF_UTILITY == 0
    621  1.1  oster /*****************************************************************************************
    622  1.1  oster  *
    623  1.1  oster  * ConfigureLayout --
    624  1.1  oster  *
    625  1.1  oster  * read the configuration file and set up the RAID layout parameters.  After reading
    626  1.1  oster  * common params, invokes the layout-specific configuration routine to finish
    627  1.1  oster  * the configuration.
    628  1.1  oster  *
    629  1.1  oster  ****************************************************************************************/
    630  1.1  oster int rf_ConfigureLayout(
    631  1.1  oster   RF_ShutdownList_t  **listp,
    632  1.1  oster   RF_Raid_t           *raidPtr,
    633  1.1  oster   RF_Config_t         *cfgPtr)
    634  1.1  oster {
    635  1.1  oster   RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout);
    636  1.1  oster   RF_ParityConfig_t parityConfig;
    637  1.1  oster   RF_LayoutSW_t *p;
    638  1.1  oster   int retval;
    639  1.1  oster 
    640  1.1  oster   layoutPtr->sectorsPerStripeUnit = cfgPtr->sectPerSU;
    641  1.1  oster   layoutPtr->SUsPerPU             = cfgPtr->SUsPerPU;
    642  1.1  oster   layoutPtr->SUsPerRU             = cfgPtr->SUsPerRU;
    643  1.1  oster   parityConfig                    = cfgPtr->parityConfig;
    644  1.1  oster 
    645  1.1  oster   layoutPtr->stripeUnitsPerDisk = raidPtr->sectorsPerDisk / layoutPtr->sectorsPerStripeUnit;
    646  1.1  oster 
    647  1.1  oster   p = rf_GetLayout(parityConfig);
    648  1.1  oster   if (p == NULL) {
    649  1.1  oster     RF_ERRORMSG1("Unknown parity configuration '%c'", parityConfig);
    650  1.1  oster     return(EINVAL);
    651  1.1  oster   }
    652  1.1  oster   RF_ASSERT(p->parityConfig == parityConfig);
    653  1.1  oster   layoutPtr->map = p;
    654  1.1  oster 
    655  1.1  oster   /* initialize the specific layout */
    656  1.1  oster 
    657  1.1  oster   retval = (p->Configure)(listp, raidPtr, cfgPtr);
    658  1.1  oster 
    659  1.1  oster   if (retval)
    660  1.1  oster     return(retval);
    661  1.1  oster 
    662  1.1  oster   layoutPtr->dataBytesPerStripe = layoutPtr->dataSectorsPerStripe << raidPtr->logBytesPerSector;
    663  1.1  oster   raidPtr->sectorsPerDisk = layoutPtr->stripeUnitsPerDisk * layoutPtr->sectorsPerStripeUnit;
    664  1.1  oster 
    665  1.1  oster   if (rf_forceNumFloatingReconBufs >= 0) {
    666  1.1  oster     raidPtr->numFloatingReconBufs = rf_forceNumFloatingReconBufs;
    667  1.1  oster   }
    668  1.1  oster   else {
    669  1.1  oster     raidPtr->numFloatingReconBufs = rf_GetDefaultNumFloatingReconBuffers(raidPtr);
    670  1.1  oster   }
    671  1.1  oster 
    672  1.1  oster   if (rf_forceHeadSepLimit >= 0) {
    673  1.1  oster     raidPtr->headSepLimit = rf_forceHeadSepLimit;
    674  1.1  oster   }
    675  1.1  oster   else {
    676  1.1  oster     raidPtr->headSepLimit = rf_GetDefaultHeadSepLimit(raidPtr);
    677  1.1  oster   }
    678  1.1  oster 
    679  1.1  oster   printf("RAIDFRAME: Configure (%s): total number of sectors is %lu (%lu MB)\n",
    680  1.1  oster      layoutPtr->map->configName,
    681  1.1  oster      (unsigned long)raidPtr->totalSectors,
    682  1.1  oster      (unsigned long)(raidPtr->totalSectors / 1024 * (1<<raidPtr->logBytesPerSector) / 1024));
    683  1.1  oster   if (raidPtr->headSepLimit >= 0) {
    684  1.1  oster     printf("RAIDFRAME(%s): Using %ld floating recon bufs with head sep limit %ld\n",
    685  1.1  oster       layoutPtr->map->configName, (long)raidPtr->numFloatingReconBufs, (long)raidPtr->headSepLimit);
    686  1.1  oster   }
    687  1.1  oster   else {
    688  1.1  oster     printf("RAIDFRAME(%s): Using %ld floating recon bufs with no head sep limit\n",
    689  1.1  oster       layoutPtr->map->configName, (long)raidPtr->numFloatingReconBufs);
    690  1.1  oster   }
    691  1.1  oster 
    692  1.1  oster   return(0);
    693  1.1  oster }
    694  1.1  oster 
    695  1.1  oster /* typically there is a 1-1 mapping between stripes and parity stripes.
    696  1.1  oster  * however, the declustering code supports packing multiple stripes into
    697  1.1  oster  * a single parity stripe, so as to increase the size of the reconstruction
    698  1.1  oster  * unit without affecting the size of the stripe unit.  This routine finds
    699  1.1  oster  * the parity stripe identifier associated with a stripe ID.  There is also
    700  1.1  oster  * a RaidAddressToParityStripeID macro in layout.h
    701  1.1  oster  */
    702  1.1  oster RF_StripeNum_t rf_MapStripeIDToParityStripeID(layoutPtr, stripeID, which_ru)
    703  1.1  oster   RF_RaidLayout_t    *layoutPtr;
    704  1.1  oster   RF_StripeNum_t      stripeID;
    705  1.1  oster   RF_ReconUnitNum_t  *which_ru;
    706  1.1  oster {
    707  1.1  oster   RF_StripeNum_t parityStripeID;
    708  1.1  oster 
    709  1.1  oster   /* quick exit in the common case of SUsPerPU==1 */
    710  1.1  oster   if ((layoutPtr->SUsPerPU == 1) || !layoutPtr->map->MapSIDToPSID) {
    711  1.1  oster     *which_ru = 0;
    712  1.1  oster     return(stripeID);
    713  1.1  oster   }
    714  1.1  oster   else {
    715  1.1  oster     (layoutPtr->map->MapSIDToPSID)(layoutPtr, stripeID, &parityStripeID, which_ru);
    716  1.1  oster   }
    717  1.1  oster   return(parityStripeID);
    718  1.1  oster }
    719  1.1  oster #endif /* RF_UTILITY == 0 */
    720