1 /* $OpenBSD: rf_layout.h,v 1.5 2002/12/16 07:01:04 tdeval Exp $ */ 2 /* $NetBSD: rf_layout.h,v 1.4 2000/05/23 00:44:38 thorpej Exp $ */ 3 4 /* 5 * Copyright (c) 1995 Carnegie-Mellon University. 6 * All rights reserved. 7 * 8 * Author: Mark Holland 9 * 10 * Permission to use, copy, modify and distribute this software and 11 * its documentation is hereby granted, provided that both the copyright 12 * notice and this permission notice appear in all copies of the 13 * software, derivative works or modified versions, and any portions 14 * thereof, and that both notices appear in supporting documentation. 15 * 16 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 17 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 18 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 19 * 20 * Carnegie Mellon requests users of this software to return to 21 * 22 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 23 * School of Computer Science 24 * Carnegie Mellon University 25 * Pittsburgh PA 15213-3890 26 * 27 * any improvements or extensions that they make and grant Carnegie the 28 * rights to redistribute these changes. 29 */ 30 31 /* 32 * rf_layout.h -- Header file defining layout data structures. 33 */ 34 35 #ifndef _RF__RF_LAYOUT_H_ 36 #define _RF__RF_LAYOUT_H_ 37 38 #include "rf_types.h" 39 #include "rf_archs.h" 40 #include "rf_alloclist.h" 41 42 #ifndef _KERNEL 43 #include <stdio.h> 44 #endif 45 46 /***************************************************************************** 47 * 48 * This structure identifies all layout-specific operations and parameters. 49 * 50 *****************************************************************************/ 51 52 typedef struct RF_LayoutSW_s { 53 RF_ParityConfig_t parityConfig; 54 const char *configName; 55 56 #ifndef _KERNEL 57 /* Layout-specific parsing. */ 58 int (*MakeLayoutSpecific) 59 (FILE *, RF_Config_t *, void *); 60 void *makeLayoutSpecificArg; 61 #endif /* !_KERNEL */ 62 63 #if RF_UTILITY == 0 64 /* Initialization routine. */ 65 int (*Configure) 66 (RF_ShutdownList_t **, RF_Raid_t *, 67 RF_Config_t *); 68 69 /* Routine to map RAID sector address -> physical (row, col, offset). */ 70 void (*MapSector) 71 (RF_Raid_t *, RF_RaidAddr_t, RF_RowCol_t *, 72 RF_RowCol_t *, RF_SectorNum_t *, int); 73 74 /* 75 * Routine to map RAID sector address -> physical (r,c,o) of parity 76 * unit. 77 */ 78 void (*MapParity) 79 (RF_Raid_t *, RF_RaidAddr_t, RF_RowCol_t *, 80 RF_RowCol_t *, RF_SectorNum_t *, int); 81 82 /* Routine to map RAID sector address -> physical (r,c,o) of Q unit. */ 83 void (*MapQ) 84 (RF_Raid_t *, RF_RaidAddr_t, RF_RowCol_t *, 85 RF_RowCol_t *, RF_SectorNum_t *, int); 86 87 /* Routine to identify the disks comprising a stripe. */ 88 void (*IdentifyStripe) 89 (RF_Raid_t *, RF_RaidAddr_t, RF_RowCol_t **, 90 RF_RowCol_t *); 91 92 /* Routine to select a dag. */ 93 void (*SelectionFunc) 94 (RF_Raid_t *, RF_IoType_t, 95 RF_AccessStripeMap_t *, RF_VoidFuncPtr *); 96 #if 0 97 void (**createFunc) 98 (RF_Raid_t *, RF_AccessStripeMap_t *, 99 RF_DagHeader_t *, void *, 100 RF_RaidAccessFlags_t, RF_AllocListElem_t *); 101 #endif 102 103 /* 104 * Map a stripe ID to a parity stripe ID. This is typically the 105 * identity mapping. 106 */ 107 void (*MapSIDToPSID) 108 (RF_RaidLayout_t *, RF_StripeNum_t, 109 RF_StripeNum_t *, RF_ReconUnitNum_t *); 110 111 /* Get default head separation limit (may be NULL). */ 112 RF_HeadSepLimit_t (*GetDefaultHeadSepLimit) (RF_Raid_t *); 113 114 /* Get default num recon buffers (may be NULL). */ 115 int (*GetDefaultNumFloatingReconBuffers) 116 (RF_Raid_t *); 117 118 /* Get number of spare recon units (may be NULL). */ 119 RF_ReconUnitCount_t (*GetNumSpareRUs) (RF_Raid_t *); 120 121 /* Spare table installation (may be NULL). */ 122 int (*InstallSpareTable) 123 (RF_Raid_t *, RF_RowCol_t, RF_RowCol_t); 124 125 /* Recon buffer submission function. */ 126 int (*SubmitReconBuffer) 127 (RF_ReconBuffer_t *, int, int); 128 129 /* 130 * Verify that parity information for a stripe is correct. 131 * See rf_parityscan.h for return vals. 132 */ 133 int (*VerifyParity) 134 (RF_Raid_t *, RF_RaidAddr_t, 135 RF_PhysDiskAddr_t *, int, 136 RF_RaidAccessFlags_t); 137 138 /* Number of faults tolerated by this mapping. */ 139 int faultsTolerated; 140 141 /* 142 * States to step through in an access. Must end with "LastState". The 143 * default is DefaultStates in rf_layout.c . 144 */ 145 RF_AccessState_t *states; 146 147 RF_AccessStripeMapFlags_t flags; 148 #endif /* RF_UTILITY == 0 */ 149 } RF_LayoutSW_t; 150 151 /* Enables remapping to spare location under dist sparing. */ 152 #define RF_REMAP 1 153 #define RF_DONT_REMAP 0 154 155 /* 156 * Flags values for RF_AccessStripeMapFlags_t. 157 */ 158 #define RF_NO_STRIPE_LOCKS 0x0001 /* Suppress stripe locks. */ 159 #define RF_DISTRIBUTE_SPARE 0x0002 /* 160 * Distribute spare space in 161 * archs that support it. 162 */ 163 #define RF_BD_DECLUSTERED 0x0004 /* 164 * Declustering uses block 165 * designs. 166 */ 167 168 /************************************************************************* 169 * 170 * This structure forms the layout component of the main Raid 171 * structure. It describes everything needed to define and perform 172 * the mapping of logical RAID addresses <-> physical disk addresses. 173 * 174 *************************************************************************/ 175 struct RF_RaidLayout_s { 176 /* Configuration parameters. */ 177 RF_SectorCount_t sectorsPerStripeUnit; 178 /* 179 * Number of sectors in one 180 * stripe unit. 181 */ 182 RF_StripeCount_t SUsPerPU; /* 183 * Stripe units per parity unit. 184 */ 185 RF_StripeCount_t SUsPerRU; /* 186 * Stripe units per 187 * reconstruction unit. 188 */ 189 190 /* 191 * Redundant-but-useful info computed from the above, used in all 192 * layouts. 193 */ 194 RF_StripeCount_t numStripe; /* 195 * Total number of stripes 196 * in the array. 197 */ 198 RF_SectorCount_t dataSectorsPerStripe; 199 RF_StripeCount_t dataStripeUnitsPerDisk; 200 u_int bytesPerStripeUnit; 201 u_int dataBytesPerStripe; 202 RF_StripeCount_t numDataCol; /* 203 * Number of SUs of data per 204 * stripe. 205 * (name here is a la RAID4) 206 */ 207 RF_StripeCount_t numParityCol; /* 208 * Number of SUs of parity 209 * per stripe. 210 * Always 1 for now. 211 */ 212 RF_StripeCount_t numParityLogCol; 213 /* 214 * Number of SUs of parity log 215 * per stripe. 216 * Always 1 for now. 217 */ 218 RF_StripeCount_t stripeUnitsPerDisk; 219 220 RF_LayoutSW_t *map; /* 221 * Pointer to struct holding 222 * mapping fns and information. 223 */ 224 void *layoutSpecificInfo; 225 /* Pointer to a struct holding 226 * layout-specific params. 227 */ 228 }; 229 230 /***************************************************************************** 231 * 232 * The mapping code returns a pointer to a list of AccessStripeMap 233 * structures, which describes all the mapping information about an access. 234 * The list contains one AccessStripeMap structure per stripe touched by 235 * the access. Each element in the list contains a stripe identifier and 236 * a pointer to a list of PhysDiskAddr structuress. Each element in this 237 * latter list describes the physical location of a stripe unit accessed 238 * within the corresponding stripe. 239 * 240 *****************************************************************************/ 241 242 #define RF_PDA_TYPE_DATA 0 243 #define RF_PDA_TYPE_PARITY 1 244 #define RF_PDA_TYPE_Q 2 245 246 struct RF_PhysDiskAddr_s { 247 RF_RowCol_t row, col; /* Disk identifier. */ 248 RF_SectorNum_t startSector; /* 249 * Sector offset into the disk. 250 */ 251 RF_SectorCount_t numSector; /* 252 * Number of sectors accessed. 253 */ 254 int type; /* 255 * Used by higher levels: 256 * currently data, parity, 257 * or q. 258 */ 259 caddr_t bufPtr; /* 260 * Pointer to buffer 261 * supplying/receiving data. 262 */ 263 RF_RaidAddr_t raidAddress; /* 264 * Raid address corresponding 265 * to this physical disk 266 * address. 267 */ 268 RF_PhysDiskAddr_t *next; 269 }; 270 #define RF_MAX_FAILED_PDA RF_MAXCOL 271 272 struct RF_AccessStripeMap_s { 273 RF_StripeNum_t stripeID; /* The stripe index. */ 274 RF_RaidAddr_t raidAddress; /* 275 * The starting raid address 276 * within this stripe. 277 */ 278 RF_RaidAddr_t endRaidAddress;/* 279 * Raid address one sector past 280 * the end of the access. 281 */ 282 RF_SectorCount_t totalSectorsAccessed; 283 /* 284 * Total num sectors 285 * identified in physInfo list. 286 */ 287 RF_StripeCount_t numStripeUnitsAccessed; 288 /* 289 * Total num elements in 290 * physInfo list. 291 */ 292 int numDataFailed; /* 293 * Number of failed data disks 294 * accessed. 295 */ 296 int numParityFailed; 297 /* 298 * Number of failed parity 299 * disks accessed (0 or 1). 300 */ 301 int numQFailed; /* 302 * Number of failed Q units 303 * accessed (0 or 1). 304 */ 305 RF_AccessStripeMapFlags_t flags; /* Various flags. */ 306 #if 0 307 RF_PhysDiskAddr_t *failedPDA; /* 308 * Points to the PDA that 309 * has failed. 310 */ 311 RF_PhysDiskAddr_t *failedPDAtwo; /* 312 * Points to the second PDA 313 * that has failed, if any. 314 */ 315 #else 316 int numFailedPDAs; /* 317 * Number of failed phys addrs. 318 */ 319 RF_PhysDiskAddr_t *failedPDAs[RF_MAX_FAILED_PDA]; 320 /* 321 * Array of failed phys addrs. 322 */ 323 #endif 324 RF_PhysDiskAddr_t *physInfo; /* 325 * A list of PhysDiskAddr 326 * structs. 327 */ 328 RF_PhysDiskAddr_t *parityInfo; /* 329 * List of physical addrs for 330 * the parity (P of P + Q). 331 */ 332 RF_PhysDiskAddr_t *qInfo; /* 333 * List of physical addrs for 334 * the Q of P + Q. 335 */ 336 RF_LockReqDesc_t lockReqDesc; /* Used for stripe locking. */ 337 RF_RowCol_t origRow; /* 338 * The original row: we may 339 * redirect the acc to a 340 * different row. 341 */ 342 RF_AccessStripeMap_t *next; 343 }; 344 /* Flag values. */ 345 #define RF_ASM_REDIR_LARGE_WRITE 0x00000001 /* 346 * Allows large-write 347 * creation code to 348 * redirect failed 349 * accs. 350 */ 351 #define RF_ASM_BAILOUT_DAG_USED 0x00000002 /* 352 * Allows us to detect 353 * recursive calls to 354 * the bailout write 355 * dag. 356 */ 357 #define RF_ASM_FLAGS_LOCK_TRIED 0x00000004 /* 358 * We've acquired the 359 * lock on the first 360 * parity range in 361 * this parity stripe. 362 */ 363 #define RF_ASM_FLAGS_LOCK_TRIED2 0x00000008 /* 364 * we've acquired the 365 * lock on the 2nd 366 * parity range in this 367 * parity stripe. 368 */ 369 #define RF_ASM_FLAGS_FORCE_TRIED 0x00000010 /* 370 * We've done the 371 * force-recon call on 372 * this parity stripe. 373 */ 374 #define RF_ASM_FLAGS_RECON_BLOCKED 0x00000020 /* 375 * We blocked recon 376 * => we must unblock 377 * it later. 378 */ 379 380 struct RF_AccessStripeMapHeader_s { 381 RF_StripeCount_t numStripes; /* 382 * Total number of stripes 383 * touched by this access. 384 */ 385 RF_AccessStripeMap_t *stripeMap; /* 386 * Pointer to the actual map. 387 * Also used for making lists. 388 */ 389 RF_AccessStripeMapHeader_t *next; 390 }; 391 392 393 /***************************************************************************** 394 * 395 * Various routines mapping addresses in the RAID address space. These work 396 * across all layouts. DON'T PUT ANY LAYOUT-SPECIFIC CODE HERE. 397 * 398 *****************************************************************************/ 399 400 /* Return the identifier of the stripe containing the given address. */ 401 #define rf_RaidAddressToStripeID(_layoutPtr_,_addr_) \ 402 (((_addr_) / (_layoutPtr_)->sectorsPerStripeUnit) / \ 403 (_layoutPtr_)->numDataCol) 404 405 /* Return the raid address of the start of the indicates stripe ID. */ 406 #define rf_StripeIDToRaidAddress(_layoutPtr_,_sid_) \ 407 (((_sid_) * (_layoutPtr_)->sectorsPerStripeUnit) * \ 408 (_layoutPtr_)->numDataCol) 409 410 /* Return the identifier of the stripe containing the given stripe unit ID. */ 411 #define rf_StripeUnitIDToStripeID(_layoutPtr_,_addr_) \ 412 ((_addr_) / (_layoutPtr_)->numDataCol) 413 414 /* Return the identifier of the stripe unit containing the given address. */ 415 #define rf_RaidAddressToStripeUnitID(_layoutPtr_,_addr_) \ 416 (((_addr_) / (_layoutPtr_)->sectorsPerStripeUnit)) 417 418 /* Return the RAID address of next stripe boundary beyond the given address. */ 419 #define rf_RaidAddressOfNextStripeBoundary(_layoutPtr_,_addr_) \ 420 ((((_addr_) / (_layoutPtr_)->dataSectorsPerStripe) + 1) * \ 421 (_layoutPtr_)->dataSectorsPerStripe) 422 423 /* 424 * Return the RAID address of the start of the stripe containing the 425 * given address. 426 */ 427 #define rf_RaidAddressOfPrevStripeBoundary(_layoutPtr_,_addr_) \ 428 ((((_addr_) / (_layoutPtr_)->dataSectorsPerStripe) + 0) * \ 429 (_layoutPtr_)->dataSectorsPerStripe) 430 431 /* 432 * Return the RAID address of next stripe unit boundary beyond the 433 * given address. 434 */ 435 #define rf_RaidAddressOfNextStripeUnitBoundary(_layoutPtr_,_addr_) \ 436 ((((_addr_) / (_layoutPtr_)->sectorsPerStripeUnit) + 1L) * \ 437 (_layoutPtr_)->sectorsPerStripeUnit) 438 439 /* 440 * Return the RAID address of the start of the stripe unit containing 441 * RAID address _addr_. 442 */ 443 #define rf_RaidAddressOfPrevStripeUnitBoundary(_layoutPtr_,_addr_) \ 444 ((((_addr_) / (_layoutPtr_)->sectorsPerStripeUnit) + 0) * \ 445 (_layoutPtr_)->sectorsPerStripeUnit) 446 447 /* Returns the offset into the stripe. Used by RaidAddressStripeAligned. */ 448 #define rf_RaidAddressStripeOffset(_layoutPtr_,_addr_) \ 449 ((_addr_) % (_layoutPtr_)->dataSectorsPerStripe) 450 451 /* Returns the offset into the stripe unit. */ 452 #define rf_StripeUnitOffset(_layoutPtr_,_addr_) \ 453 ((_addr_) % (_layoutPtr_)->sectorsPerStripeUnit) 454 455 /* Returns nonzero if the given RAID address is stripe-aligned. */ 456 #define rf_RaidAddressStripeAligned(__layoutPtr__,__addr__) \ 457 (rf_RaidAddressStripeOffset(__layoutPtr__, __addr__) == 0) 458 459 /* Returns nonzero if the given address is stripe-unit aligned. */ 460 #define rf_StripeUnitAligned(__layoutPtr__,__addr__) \ 461 (rf_StripeUnitOffset(__layoutPtr__, __addr__) == 0) 462 463 /* 464 * Convert an address expressed in RAID blocks to/from an addr expressed 465 * in bytes. 466 */ 467 #define rf_RaidAddressToByte(_raidPtr_,_addr_) \ 468 ((_addr_) << (_raidPtr_)->logBytesPerSector) 469 470 #define rf_ByteToRaidAddress(_raidPtr_,_addr_) \ 471 ((_addr_) >> (_raidPtr_)->logBytesPerSector) 472 473 /* 474 * Convert a raid address to/from a parity stripe ID. Conversion to raid 475 * address is easy, since we're asking for the address of the first sector 476 * in the parity stripe. Conversion to a parity stripe ID is more complex, 477 * since stripes are not contiguously allocated in parity stripes. 478 */ 479 #define rf_RaidAddressToParityStripeID(_layoutPtr_,_addr_,_ru_num_) \ 480 rf_MapStripeIDToParityStripeID((_layoutPtr_), \ 481 rf_RaidAddressToStripeID((_layoutPtr_), (_addr_)), (_ru_num_)) 482 483 #define rf_ParityStripeIDToRaidAddress(_layoutPtr_,_psid_) \ 484 ((_psid_) * (_layoutPtr_)->SUsPerPU * \ 485 (_layoutPtr_)->numDataCol * (_layoutPtr_)->sectorsPerStripeUnit) 486 487 RF_LayoutSW_t *rf_GetLayout(RF_ParityConfig_t); 488 int rf_ConfigureLayout(RF_ShutdownList_t **, RF_Raid_t *, RF_Config_t *); 489 RF_StripeNum_t rf_MapStripeIDToParityStripeID(RF_RaidLayout_t *, 490 RF_StripeNum_t, RF_ReconUnitNum_t *); 491 492 #endif /* !_RF__RF_LAYOUT_H_ */ 493