Home | History | Annotate | Line # | Download | only in raidframe
rf_layout.h revision 1.2
      1 /*	$NetBSD: rf_layout.h,v 1.2 1999/01/26 02:33:58 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.h -- header file defining layout data structures
     30  */
     31 
     32 #ifndef _RF__RF_LAYOUT_H_
     33 #define _RF__RF_LAYOUT_H_
     34 
     35 #include "rf_types.h"
     36 #include "rf_archs.h"
     37 #include "rf_alloclist.h"
     38 
     39 #ifndef _KERNEL
     40 #include <stdio.h>
     41 #endif
     42 
     43 /*****************************************************************************************
     44  *
     45  * This structure identifies all layout-specific operations and parameters.
     46  *
     47  ****************************************************************************************/
     48 
     49 typedef struct RF_LayoutSW_s {
     50   RF_ParityConfig_t   parityConfig;
     51   char               *configName;
     52 
     53 #ifndef _KERNEL
     54  /* layout-specific parsing */
     55   int (*MakeLayoutSpecific)(FILE *fp, RF_Config_t *cfgPtr, void *arg);
     56   void *makeLayoutSpecificArg;
     57 #endif /* !KERNEL */
     58 
     59 #if RF_UTILITY == 0
     60  /* initialization routine */
     61   int (*Configure)(RF_ShutdownList_t **shutdownListp, RF_Raid_t *raidPtr, RF_Config_t *cfgPtr);
     62 
     63  /* routine to map RAID sector address -> physical (row, col, offset) */
     64   void (*MapSector)(RF_Raid_t *raidPtr, RF_RaidAddr_t raidSector,
     65     RF_RowCol_t *row, RF_RowCol_t *col, RF_SectorNum_t *diskSector, int remap);
     66 
     67  /* routine to map RAID sector address -> physical (r,c,o) of parity unit */
     68   void (*MapParity)(RF_Raid_t *raidPtr, RF_RaidAddr_t raidSector,
     69     RF_RowCol_t *row, RF_RowCol_t *col, RF_SectorNum_t *diskSector, int remap);
     70 
     71  /* routine to map RAID sector address -> physical (r,c,o) of Q unit */
     72   void (*MapQ)(RF_Raid_t *raidPtr, RF_RaidAddr_t raidSector, RF_RowCol_t *row,
     73     RF_RowCol_t *col, RF_SectorNum_t *diskSector, int remap);
     74 
     75  /* routine to identify the disks comprising a stripe */
     76   void (*IdentifyStripe)(RF_Raid_t *raidPtr, RF_RaidAddr_t addr,
     77     RF_RowCol_t **diskids, RF_RowCol_t *outRow);
     78 
     79  /* routine to select a dag */
     80   void (*SelectionFunc)(RF_Raid_t *raidPtr, RF_IoType_t type,
     81 			RF_AccessStripeMap_t *asmap,
     82 			RF_VoidFuncPtr *);
     83 #if 0
     84 			void (**createFunc)(RF_Raid_t *,
     85 					    RF_AccessStripeMap_t *,
     86 					    RF_DagHeader_t *, void *,
     87 					    RF_RaidAccessFlags_t,
     88 					    RF_AllocListElem_t *));
     89 
     90 #endif
     91 
     92  /* map a stripe ID to a parity stripe ID.  This is typically the identity mapping */
     93   void (*MapSIDToPSID)(RF_RaidLayout_t *layoutPtr, RF_StripeNum_t stripeID,
     94     RF_StripeNum_t *psID, RF_ReconUnitNum_t *which_ru);
     95 
     96  /* get default head separation limit (may be NULL) */
     97   RF_HeadSepLimit_t (*GetDefaultHeadSepLimit)(RF_Raid_t *raidPtr);
     98 
     99  /* get default num recon buffers (may be NULL) */
    100   int (*GetDefaultNumFloatingReconBuffers)(RF_Raid_t *raidPtr);
    101 
    102  /* get number of spare recon units (may be NULL) */
    103   RF_ReconUnitCount_t (*GetNumSpareRUs)(RF_Raid_t *raidPtr);
    104 
    105  /* spare table installation (may be NULL) */
    106   int (*InstallSpareTable)(RF_Raid_t *raidPtr, RF_RowCol_t frow, RF_RowCol_t fcol);
    107 
    108  /* recon buffer submission function */
    109   int (*SubmitReconBuffer)(RF_ReconBuffer_t *rbuf, int keep_it,
    110     int use_committed);
    111 
    112  /*
    113   * verify that parity information for a stripe is correct
    114   * see rf_parityscan.h for return vals
    115   */
    116   int (*VerifyParity)(RF_Raid_t *raidPtr, RF_RaidAddr_t raidAddr,
    117     RF_PhysDiskAddr_t *parityPDA, int correct_it, RF_RaidAccessFlags_t flags);
    118 
    119  /* number of faults tolerated by this mapping */
    120   int  faultsTolerated;
    121 
    122  /* states to step through in an access. Must end with "LastState".
    123   * The default is DefaultStates in rf_layout.c */
    124   RF_AccessState_t *states;
    125 
    126   RF_AccessStripeMapFlags_t  flags;
    127 #endif /* RF_UTILITY == 0 */
    128 } RF_LayoutSW_t;
    129 
    130 /* enables remapping to spare location under dist sparing */
    131 #define RF_REMAP       1
    132 #define RF_DONT_REMAP  0
    133 
    134 /*
    135  * Flags values for RF_AccessStripeMapFlags_t
    136  */
    137 #define RF_NO_STRIPE_LOCKS   0x0001   /* suppress stripe locks */
    138 #define RF_DISTRIBUTE_SPARE  0x0002   /* distribute spare space in archs that support it */
    139 #define RF_BD_DECLUSTERED    0x0004   /* declustering uses block designs */
    140 
    141 /*************************************************************************
    142  *
    143  * this structure forms the layout component of the main Raid
    144  * structure.  It describes everything needed to define and perform
    145  * the mapping of logical RAID addresses <-> physical disk addresses.
    146  *
    147  *************************************************************************/
    148 struct RF_RaidLayout_s {
    149   /* configuration parameters */
    150   RF_SectorCount_t  sectorsPerStripeUnit;   /* number of sectors in one stripe unit */
    151   RF_StripeCount_t  SUsPerPU;               /* stripe units per parity unit */
    152   RF_StripeCount_t  SUsPerRU;               /* stripe units per reconstruction unit */
    153 
    154   /* redundant-but-useful info computed from the above, used in all layouts */
    155   RF_StripeCount_t  numStripe;              /* total number of stripes in the array */
    156   RF_SectorCount_t  dataSectorsPerStripe;
    157   RF_StripeCount_t  dataStripeUnitsPerDisk;
    158   u_int             bytesPerStripeUnit;
    159   u_int             dataBytesPerStripe;
    160   RF_StripeCount_t  numDataCol;             /* number of SUs of data per stripe (name here is a la RAID4) */
    161   RF_StripeCount_t  numParityCol;           /* number of SUs of parity per stripe.  Always 1 for now */
    162   RF_StripeCount_t  numParityLogCol;        /* number of SUs of parity log per stripe.  Always 1 for now */
    163   RF_StripeCount_t  stripeUnitsPerDisk;
    164 
    165   RF_LayoutSW_t *map;               /* ptr to struct holding mapping fns and information */
    166   void *layoutSpecificInfo;         /* ptr to a structure holding layout-specific params */
    167 };
    168 
    169 /*****************************************************************************************
    170  *
    171  * The mapping code returns a pointer to a list of AccessStripeMap structures, which
    172  * describes all the mapping information about an access.  The list contains one
    173  * AccessStripeMap structure per stripe touched by the access.  Each element in the list
    174  * contains a stripe identifier and a pointer to a list of PhysDiskAddr structuress.  Each
    175  * element in this latter list describes the physical location of a stripe unit accessed
    176  * within the corresponding stripe.
    177  *
    178  ****************************************************************************************/
    179 
    180 #define RF_PDA_TYPE_DATA   0
    181 #define RF_PDA_TYPE_PARITY 1
    182 #define RF_PDA_TYPE_Q      2
    183 
    184 struct RF_PhysDiskAddr_s {
    185   RF_RowCol_t         row,col;      /* disk identifier */
    186   RF_SectorNum_t      startSector;  /* sector offset into the disk */
    187   RF_SectorCount_t    numSector;    /* number of sectors accessed */
    188   int                 type;         /* used by higher levels: currently, data, parity, or q */
    189   caddr_t             bufPtr;       /* pointer to buffer supplying/receiving data */
    190   RF_RaidAddr_t       raidAddress;  /* raid address corresponding to this physical disk address */
    191   RF_PhysDiskAddr_t  *next;
    192 };
    193 
    194 #define RF_MAX_FAILED_PDA RF_MAXCOL
    195 
    196 struct RF_AccessStripeMap_s {
    197   RF_StripeNum_t             stripeID;                /* the stripe index */
    198   RF_RaidAddr_t              raidAddress;             /* the starting raid address within this stripe */
    199   RF_RaidAddr_t              endRaidAddress;          /* raid address one sector past the end of the access */
    200   RF_SectorCount_t           totalSectorsAccessed;    /* total num sectors identified in physInfo list */
    201   RF_StripeCount_t           numStripeUnitsAccessed;  /* total num elements in physInfo list */
    202   int                        numDataFailed;           /* number of failed data disks accessed */
    203   int                        numParityFailed;         /* number of failed parity disks accessed (0 or 1) */
    204   int                        numQFailed;              /* number of failed Q units accessed (0 or 1) */
    205   RF_AccessStripeMapFlags_t  flags;                   /* various flags */
    206 #if 0
    207   RF_PhysDiskAddr_t         *failedPDA;               /* points to the PDA that has failed */
    208   RF_PhysDiskAddr_t         *failedPDAtwo;            /* points to the second PDA that has failed, if any */
    209 #else
    210   int                        numFailedPDAs;           /* number of failed phys addrs */
    211   RF_PhysDiskAddr_t         *failedPDAs[RF_MAX_FAILED_PDA]; /* array of failed phys addrs */
    212 #endif
    213   RF_PhysDiskAddr_t         *physInfo;                /* a list of PhysDiskAddr structs */
    214   RF_PhysDiskAddr_t         *parityInfo;              /* list of physical addrs for the parity (P of P + Q ) */
    215   RF_PhysDiskAddr_t         *qInfo;                   /* list of physical addrs for the Q of P + Q */
    216   RF_LockReqDesc_t           lockReqDesc;             /* used for stripe locking */
    217   RF_RowCol_t                origRow;                 /* the original row:  we may redirect the acc to a different row */
    218   RF_AccessStripeMap_t      *next;
    219 };
    220 
    221 /* flag values */
    222 #define RF_ASM_REDIR_LARGE_WRITE   0x00000001 /* allows large-write creation code to redirect failed accs */
    223 #define RF_ASM_BAILOUT_DAG_USED    0x00000002 /* allows us to detect recursive calls to the bailout write dag */
    224 #define RF_ASM_FLAGS_LOCK_TRIED    0x00000004 /* we've acquired the lock on the first parity range in this parity stripe */
    225 #define RF_ASM_FLAGS_LOCK_TRIED2   0x00000008 /* we've acquired the lock on the 2nd   parity range in this parity stripe */
    226 #define RF_ASM_FLAGS_FORCE_TRIED   0x00000010 /* we've done the force-recon call on this parity stripe */
    227 #define RF_ASM_FLAGS_RECON_BLOCKED 0x00000020 /* we blocked recon => we must unblock it later */
    228 
    229 struct RF_AccessStripeMapHeader_s {
    230   RF_StripeCount_t             numStripes; /* total number of stripes touched by this acc */
    231   RF_AccessStripeMap_t        *stripeMap;  /* pointer to the actual map.  Also used for making lists */
    232   RF_AccessStripeMapHeader_t  *next;
    233 };
    234 
    235 /*****************************************************************************************
    236  *
    237  * various routines mapping addresses in the RAID address space.  These work across
    238  * all layouts.  DON'T PUT ANY LAYOUT-SPECIFIC CODE HERE.
    239  *
    240  ****************************************************************************************/
    241 
    242 /* return the identifier of the stripe containing the given address */
    243 #define rf_RaidAddressToStripeID(_layoutPtr_, _addr_) \
    244   ( ((_addr_) / (_layoutPtr_)->sectorsPerStripeUnit) / (_layoutPtr_)->numDataCol )
    245 
    246 /* return the raid address of the start of the indicates stripe ID */
    247 #define rf_StripeIDToRaidAddress(_layoutPtr_, _sid_) \
    248   ( ((_sid_) * (_layoutPtr_)->sectorsPerStripeUnit) * (_layoutPtr_)->numDataCol )
    249 
    250 /* return the identifier of the stripe containing the given stripe unit id */
    251 #define rf_StripeUnitIDToStripeID(_layoutPtr_, _addr_) \
    252   ( (_addr_) / (_layoutPtr_)->numDataCol )
    253 
    254 /* return the identifier of the stripe unit containing the given address */
    255 #define rf_RaidAddressToStripeUnitID(_layoutPtr_, _addr_) \
    256   ( ((_addr_) / (_layoutPtr_)->sectorsPerStripeUnit) )
    257 
    258 /* return the RAID address of next stripe boundary beyond the given address */
    259 #define rf_RaidAddressOfNextStripeBoundary(_layoutPtr_, _addr_) \
    260   ( (((_addr_)/(_layoutPtr_)->dataSectorsPerStripe)+1) * (_layoutPtr_)->dataSectorsPerStripe )
    261 
    262 /* return the RAID address of the start of the stripe containing the given address */
    263 #define rf_RaidAddressOfPrevStripeBoundary(_layoutPtr_, _addr_) \
    264   ( (((_addr_)/(_layoutPtr_)->dataSectorsPerStripe)+0) * (_layoutPtr_)->dataSectorsPerStripe )
    265 
    266 /* return the RAID address of next stripe unit boundary beyond the given address */
    267 #define rf_RaidAddressOfNextStripeUnitBoundary(_layoutPtr_, _addr_) \
    268   ( (((_addr_)/(_layoutPtr_)->sectorsPerStripeUnit)+1L)*(_layoutPtr_)->sectorsPerStripeUnit )
    269 
    270 /* return the RAID address of the start of the stripe unit containing RAID address _addr_ */
    271 #define rf_RaidAddressOfPrevStripeUnitBoundary(_layoutPtr_, _addr_) \
    272   ( (((_addr_)/(_layoutPtr_)->sectorsPerStripeUnit)+0)*(_layoutPtr_)->sectorsPerStripeUnit )
    273 
    274 /* returns the offset into the stripe.  used by RaidAddressStripeAligned */
    275 #define rf_RaidAddressStripeOffset(_layoutPtr_, _addr_) \
    276   ( (_addr_) % ((_layoutPtr_)->dataSectorsPerStripe) )
    277 
    278 /* returns the offset into the stripe unit.  */
    279 #define rf_StripeUnitOffset(_layoutPtr_, _addr_) \
    280   ( (_addr_) % ((_layoutPtr_)->sectorsPerStripeUnit) )
    281 
    282 /* returns nonzero if the given RAID address is stripe-aligned */
    283 #define rf_RaidAddressStripeAligned( __layoutPtr__, __addr__ ) \
    284   ( rf_RaidAddressStripeOffset(__layoutPtr__, __addr__) == 0 )
    285 
    286 /* returns nonzero if the given address is stripe-unit aligned */
    287 #define rf_StripeUnitAligned( __layoutPtr__, __addr__ ) \
    288   ( rf_StripeUnitOffset(__layoutPtr__, __addr__) == 0 )
    289 
    290 /* convert an address expressed in RAID blocks to/from an addr expressed in bytes */
    291 #define rf_RaidAddressToByte(_raidPtr_, _addr_) \
    292   ( (_addr_) << ( (_raidPtr_)->logBytesPerSector ) )
    293 
    294 #define rf_ByteToRaidAddress(_raidPtr_, _addr_) \
    295   ( (_addr_) >> ( (_raidPtr_)->logBytesPerSector ) )
    296 
    297 /* convert a raid address to/from a parity stripe ID.  Conversion to raid address is easy,
    298  * since we're asking for the address of the first sector in the parity stripe.  Conversion to a
    299  * parity stripe ID is more complex, since stripes are not contiguously allocated in
    300  * parity stripes.
    301  */
    302 #define rf_RaidAddressToParityStripeID(_layoutPtr_, _addr_, _ru_num_) \
    303   rf_MapStripeIDToParityStripeID( (_layoutPtr_), rf_RaidAddressToStripeID( (_layoutPtr_), (_addr_) ), (_ru_num_) )
    304 
    305 #define rf_ParityStripeIDToRaidAddress(_layoutPtr_, _psid_) \
    306   ( (_psid_) * (_layoutPtr_)->SUsPerPU * (_layoutPtr_)->numDataCol * (_layoutPtr_)->sectorsPerStripeUnit )
    307 
    308 RF_LayoutSW_t *rf_GetLayout(RF_ParityConfig_t parityConfig);
    309 int rf_ConfigureLayout(RF_ShutdownList_t **listp, RF_Raid_t *raidPtr,
    310 	RF_Config_t *cfgPtr);
    311 RF_StripeNum_t rf_MapStripeIDToParityStripeID(RF_RaidLayout_t *layoutPtr,
    312 	RF_StripeNum_t stripeID, RF_ReconUnitNum_t *which_ru);
    313 
    314 #endif /* !_RF__RF_LAYOUT_H_ */
    315