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@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