xref: /titanic_41/usr/src/uts/common/sys/lvm/md_raid.h (revision e0724c534a46ca4754330bc022bf1e2a68f5bb93)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef _SYS_MD_RAID_H
27 #define	_SYS_MD_RAID_H
28 
29 #include <sys/lvm/mdvar.h>
30 #include <sys/lvm/md_rename.h>
31 
32 #ifdef	__cplusplus
33 extern "C" {
34 #endif
35 
36 
37 /*
38  * following bits are used in status word in the common section
39  * of unit structure: un_status
40  */
41 #define	RAID_UNMAGIC		0xBADBABE0
42 #define	RAID_PSMAGIC		0xBADBABE1
43 #define	RAID_CSMAGIC		0xBADBABE2
44 #define	RAID_PWMAGIC		0xBADBABE3
45 #define	RAID_BUFMAGIC		0xBADBABE4
46 /*
47  * These are the major constants for the definition of a raid device
48  */
49 #define	PWCNT_MIN	10	/* mininum # prewrites */
50 #define	PWCNT_MAX	100	/* maximum # prewrites */
51 #define	RAID_MIN_INTERLACE	(DEV_BSIZE * 2)
52 
53 #define	UNIT_STATE(un) ((un)->un_state)
54 #define	COLUMN_STATE(un, column) ((un)->un_column[(column)].un_devstate)
55 
56 #define	COLUMN_STATE_ONLY(un, column) (\
57 	((un)->un_column[(column)].un_devstate == RCS_INIT) || \
58 	((un)->un_column[(column)].un_devstate == RCS_OKAY) || \
59 	((un)->un_column[(column)].un_devstate == RCS_ERRED) || \
60 	((un)->un_column[(column)].un_devstate == RCS_RESYNC) || \
61 	((un)->un_column[(column)].un_devstate == RCS_LAST_ERRED) || \
62 	((un)->un_column[(column)].un_devstate == RCS_REGEN))
63 
64 #define	COLUMN_ISUP(un, column) (\
65 	((un)->un_column[(column)].un_devstate == RCS_OKAY) || \
66 	((un)->un_column[(column)].un_devstate == RCS_RESYNC) || \
67 	((un)->un_column[(column)].un_devstate == RCS_LAST_ERRED))
68 
69 #define	COLUMN_ISOKAY(un, column) (\
70 	((un)->un_column[(column)].un_devstate == RCS_OKAY))
71 
72 #define	COLUMN_ISLASTERR(un, column) (\
73 	((un)->un_column[(column)].un_devstate == RCS_LAST_ERRED))
74 
75 #define	WRITE_ALT(un, column) ( \
76 	((un)->un_column[(column)].un_alt_dev != NODEV64) && \
77 	(((un)->un_column[(column)].un_devflags & MD_RAID_WRITE_ALT)))
78 
79 #define	HOTSPARED(un, column) ( \
80 	((un)->un_column[(column)].un_hs_id != 0))
81 
82 #define	OVERLAPED(blk1, lblk1, blk2, lblk2) (				\
83 	(((blk1 > lblk2) ? 1 : 0) ||					\
84 	((lblk1 < blk2) ? 1 : 0)))
85 
86 
87 /*
88  * Note: magic is needed only to set rpw_magic, not rpw_magic_ext!
89  */
90 #define	RAID_FILLIN_RPW(buf, un, sum, colnum, 				\
91 			blkno, blkcnt, id,  				\
92 			colcount, col, magic) { 			\
93 	if ((un)->c.un_revision & MD_64BIT_META_DEV) { 		\
94 		raid_pwhdr_t *rpw64	= (raid_pwhdr_t *)(void *)(buf);\
95 		rpw64->rpw_magic	= magic;			\
96 		rpw64->rpw_sum		= sum;				\
97 		rpw64->rpw_columnnum	= colnum;			\
98 		rpw64->rpw_blkno	= (diskaddr_t)blkno;		\
99 		rpw64->rpw_blkcnt	= blkcnt;			\
100 		rpw64->rpw_id		= id;				\
101 		rpw64->rpw_colcount	= colcount;			\
102 		rpw64->rpw_column	= col;				\
103 		rpw64->rpw_unit		= MD_SID(un);			\
104 		rpw64->rpw_magic_ext	= RAID_PWMAGIC;			\
105 		rpw64->rpw_origcolumncnt  = (un)->un_origcolumncnt;	\
106 		rpw64->rpw_totalcolumncnt  = (un)->un_totalcolumncnt;	\
107 		rpw64->rpw_segsize	= (un)->un_segsize;		\
108 		rpw64->rpw_segsincolumn	= (diskaddr_t)((un)->un_segsincolumn);\
109 		rpw64->rpw_pwcnt	= (un)->un_pwcnt;		\
110 		rpw64->rpw_pwsize	= (un)->un_pwsize;		\
111 		rpw64->rpw_devstart	=				\
112 			(diskaddr_t)((un)->un_column[col].un_orig_devstart);\
113 		rpw64->rpw_pwstart	=				\
114 			(diskaddr_t)((un)->un_column[col].un_orig_pwstart);\
115 	} else { 							\
116 		raid_pwhdr32_od_t *rpw32 =				\
117 				(raid_pwhdr32_od_t *)(void *)(buf);	\
118 		rpw32->rpw_magic	= magic;			\
119 		rpw32->rpw_sum		= sum;				\
120 		rpw32->rpw_columnnum	= colnum;			\
121 		rpw32->rpw_blkno	= (daddr_t)blkno;		\
122 		rpw32->rpw_blkcnt	= blkcnt;			\
123 		rpw32->rpw_id		= id;				\
124 		rpw32->rpw_colcount	= colcount;			\
125 		rpw32->rpw_column	= col;				\
126 		rpw32->rpw_unit		= MD_SID(un);			\
127 		rpw32->rpw_magic_ext	= RAID_PWMAGIC;			\
128 		rpw32->rpw_origcolumncnt  = (un)->un_origcolumncnt;	\
129 		rpw32->rpw_totalcolumncnt = (un)->un_totalcolumncnt;	\
130 		rpw32->rpw_segsize	= (daddr_t)((un)->un_segsize);	\
131 		rpw32->rpw_segsincolumn	= (daddr_t)((un)->un_segsincolumn);\
132 		rpw32->rpw_pwcnt	= (un)->un_pwcnt;		\
133 		rpw32->rpw_pwsize	= (un)->un_pwsize;		\
134 		rpw32->rpw_devstart	=				\
135 			(daddr_t)((un)->un_column[col].un_orig_devstart);\
136 		rpw32->rpw_pwstart	=				\
137 			(daddr_t)((un)->un_column[col].un_orig_pwstart);\
138 	} 								\
139 }
140 
141 #define	RAID_CONVERT_RPW(rpw32, rpw64) { 				\
142 	(rpw64)->rpw_magic		= (rpw32)->rpw_magic;		\
143 	(rpw64)->rpw_sum		= (rpw32)->rpw_sum;		\
144 	(rpw64)->rpw_columnnum		= (rpw32)->rpw_columnnum;	\
145 	(rpw64)->rpw_blkno		= (rpw32)->rpw_blkno;		\
146 	(rpw64)->rpw_blkcnt		= (rpw32)->rpw_blkcnt;		\
147 	(rpw64)->rpw_id			= (rpw32)->rpw_id;		\
148 	(rpw64)->rpw_colcount		= (rpw32)->rpw_colcount;	\
149 	(rpw64)->rpw_column		= (rpw32)->rpw_column;		\
150 	(rpw64)->rpw_unit		= (rpw32)->rpw_unit;		\
151 	(rpw64)->rpw_magic_ext		= (rpw32)->rpw_magic_ext;	\
152 	(rpw64)->rpw_origcolumncnt	= (rpw32)->rpw_origcolumncnt;	\
153 	(rpw64)->rpw_totalcolumncnt	= (rpw32)->rpw_totalcolumncnt;	\
154 	(rpw64)->rpw_segsize		= (rpw32)->rpw_segsize;		\
155 	(rpw64)->rpw_segsincolumn	= (rpw32)->rpw_segsincolumn;	\
156 	(rpw64)->rpw_pwcnt		= (rpw32)->rpw_pwcnt;		\
157 	(rpw64)->rpw_pwsize		= (rpw32)->rpw_pwsize;		\
158 	(rpw64)->rpw_devstart		= (rpw32)->rpw_devstart;	\
159 	(rpw64)->rpw_pwstart		= (rpw32)->rpw_pwstart;		\
160 }
161 
162 typedef struct mr_scoreboard {
163 	int		sb_column;
164 	int		sb_flags;
165 	diskaddr_t	sb_start_blk;
166 	diskaddr_t	sb_last_blk;
167 	void		*sb_cs;
168 } mr_scoreboard_t;
169 
170 #define	SB_AVAIL	(0x00000001)	/* useable and valid blocks */
171 #define	SB_INUSE	(0x00000002)	/* being used */
172 #define	SB_UNUSED	(0x00000004)	/* useable and no valid blocks */
173 #define	SB_INVAL_PEND	(0x00000008)	/* being invalidated */
174 
175 typedef struct mr_pw_reserve {
176 	uint_t		pw_magic;
177 	int		pw_column;
178 	int		pw_free;
179 	mr_scoreboard_t	pw_sb[1];
180 } mr_pw_reserve_t;
181 
182 
183 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
184 #pragma pack(4)
185 #endif
186 typedef struct mr_column {
187 	rcs_state_t	un_devstate;
188 	rcs_flags_t	un_devflags;
189 	md_timeval32_t	un_devtimestamp; /* time of last state change, 32 bit */
190 
191 	mddb_recid_t	un_hs_id;
192 	diskaddr_t	un_hs_pwstart;
193 	diskaddr_t	un_hs_devstart;
194 	mdkey_t		un_hs_key;
195 
196 
197 	md_dev64_t	un_orig_dev;		/* original device, 64 bit */
198 	mdkey_t		un_orig_key;
199 	diskaddr_t	un_orig_pwstart;
200 	diskaddr_t	un_orig_devstart;
201 
202 	md_dev64_t	un_dev;			/* current read/write dev */
203 	diskaddr_t	un_pwstart;
204 	diskaddr_t	un_devstart;
205 
206 	md_dev64_t	un_alt_dev;		/* write to if resync */
207 	diskaddr_t	un_alt_pwstart;
208 	diskaddr_t	un_alt_devstart;
209 } mr_column_t;
210 
211 /*
212  * mr_column32_od is for old 32 bit format only
213  */
214 typedef struct mr_column32_od {
215 	rcs_state_t	un_devstate;
216 	rcs_flags_t	un_devflags;
217 	struct timeval32 un_devtimestamp;	/* time of last state change */
218 	caddr32_t	xx_un_pw_reserve;
219 
220 	mddb_recid_t	un_hs_id;
221 	daddr32_t	un_hs_pwstart;
222 	daddr32_t	un_hs_devstart;
223 	mdkey_t		un_hs_key;
224 
225 	dev32_t		un_orig_dev;	/* original device */
226 	mdkey_t		un_orig_key;
227 	daddr32_t	un_orig_pwstart;
228 	daddr32_t	un_orig_devstart;
229 
230 	dev32_t		un_dev;		/* current read/write dev */
231 	daddr32_t	un_pwstart;
232 	daddr32_t	un_devstart;
233 
234 	dev32_t		un_alt_dev;	/* write to if resync */
235 	daddr32_t	un_alt_pwstart;
236 	daddr32_t	un_alt_devstart;
237 } mr_column32_od_t;
238 
239 
240 /*
241  * Incore only elements structures
242  */
243 typedef struct mr_column_ic {
244 	mr_pw_reserve_t *un_pw_reserve;
245 } mr_column_ic_t;
246 
247 /*
248  * Do not rearrange elements as mutexes must be aligned on
249  * an 8 byte boundary. Element _t_un_linlck_mx corresponds to
250  * _t_un_linlck_cv and element _t_un_mx corresponds to _t_un_cv
251  */
252 typedef struct mr_unit_ic {
253 	caddr_t			_t_un_pbuffer;
254 	caddr_t			_t_un_dbuffer;
255 	struct md_raidcs	*_t_un_linlck_chn;
256 	kmutex_t		_t_un_linlck_mx;
257 	kmutex_t		_t_un_mx;
258 	kcondvar_t		_t_un_linlck_cv;
259 	kcondvar_t		_t_un_cv;
260 	mr_column_ic_t		*_t_un_column_ic;
261 } mr_unit_ic_t;
262 
263 typedef struct mr_unit {
264 	mdc_unit_t	c;
265 	int		un_raid_res;
266 	uint_t		un_magic;
267 	rus_state_t	un_state;
268 	md_timeval32_t	un_timestamp;	/* 32 bit fixed size */
269 	uint_t		un_origcolumncnt;
270 	uint_t		un_totalcolumncnt;
271 	uint_t		un_rflags;
272 	uint_t		un_segsize;
273 	diskaddr_t	un_segsincolumn;
274 	uint_t		un_maxio;	/* in blks */
275 	uint_t		un_iosize;	/* in blks */
276 	uint_t		un_linlck_flg;
277 	uint_t		un_pwcnt;
278 	uint_t		un_pwsize;
279 	long long	un_pwid;
280 	uint_t		un_percent_done;
281 	uint_t		un_resync_copysize;	/* in blks */
282 	hsp_t		un_hsp_id;
283 	/*
284 	 * This union has to begin at an 8 byte aligned address.
285 	 * If not, this structure has different sizes in 32 / 64 bit
286 	 * environments, since in a 64 bit environment the compiler
287 	 * adds paddings before a long long, if it doesn't start at an 8byte
288 	 * aligned address.
289 	 * Be careful if you add or remove structure elements before it!
290 	 */
291 
292 	union	{
293 		struct	{
294 			diskaddr_t	_t_un_resync_line_index;
295 			uint_t		_t_un_resync_segment;
296 			int		_t_un_resync_index;
297 		} _resync;
298 		struct	{
299 			diskaddr_t	_t_un_grow_tb;
300 			uint_t		_t_un_init_colcnt;
301 			u_longlong_t	_t_un_init_iocnt;
302 		} _init;
303 	} _t_un;
304 
305 	/*
306 	 * This union has to begin at an 8 byte aligned address.
307 	 * Be careful if you add or remove structure elements before it!
308 	 */
309 	union {
310 		mr_unit_ic_t	*_mr_ic;
311 		uint_t		_mr_ic_pad[2];
312 	} un_mr_ic;
313 
314 	mr_column_t	un_column[1];
315 } mr_unit_t;
316 
317 #define	mr_ic		un_mr_ic._mr_ic
318 #define	un_pbuffer	mr_ic->_t_un_pbuffer
319 #define	un_dbuffer	mr_ic->_t_un_dbuffer
320 #define	un_linlck_chn	mr_ic->_t_un_linlck_chn
321 #define	un_linlck_mx	mr_ic->_t_un_linlck_mx
322 #define	un_linlck_cv	mr_ic->_t_un_linlck_cv
323 #define	un_mx		mr_ic->_t_un_mx
324 #define	un_cv		mr_ic->_t_un_cv
325 #define	un_column_ic	mr_ic->_t_un_column_ic
326 
327 /*
328  * For old 32 bit format use only
329  */
330 typedef struct mr_unit32_od {
331 	mdc_unit32_od_t		c;
332 	caddr32_t		xx_un_raid_res;
333 	uint_t			un_magic;
334 	rus_state_t		un_state;
335 	struct timeval32	un_timestamp;
336 	uint_t			un_origcolumncnt;
337 	uint_t			un_totalcolumncnt;
338 	uint_t			un_rflags;
339 	uint_t			un_segsize;
340 	uint_t			un_segsincolumn;
341 	uint_t			un_maxio;
342 	uint_t			un_iosize;
343 	caddr32_t		xx_un_pbuffer;
344 	caddr32_t		xx_un_dbuffer;
345 	uint_t			un_linlck_flg;
346 	caddr32_t		xx_un_linlck_chn;
347 	uint_t			un_pwcnt;
348 	uint_t			un_pwsize;
349 	long long		un_pwid;
350 	uint_t			un_rebuild_size;
351 	uint_t			un_percent_done;
352 	union   {
353 		struct  {
354 			uint_t	_t_un_resync_segment;
355 			int	_t_un_resync_index;
356 			uint_t	 _t_un_resync_line_index;
357 		} _resync;
358 		struct  {
359 			daddr32_t _t_un_grow_tb;
360 			uint_t  _t_un_init_colcnt;
361 			uint_t  _t_un_init_iocnt;
362 		} _init;
363 	} _t_un;
364 	uint_t			un_resync_copysize;
365 
366 	/*
367 	 * This spot is 8 byte aligned!!!
368 	 * Don't change this arrangement.
369 	 */
370 	union {
371 		struct {
372 			mr_unit_ic_t *_t_mr_ic;
373 		} _mric;
374 		struct {
375 			uint_t xx_un_linlck_mx[2];
376 		} _lckmx;
377 	} _unic;
378 
379 	short			xx_un_linlck_cv;
380 	int			xx_un_mx[2];
381 	short			xx_un_cv;
382 	hsp_t			un_hsp_id;
383 	mr_column32_od_t	un_column[1];
384 } mr_unit32_od_t;
385 
386 typedef struct raid_pwhdr {
387 	uint_t		rpw_magic;
388 	uint_t		rpw_sum;
389 	int		rpw_columnnum;
390 	diskaddr_t	rpw_blkno;
391 	uint_t		rpw_blkcnt;
392 	long long	rpw_id;
393 	uint_t		rpw_colcount;
394 	uint_t		rpw_column;
395 	uint_t		rpw_unit;
396 	uint_t		rpw_magic_ext;
397 	uint_t		rpw_origcolumncnt;
398 	uint_t		rpw_totalcolumncnt;
399 	uint_t		rpw_segsize;
400 	diskaddr_t	rpw_segsincolumn;
401 	uint_t		rpw_pwcnt;
402 	uint_t		rpw_pwsize;
403 	diskaddr_t	rpw_devstart;
404 	diskaddr_t	rpw_pwstart;
405 	char 		rpw_filler[12];
406 } raid_pwhdr_t;
407 
408 /*
409  * For old 32 bit pre-write area
410  */
411 typedef struct raid_pwhdr32_od {
412 	uint_t		rpw_magic;
413 	uint_t		rpw_sum;
414 	int		rpw_columnnum;
415 	daddr32_t	rpw_blkno;
416 	daddr32_t	rpw_blkcnt;
417 	long long	rpw_id;
418 	uint_t		rpw_colcount;
419 	uint_t		rpw_column;
420 	uint_t		rpw_unit;
421 	uint_t		rpw_magic_ext;
422 	uint_t		rpw_origcolumncnt;
423 	uint_t		rpw_totalcolumncnt;
424 	uint_t		rpw_segsize;
425 	uint_t		rpw_segsincolumn;
426 	uint_t		rpw_pwcnt;
427 	uint_t		rpw_pwsize;
428 	uint_t		rpw_devstart;
429 	uint_t		rpw_pwstart;
430 	rus_state_t	rpw_unit_state;
431 	rcs_state_t	rpw_next_column_state;
432 	rcs_state_t	rpw_prev_column_state;
433 } raid_pwhdr32_od_t;
434 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
435 #pragma pack()
436 #endif
437 
438 #ifdef	_KERNEL
439 
440 /*
441  * the buffer header is only bp_mapin if it is needed.  It is needed on
442  * all writes and on some reads.  ps_mapin is non zero if the buffer is
443  * maped in.  ps_mapin_mx protect ps_mapin.  The protocol for usage is
444  *
445  * 1) check for non-zero and continue if non-zero
446  * 2) aquire the ps_mapin_mx
447  * 3) recheck for non-zero and continue if non-zero
448  * 4) bp_mapin
449  * 5) set ps_mapin to non-zero
450  * 6) drop ps_mapin_mx
451  *
452  * the reason for this is to avoid the mutex when possible.
453  */
454 typedef struct md_raidps {			/* raid parent save */
455 	DAEMON_QUEUE
456 	uint_t		ps_magic;
457 	mr_unit_t	*ps_un;
458 	mdi_unit_t	*ps_ui;
459 	buf_t		*ps_bp;
460 	caddr_t		ps_addr;
461 	int		ps_flags;
462 	int		ps_error;
463 	int		ps_frags;
464 	int		ps_pwfrags;
465 	int		ps_mapin;	/* buffer maped in if non zero */
466 	kmutex_t	ps_mx;
467 	kmutex_t	ps_mapin_mx;	/* protects ps_mapin */
468 } md_raidps_t;
469 
470 /* flags for parent save area */
471 
472 #define	MD_RPS_ERROR		0x0001
473 #define	MD_RPS_READ		0x0020
474 #define	MD_RPS_WRITE		0x0040
475 #define	MD_RPS_DONE		0x0080
476 #define	MD_RPS_INUSE		0x0100
477 #define	MD_RPS_IODONE		0x0200
478 #define	MD_RPS_HSREQ		0x0400
479 
480 /*
481  * used in cs_state to describe the type of io operation in progress
482  */
483 enum	raid_io_stage {
484 		RAID_NONE = 0x0,
485 		RAID_READ_DONE = 0x1,
486 		RAID_WRITE_DONE = 0x2,
487 		RAID_PREWRITE_DONE = 0x4,
488 		RAID_WRITE_PONLY_DONE = 0x8,
489 		RAID_WRITE_DONLY_DONE = 0x10,
490 		RAID_LINE_PWDONE = 0x20
491 };
492 
493 typedef struct md_raidcbuf {
494 	DAEMON_QUEUE
495 	uint_t			cbuf_magic;
496 	struct md_raidcbuf	*cbuf_next;		/* 0x10 */
497 	mr_unit_t		*cbuf_un;
498 	md_raidps_t		*cbuf_ps;
499 	int			cbuf_column;
500 	size_t			cbuf_bcount;		/* 0x20 */
501 	caddr_t			cbuf_buffer;
502 	int			cbuf_sum;
503 	int			cbuf_pwslot;
504 	int			cbuf_pwcnt;		/* 0x30 */
505 	int			cbuf_flags;
506 	buf_t			cbuf_bp;
507 	uint_t			cbuf_pad[4];
508 } md_raidcbuf_t;
509 #define	CBUF_PW_INVALIDATE	(0x00000001)
510 #define	CBUF_WRITE		(0x00000002)
511 
512 typedef struct md_raidcs {
513 	DAEMON_QUEUE
514 	uint_t			cs_magic;
515 	minor_t			cs_mdunit;
516 	mr_unit_t		*cs_un;
517 	int			cs_flags;
518 	md_raidps_t		*cs_ps;
519 	diskaddr_t		cs_line;
520 	void			(*cs_call)();
521 	void			(*cs_error_call)();
522 	void			(*cs_retry_call)();
523 	struct md_raidcs	*cs_linlck_next;
524 	struct md_raidcs	*cs_linlck_prev;
525 	long long		cs_pwid;
526 	int			cs_dcolumn;
527 	int			cs_dpwslot;
528 	uint_t			cs_dflags;
529 	int			cs_pcolumn;
530 	int			cs_ppwslot;
531 	uint_t			cs_pflags;
532 	size_t			cs_bcount;
533 	uint_t			cs_blkcnt;
534 	diskaddr_t		cs_blkno;
535 	diskaddr_t		cs_lastblk;
536 	int			cs_loop;
537 	caddr_t			cs_addr;	/* base address of io */
538 	off_t			cs_offset;	/* offset into the base */
539 	caddr_t			cs_dbuffer;
540 	caddr_t			cs_pbuffer;
541 	int			cs_frags;
542 	int			cs_strategy_flag;
543 	void			*cs_strategy_private;
544 	md_raidcbuf_t		*cs_buflist;
545 	int			cs_error;
546 	int			cs_resync_check;
547 	int			cs_rstate;
548 	enum raid_io_stage	cs_stage; 		/* current io stage */
549 	md_raidcbuf_t		*cs_pw_inval_list;
550 
551 	kmutex_t		cs_mx;
552 
553 	buf_t			cs_pbuf;
554 	uint_t			cs_pad1;
555 	buf_t			cs_hbuf;
556 	uint_t			cs_pad2;
557 	/* Add new structure members HERE!! */
558 	buf_t			cs_dbuf;
559 	/*  DO NOT add struture members here; cs_dbuf is dynamically sized */
560 } md_raidcs_t;
561 
562 /* value definitions for cs_resync_check */
563 #define	RCL_OKAY		0x01	/* write to both orig and alt */
564 #define	RCL_ERRED		0x08	/* treat column as rcs_ERRED */
565 
566 #define	RCL_DATA_MASK		0x000000ff
567 #define	RCL_PARITY_MASK		0x0000ff00
568 #define	RCL_PARITY_OFFSET	8	/* insure masks match offset */
569 
570 #define	RCL_PARITY(value)	(((value) & RCL_PARITY_MASK) >> \
571 				    RCL_PARITY_OFFSET)
572 
573 #define	RCL_DATA(value)		((value) & RCL_DATA_MASK)
574 
575 /* value definitions for cs_flags */
576 #define	MD_RCS_ISCALL		0x000001	/* call cs_call in interrupt */
577 #define	MD_RCS_UNDBUF		0x000002	/* holding unit data buffer */
578 #define	MD_RCS_UNPBUF		0x000004	/* holding unit parity buffer */
579 #define	MD_RCS_MPBUF		0x000008
580 #define	MD_RCS_HAVE_PW_SLOTS	0x000010	/* pw slots gotten */
581 #define	MD_RCS_PWDONE		0x000040	/* pwfrags are decremented */
582 #define	MD_RCS_READER		0x000100	/* reader line lock needed */
583 #define	MD_RCS_WRITER		0x000200	/* writer line lock needed */
584 #define	MD_RCS_LLOCKD		0x000400	/* line lock held */
585 #define	MD_RCS_WAITING		0x000800	/* line lock waiting */
586 #define	MD_RCS_LINE		0x001000	/* full line write */
587 #define	MD_RCS_ERROR		0x010000	/* I/O error on this child */
588 #define	MD_RCS_RECOVERY		0x020000
589 
590 /* value definitions for cs_pflags or cs_dflags */
591 #define	MD_RCS_ISUP		0x0002
592 
593 /* value definitions for gcs_flags */
594 #define	MD_RGCS_ALLOCBUF	0x0001
595 /* returned value from raid_replay() */
596 #define	RAID_RPLY_SUCCESS	0x0000
597 #define	RAID_RPLY_ALLOCFAIL	0x0001
598 #define	RAID_RPLY_COMPREPLAY	0x0002
599 #define	RAID_RPLY_READONLY	0x0004
600 #define	RAID_RPLY_EIO		0x0008
601 
602 typedef struct raid_rplybuf {
603 	caddr_t			rpl_data;
604 	buf_t			*rpl_buf;
605 } raid_rplybuf_t;
606 
607 typedef struct raid_rplylst {
608 	struct raid_rplylst	*rpl_next;
609 	uint_t			rpl_colcnt;
610 	long long		rpl_id;
611 	int			rpl_column1;
612 	uint_t			rpl_slot1;
613 	raid_pwhdr_t		rpl_pwhdr1;
614 	int			rpl_column2;
615 	uint_t			rpl_slot2;
616 	raid_pwhdr_t		rpl_pwhdr2;
617 } raid_rplylst_t;
618 
619 /* Externals from raid.c */
620 extern int	raid_build_incore(void *, int);
621 extern void	reset_raid(mr_unit_t *, minor_t, int);
622 
623 /* Externals from raid_ioctl.c */
624 extern int	md_raid_ioctl(dev_t dev, int cmd, void *data,
625 		    int mode, IOLOCK *lockp);
626 
627 /* rename named service functions */
628 md_ren_svc_t		raid_rename_check;
629 md_ren_svc_t		raid_rename_lock;
630 md_ren_void_svc_t	raid_rename_unlock;
631 
632 
633 /* redefinitions of the union shared by resync and init */
634 #define		un_resync_segment 	_t_un._resync._t_un_resync_segment
635 #define		un_resync_index		_t_un._resync._t_un_resync_index
636 #define		un_resync_line_index	_t_un._resync._t_un_resync_line_index
637 
638 #define		un_grow_tb 		_t_un._init._t_un_grow_tb
639 #define		un_init_colcnt		_t_un._init._t_un_init_colcnt
640 #define		un_init_iocnt		_t_un._init._t_un_init_iocnt
641 
642 #define	MD_RFLAG_NEEDBUF	(0x0001)
643 #define	MD_RFLAG_CLEAR		(0x0002)
644 #define	MD_RFLAG_KEEP		(0x0004)
645 #define	MD_RFLAG_NEEDPW		(0x0008)
646 
647 
648 extern void 		raid_set_state(mr_unit_t *un, int col,
649 			    rcs_state_t new_state, int force);
650 extern int		raid_replay(mr_unit_t *un);
651 extern void		raid_commit(mr_unit_t *un, mddb_recid_t *extras);
652 extern char		*raid_unit_state(rus_state_t state);
653 extern intptr_t		raid_hotspares();
654 extern void		raid_hs_release(hs_cmds_t cmd, mr_unit_t *un,
655 			    mddb_recid_t *recids, int hs_index);
656 extern int		raid_internal_open(minor_t mnum, int flag, int otyp,
657 			    int oflags);
658 extern int		raid_internal_close(minor_t mnum, int otyp,
659 			    int init_pw, int cflags);
660 extern int		raid_build_pwslot(mr_unit_t *unit, int column_index);
661 extern void		raid_free_pwslot(mr_unit_t *unit, int column_index);
662 extern void		release_resync_request(minor_t mnum);
663 extern int		resync_request(minor_t mnum, int column_index,
664 				size_t copysize, md_error_t *ep);
665 extern int		raid_resync_unit(minor_t mnum, md_error_t *ep);
666 extern void		raid_line_reader_lock(md_raidcs_t *cs,
667 			    int resync_thread);
668 extern void		raid_line_exit(md_raidcs_t *cs);
669 extern int		raid_state_cnt(mr_unit_t *un, rcs_state_t state);
670 extern int		raid_build_pw_reservation(mr_unit_t *un,
671 				int colindex);
672 extern int		init_pw_area(mr_unit_t *un, md_dev64_t dev_to_write,
673 			    diskaddr_t pwstart, uint_t col);
674 extern void		init_buf(buf_t *bp, int flags, size_t size);
675 extern void		destroy_buf(buf_t *bp);
676 extern void		reset_buf(buf_t *bp, int flags, size_t size);
677 extern void		md_raid_strategy(buf_t *pb, int flag, void *private);
678 extern void		raid_free_pw_reservation(mr_unit_t *un,
679 				int colindex);
680 extern void		raid_fillin_rpw(mr_unit_t *un,
681 				raid_pwhdr_t *pwhdrp, int col);
682 #endif  /* _KERNEL */
683 
684 #ifdef	__cplusplus
685 }
686 #endif
687 
688 #endif	/* _SYS_MD_RAID_H */
689