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