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