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