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