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