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