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