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_ */