Annotation of sys/dev/raidframe/rf_layout.h, Revision 1.1
1.1 ! nbrk 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_ */
CVSweb