xref: /onnv-gate/usr/src/uts/common/sys/lvm/md_mirror.h (revision 8452:89d32dfdae6e)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
56901Sjkennedy  * Common Development and Distribution License (the "License").
66901Sjkennedy  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
21*8452SJohn.Wren.Kennedy@Sun.COM 
220Sstevel@tonic-gate /*
236901Sjkennedy  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #ifndef _SYS_MD_MIRROR_H
280Sstevel@tonic-gate #define	_SYS_MD_MIRROR_H
290Sstevel@tonic-gate 
300Sstevel@tonic-gate #include <sys/callb.h>
310Sstevel@tonic-gate #include <sys/lvm/mdvar.h>
320Sstevel@tonic-gate #include <sys/lvm/md_mirror_shared.h>
330Sstevel@tonic-gate #include <sys/lvm/md_rename.h>
34*8452SJohn.Wren.Kennedy@Sun.COM #ifdef	_KERNEL
35*8452SJohn.Wren.Kennedy@Sun.COM #include <sys/sunddi.h>
36*8452SJohn.Wren.Kennedy@Sun.COM #endif
370Sstevel@tonic-gate 
380Sstevel@tonic-gate #ifdef	__cplusplus
390Sstevel@tonic-gate extern "C" {
400Sstevel@tonic-gate #endif
410Sstevel@tonic-gate 
420Sstevel@tonic-gate /*
430Sstevel@tonic-gate  * following bits are used in status word in the common section
440Sstevel@tonic-gate  * of unit structure
450Sstevel@tonic-gate  */
460Sstevel@tonic-gate #define	SMS_IS(sm, state) (((sm)->sm_state & (state)) != 0)
470Sstevel@tonic-gate #define	SMS_BY_INDEX_IS(un, index, state) \
480Sstevel@tonic-gate 		(((un)->un_sm[(index)].sm_state & (state)) != 0)
490Sstevel@tonic-gate 
500Sstevel@tonic-gate #define	SMS_BY_INDEX_IS_TARGET(un, index) \
510Sstevel@tonic-gate 		((un)->un_sm[(index)].sm_flags & MD_SM_RESYNC_TARGET)
520Sstevel@tonic-gate 
530Sstevel@tonic-gate #define	SUBMIRROR_IS_READABLE(un, isubmirror)				\
540Sstevel@tonic-gate 	((((un)->un_sm[(isubmirror)].sm_state & SMS_IGNORE) == 0) &&	\
550Sstevel@tonic-gate 	    ((un)->un_sm[(isubmirror)].sm_state & 			\
560Sstevel@tonic-gate 	    (SMS_RUNNING | SMS_COMP_ERRED | SMS_COMP_RESYNC)))
570Sstevel@tonic-gate 
580Sstevel@tonic-gate #define	SUBMIRROR_IS_WRITEABLE(un, isubmirror)			\
590Sstevel@tonic-gate 	((un)->un_sm[(isubmirror)].sm_state &			\
600Sstevel@tonic-gate 	    (SMS_RUNNING | SMS_COMP_ERRED | SMS_COMP_RESYNC |	\
610Sstevel@tonic-gate 	    SMS_ATTACHED_RESYNC | SMS_OFFLINE_RESYNC))
620Sstevel@tonic-gate 
630Sstevel@tonic-gate /*
640Sstevel@tonic-gate  * Default resync block size for MN resync messages
650Sstevel@tonic-gate  */
660Sstevel@tonic-gate #define	MD_DEF_RESYNC_BLK_SZ		8192
670Sstevel@tonic-gate 
680Sstevel@tonic-gate /*
690Sstevel@tonic-gate  * macro to test if the current block is within the current resync region
700Sstevel@tonic-gate  */
710Sstevel@tonic-gate #define	IN_RESYNC_REGION(un, ps) \
726901Sjkennedy 	((un->un_rs_prev_overlap != NULL) && (ps->ps_firstblk >= \
736901Sjkennedy 	    un->un_rs_prev_overlap->ps_firstblk) && \
746901Sjkennedy 	    (ps->ps_lastblk <=  un->un_rs_prev_overlap->ps_lastblk))
750Sstevel@tonic-gate /*
760Sstevel@tonic-gate  * Default resync update interval (in minutes).
770Sstevel@tonic-gate  */
780Sstevel@tonic-gate #define	MD_DEF_MIRROR_RESYNC_INTVL	5
790Sstevel@tonic-gate 
800Sstevel@tonic-gate /*
810Sstevel@tonic-gate  * Defines for flags argument in function set_sm_comp_state()
820Sstevel@tonic-gate  */
830Sstevel@tonic-gate #define	MD_STATE_NO_XMIT	0x0000 /* Local action, (sent from master) */
840Sstevel@tonic-gate #define	MD_STATE_XMIT		0x0001 /* Non-local action, send to master */
850Sstevel@tonic-gate #define	MD_STATE_WMUPDATE	0x0002 /* Action because of watermark update */
860Sstevel@tonic-gate #define	MD_STATE_OCHELD		0x0004 /* open/close lock held */
870Sstevel@tonic-gate 
880Sstevel@tonic-gate /*
890Sstevel@tonic-gate  * Defines for flags argument in function check_comp_4_hotspares()
900Sstevel@tonic-gate  */
910Sstevel@tonic-gate #define	MD_HOTSPARE_NO_XMIT	0x0000 /* Local action, (sent from master) */
920Sstevel@tonic-gate #define	MD_HOTSPARE_XMIT	0x0001 /* Non-local action, send to master */
930Sstevel@tonic-gate #define	MD_HOTSPARE_WMUPDATE	0x0002 /* Action because of watermark update */
940Sstevel@tonic-gate #define	MD_HOTSPARE_LINKHELD	0x0004 /* md_link_rw lock held */
950Sstevel@tonic-gate 
960Sstevel@tonic-gate /*
970Sstevel@tonic-gate  * Defines for argument in function send_mn_resync_done_message()
980Sstevel@tonic-gate  */
990Sstevel@tonic-gate #define	RESYNC_ERR		0x1
1000Sstevel@tonic-gate #define	CLEAR_OPT_NOT_DONE	0x2
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate /*
1030Sstevel@tonic-gate  * Defines for argument in function resync_read_blk_range()
1040Sstevel@tonic-gate  */
1050Sstevel@tonic-gate #define	MD_FIRST_RESYNC_NEXT	0x1
1060Sstevel@tonic-gate #define	MD_SEND_MESS_XMIT	0x2
1070Sstevel@tonic-gate #define	MD_RESYNC_FLAG_ERR	0x4
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate /*
1100Sstevel@tonic-gate  * Define for argument in function wait_for_overlaps()
1110Sstevel@tonic-gate  */
1126901Sjkennedy #define	MD_OVERLAP_ALLOW_REPEAT	0x1	/* Allow if ps already in tree */
1136901Sjkennedy #define	MD_OVERLAP_NO_REPEAT	0	/* ps must not already be in tree */
1140Sstevel@tonic-gate 
1150Sstevel@tonic-gate /*
1160Sstevel@tonic-gate  * Define for max retries of mirror_owner
1170Sstevel@tonic-gate  */
1180Sstevel@tonic-gate #define	MD_OWNER_RETRIES	10
1190Sstevel@tonic-gate 
1200Sstevel@tonic-gate /*
1210Sstevel@tonic-gate  * mm_submirror32_od and mm_unit32_od are used only for 32 bit old format
1220Sstevel@tonic-gate  */
1230Sstevel@tonic-gate #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
1240Sstevel@tonic-gate #pragma pack(4)
1250Sstevel@tonic-gate #endif
1260Sstevel@tonic-gate typedef struct  mm_submirror32_od {	/* submirrors */
1270Sstevel@tonic-gate 	mdkey_t		sm_key;
1280Sstevel@tonic-gate 	dev32_t		sm_dev;
1290Sstevel@tonic-gate 	sm_state_t	sm_state;
1300Sstevel@tonic-gate 	sm_flags_t	sm_flags;
1310Sstevel@tonic-gate 	caddr32_t	xx_sm_shared_by_blk;	/* really void *) */
1320Sstevel@tonic-gate 	caddr32_t	xx_sm_shared_by_indx;	/* really void *) */
1330Sstevel@tonic-gate 	caddr32_t	xx_sm_get_component_count;
1340Sstevel@tonic-gate 	caddr32_t	xx_sm_get_bcss;	/* block count skip size */
1350Sstevel@tonic-gate 	md_m_shared32_od_t sm_shared;	/* used for mirroring plain devices */
1360Sstevel@tonic-gate 	int		sm_hsp_id;	/* used for mirroring plain devices */
1370Sstevel@tonic-gate 	struct timeval32 sm_timestamp;	/* time of last state change */
1380Sstevel@tonic-gate } mm_submirror32_od_t;
1390Sstevel@tonic-gate 
1400Sstevel@tonic-gate typedef struct	mm_submirror {		/* submirrors */
1410Sstevel@tonic-gate 	mdkey_t		sm_key;
1420Sstevel@tonic-gate 	md_dev64_t	sm_dev;		/* 64 bit */
1430Sstevel@tonic-gate 	sm_state_t	sm_state;
1440Sstevel@tonic-gate 	sm_flags_t	sm_flags;
1450Sstevel@tonic-gate 	md_m_shared_t	sm_shared;	/* used for mirroring plain devices */
1460Sstevel@tonic-gate 	int		sm_hsp_id;	/* used for mirroring plain devices */
1470Sstevel@tonic-gate 	md_timeval32_t	sm_timestamp;	/* time of last state change, 32 bit */
1480Sstevel@tonic-gate } mm_submirror_t;
1490Sstevel@tonic-gate 
1500Sstevel@tonic-gate typedef struct mm_unit32_od {
1510Sstevel@tonic-gate 	mdc_unit32_od_t	c;			/* common stuff */
1520Sstevel@tonic-gate 
1530Sstevel@tonic-gate 	int		un_last_read;		/* last submirror index read */
1540Sstevel@tonic-gate 	uint_t		un_changecnt;
1550Sstevel@tonic-gate 	ushort_t	un_nsm;			/* number of submirrors */
1560Sstevel@tonic-gate 	mm_submirror32_od_t un_sm[NMIRROR];
1576901Sjkennedy 	int		un_overlap_tree_flag;
1586901Sjkennedy 	int		xx_un_overlap_tree_mx[2];	/* replaces mutex */
1596901Sjkennedy 	ushort_t	xx_un_overlap_tree_cv;
1606901Sjkennedy 	caddr32_t	xx_un_overlap_root;
1610Sstevel@tonic-gate 	mm_rd_opt_t	un_read_option;		/* mirror read option */
1620Sstevel@tonic-gate 	mm_wr_opt_t	un_write_option;	/* mirror write option */
1630Sstevel@tonic-gate 	mm_pass_num_t	un_pass_num;		/* resync pass number */
1640Sstevel@tonic-gate 	/*
1650Sstevel@tonic-gate 	 * following used to keep dirty bitmaps
1660Sstevel@tonic-gate 	 */
1670Sstevel@tonic-gate 	int		xx_un_resync_mx[2];	/* replaces mutex */
1680Sstevel@tonic-gate 	ushort_t	xx_un_resync_cv;
1690Sstevel@tonic-gate 	uint_t		un_resync_flg;
1700Sstevel@tonic-gate 	uint_t		un_waiting_to_mark;
1710Sstevel@tonic-gate 	uint_t		un_waiting_to_commit;
1720Sstevel@tonic-gate 	caddr32_t	xx_un_outstanding_writes;	/* outstanding write */
1730Sstevel@tonic-gate 	caddr32_t	xx_un_goingclean_bm;
1740Sstevel@tonic-gate 	caddr32_t	xx_un_goingdirty_bm;
1750Sstevel@tonic-gate 	caddr32_t	xx_un_dirty_bm;
1760Sstevel@tonic-gate 	caddr32_t	xx_un_resync_bm;
1770Sstevel@tonic-gate 	uint_t		un_rrd_blksize;	/* The blocksize of the dirty bits */
1780Sstevel@tonic-gate 	uint_t		un_rrd_num;	/* The number of resync regions */
1790Sstevel@tonic-gate 	mddb_recid_t	un_rr_dirty_recid;	/* resync region bm record id */
1800Sstevel@tonic-gate 	/*
1810Sstevel@tonic-gate 	 * following stuff is private to resync process
1820Sstevel@tonic-gate 	 */
1830Sstevel@tonic-gate 	int		un_rs_copysize;
1840Sstevel@tonic-gate 	int		un_rs_dests;	/* destinations */
1850Sstevel@tonic-gate 	daddr32_t	un_rs_resync_done;	/* used for percent done */
1860Sstevel@tonic-gate 	daddr32_t	un_rs_resync_2_do;	/* user for percent done */
1870Sstevel@tonic-gate 	int		un_rs_dropped_lock;
1880Sstevel@tonic-gate 	caddr32_t	un_rs_type;		/* type of resync in progress */
1890Sstevel@tonic-gate 	/*
1900Sstevel@tonic-gate 	 * Incore elements in this old structure are no longer referenced by
1910Sstevel@tonic-gate 	 * current 64 bit kernel.  Comment them out for maintenance purpose.
1920Sstevel@tonic-gate 	 *
1930Sstevel@tonic-gate 	 * 	mm_submirror_ic_t	un_smic[NMIRROR];
1940Sstevel@tonic-gate 	 * 	kmutex_t		un_ovrlap_chn_mx;
1950Sstevel@tonic-gate 	 * 	kcondvar_t		un_ovrlap_chn_cv;
1960Sstevel@tonic-gate 	 * 	struct md_mps		*un_ovrlap_chn;
1970Sstevel@tonic-gate 	 * 	kmutex_t		un_resync_mx;
1980Sstevel@tonic-gate 	 * 	kcondvar_t		un_resync_cv;
1990Sstevel@tonic-gate 	 * 	short			*un_outstanding_writes;
2000Sstevel@tonic-gate 	 * 	uchar_t			*un_goingclean_bm;
2010Sstevel@tonic-gate 	 * 	uchar_t			*un_goingdirty_bm;
2020Sstevel@tonic-gate 	 * 	uchar_t			*un_dirty_bm;
2030Sstevel@tonic-gate 	 * 	uchar_t			*un_resync_bm;
2040Sstevel@tonic-gate 	 * 	char			*un_rs_buffer;
2050Sstevel@tonic-gate 	 */
2060Sstevel@tonic-gate } mm_unit32_od_t;
2070Sstevel@tonic-gate #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
2080Sstevel@tonic-gate #pragma pack()
2090Sstevel@tonic-gate #endif
2100Sstevel@tonic-gate 
2110Sstevel@tonic-gate /* Types of resync in progress (used for un_rs_type) */
2120Sstevel@tonic-gate #define	MD_RS_NONE		0		/* No resync */
2130Sstevel@tonic-gate #define	MD_RS_OPTIMIZED		0x0001		/* Optimized resync */
2140Sstevel@tonic-gate #define	MD_RS_COMPONENT		0x0002		/* Component resync */
2150Sstevel@tonic-gate #define	MD_RS_SUBMIRROR		0x0003		/* Submirror resync */
2160Sstevel@tonic-gate #define	MD_RS_ABR		0x0004		/* Application based resync */
2170Sstevel@tonic-gate 
2180Sstevel@tonic-gate /*
2190Sstevel@tonic-gate  * un_rs_type is split into the following bitfields:
2200Sstevel@tonic-gate  *
2210Sstevel@tonic-gate  * 0-3	Resync type (as above)
2220Sstevel@tonic-gate  * 4-7	Submirror index [0..3]
2230Sstevel@tonic-gate  * 8-31	Component index
2240Sstevel@tonic-gate  */
2250Sstevel@tonic-gate #define	RS_TYPE_MASK	0xF
2260Sstevel@tonic-gate #define	RS_SMI_MASK	0xF0
2270Sstevel@tonic-gate #define	RS_CI_MASK	0x1FFF00
2280Sstevel@tonic-gate 
2290Sstevel@tonic-gate #define	RS_TYPE(x)	((x) & RS_TYPE_MASK)
2300Sstevel@tonic-gate #define	RS_SMI(x)	(((x) & RS_SMI_MASK) >> 4)
2310Sstevel@tonic-gate #define	RS_CI(x)	(((x) & RS_CI_MASK) >> 8)
2320Sstevel@tonic-gate 
2330Sstevel@tonic-gate #define	SET_RS_TYPE(x, v)	{					\
2340Sstevel@tonic-gate 				    (x) &= ~RS_TYPE_MASK;		\
2350Sstevel@tonic-gate 				    (x) |= ((v) & RS_TYPE_MASK);	\
2360Sstevel@tonic-gate 				}
2370Sstevel@tonic-gate #define	SET_RS_TYPE_NONE(x)	{					\
2380Sstevel@tonic-gate 				    (x) &= ~RS_TYPE_MASK;		\
2390Sstevel@tonic-gate 				}
2400Sstevel@tonic-gate #define	SET_RS_SMI(x, v)	{					\
2410Sstevel@tonic-gate 				    (x) &= ~RS_SMI_MASK; 		\
2420Sstevel@tonic-gate 				    (x) |= (((v) << 4) & RS_SMI_MASK);	\
2430Sstevel@tonic-gate 				}
2440Sstevel@tonic-gate #define	SET_RS_CI(x, v)		{					\
2450Sstevel@tonic-gate 				    (x) &= ~RS_CI_MASK;			\
2460Sstevel@tonic-gate 				    (x) |= (((v) << 8) & RS_CI_MASK);	\
2470Sstevel@tonic-gate 				}
2480Sstevel@tonic-gate 
2490Sstevel@tonic-gate typedef struct	mm_submirror_ic {
2500Sstevel@tonic-gate 	intptr_t	(*sm_shared_by_blk)(md_dev64_t, void *,
2510Sstevel@tonic-gate 				diskaddr_t, u_longlong_t *);
2520Sstevel@tonic-gate 	intptr_t	(*sm_shared_by_indx)(md_dev64_t, void *, int);
2530Sstevel@tonic-gate 	int		(*sm_get_component_count)(md_dev64_t, void *);
2540Sstevel@tonic-gate 	int		(*sm_get_bcss)(md_dev64_t, void *, int, diskaddr_t *,
2550Sstevel@tonic-gate 				size_t *, u_longlong_t *, u_longlong_t *);
2560Sstevel@tonic-gate } mm_submirror_ic_t;
2570Sstevel@tonic-gate 
2580Sstevel@tonic-gate typedef struct md_mps {
2590Sstevel@tonic-gate 	DAEMON_QUEUE
2600Sstevel@tonic-gate 	buf_t		*ps_bp;
2610Sstevel@tonic-gate 	struct mm_unit	*ps_un;
2620Sstevel@tonic-gate 	mdi_unit_t	*ps_ui;
2630Sstevel@tonic-gate 	uint_t		 ps_childbflags;
2640Sstevel@tonic-gate 	caddr_t		 ps_addr;
2650Sstevel@tonic-gate 	diskaddr_t	 ps_firstblk;
2660Sstevel@tonic-gate 	diskaddr_t	 ps_lastblk;
2670Sstevel@tonic-gate 	uint_t		 ps_flags;
2680Sstevel@tonic-gate 	uint_t		 ps_allfrom_sm;		/* entire read came from here */
2690Sstevel@tonic-gate 	uint_t		 ps_writable_sm;
2700Sstevel@tonic-gate 	uint_t		 ps_current_sm;
2710Sstevel@tonic-gate 	uint_t		 ps_active_cnt;
2720Sstevel@tonic-gate 	int		 ps_frags;
2730Sstevel@tonic-gate 	uint_t		 ps_changecnt;
2746901Sjkennedy 	struct md_mps	*ps_unused1;
2756901Sjkennedy 	struct md_mps	*ps_unused2;
2760Sstevel@tonic-gate 	void		 (*ps_call)();
2770Sstevel@tonic-gate 	kmutex_t	 ps_mx;
2786901Sjkennedy 	avl_node_t	ps_overlap_node;
2790Sstevel@tonic-gate } md_mps_t;
2800Sstevel@tonic-gate 
2810Sstevel@tonic-gate #define	MD_MPS_ON_OVERLAP	0x0001
2820Sstevel@tonic-gate #define	MD_MPS_ERROR		0x0002
2830Sstevel@tonic-gate #define	MD_MPS_WRITE_AFTER_READ	0x0004
2840Sstevel@tonic-gate #define	MD_MPS_WOW		0x0008
2850Sstevel@tonic-gate #define	MD_MPS_DONTFREE		0x0010
2860Sstevel@tonic-gate #define	MD_MPS_DONE		0x0020
2870Sstevel@tonic-gate #define	MD_MPS_MAPPED		0x0040		/* re: MD_STR_MAPPED	*/
2880Sstevel@tonic-gate #define	MD_MPS_NOBLOCK		0x0080		/* re: MD_NOBLOCK	*/
2890Sstevel@tonic-gate #define	MD_MPS_ABR		0x0100		/* re: MD_STR_ABR	*/
2900Sstevel@tonic-gate #define	MD_MPS_DMR		0x0200		/* re: MD_STR_DMR	*/
2910Sstevel@tonic-gate #define	MD_MPS_WMUPDATE		0x0400		/* re: MD_STR_WMUPDATE	*/
2920Sstevel@tonic-gate #define	MD_MPS_DIRTY_RD		0x0800		/* re: MD_STR_DIRTY_RD	*/
2930Sstevel@tonic-gate #define	MD_MPS_RESYNC_READ	0x1000
2940Sstevel@tonic-gate #define	MD_MPS_FLAG_ERROR	0x2000		/* re: MD_STR_FLAG_ERR	*/
2957975SAchim.Maurer@Sun.COM #define	MD_MPS_BLOCKABLE_IO	0x4000		/* re: MD_STR_BLOCK_OK  */
2960Sstevel@tonic-gate 
2970Sstevel@tonic-gate #define	MPS_FREE(kc, ps)			\
2980Sstevel@tonic-gate {						\
2990Sstevel@tonic-gate 	if ((ps)->ps_flags & MD_MPS_DONTFREE)	\
3000Sstevel@tonic-gate 		(ps)->ps_flags |= MD_MPS_DONE;	\
3010Sstevel@tonic-gate 	else					\
3020Sstevel@tonic-gate 		kmem_cache_free((kc), (ps));	\
3030Sstevel@tonic-gate }
3040Sstevel@tonic-gate 
3050Sstevel@tonic-gate typedef struct md_mcs {
3060Sstevel@tonic-gate 	DAEMON_QUEUE
3070Sstevel@tonic-gate 	md_mps_t	*cs_ps;
3080Sstevel@tonic-gate 	minor_t		 cs_mdunit;
3090Sstevel@tonic-gate 	/* Add new structure members HERE!! */
3100Sstevel@tonic-gate 	buf_t		 cs_buf;
3110Sstevel@tonic-gate 	/*  DO NOT add structure members here; cs_buf is dynamically sized */
3120Sstevel@tonic-gate } md_mcs_t;
3130Sstevel@tonic-gate 
3140Sstevel@tonic-gate typedef struct  mm_mirror_ic {
3156901Sjkennedy 	kmutex_t	un_overlap_tree_mx;
3166901Sjkennedy 	kcondvar_t	un_overlap_tree_cv;
3176901Sjkennedy 	avl_tree_t	un_overlap_root;
3180Sstevel@tonic-gate 	kmutex_t	un_resync_mx;
3190Sstevel@tonic-gate 	kcondvar_t	un_resync_cv;
3200Sstevel@tonic-gate 	short		*un_outstanding_writes; /* outstanding write array */
3210Sstevel@tonic-gate 	uchar_t		*un_goingclean_bm;
3220Sstevel@tonic-gate 	uchar_t		*un_goingdirty_bm;
3230Sstevel@tonic-gate 	uchar_t		*un_dirty_bm;
3240Sstevel@tonic-gate 	uchar_t		*un_resync_bm;
3250Sstevel@tonic-gate 	char		*un_rs_buffer;
3260Sstevel@tonic-gate 	int		un_suspend_wr_flag;
3270Sstevel@tonic-gate 	kmutex_t	un_suspend_wr_mx;
3280Sstevel@tonic-gate 	kcondvar_t	un_suspend_wr_cv;
3290Sstevel@tonic-gate 	md_mn_nodeid_t	un_mirror_owner;	/* Node which owns mirror */
3300Sstevel@tonic-gate 	diskaddr_t	un_resync_startbl;	/* Start block for resync */
3310Sstevel@tonic-gate 	kmutex_t	un_owner_mx;		/* Mutex for un_owner_state */
3320Sstevel@tonic-gate 	uint_t		un_owner_state;		/* See below */
3330Sstevel@tonic-gate 	uint_t		un_mirror_owner_status;	/* status for ioctl request */
3340Sstevel@tonic-gate 	kmutex_t	un_dmr_mx;		/* mutex for DMR requests */
3350Sstevel@tonic-gate 	kcondvar_t	un_dmr_cv;		/* condvar for DMR requests */
3360Sstevel@tonic-gate 	int		un_dmr_last_read;	/* last DMR submirror read */
3370Sstevel@tonic-gate 	callb_cpr_t	un_rs_cprinfo;		/* CPR info for resync thread */
338*8452SJohn.Wren.Kennedy@Sun.COM 	kmutex_t	un_rs_cpr_mx;		/* mutex for resync CPR info */
339*8452SJohn.Wren.Kennedy@Sun.COM 	kmutex_t	un_prr_cpr_mx;		/* mutex for prr CPR info */
3400Sstevel@tonic-gate 	uint_t		un_resync_completed;	/* type of last resync */
3410Sstevel@tonic-gate 	int		un_abr_count;		/* count of sp's with abr set */
342*8452SJohn.Wren.Kennedy@Sun.COM 
343*8452SJohn.Wren.Kennedy@Sun.COM 	uchar_t		*un_pernode_dirty_bm[MD_MNMAXSIDES];
344*8452SJohn.Wren.Kennedy@Sun.COM 	uchar_t		*un_pernode_dirty_sum;
345*8452SJohn.Wren.Kennedy@Sun.COM 
346*8452SJohn.Wren.Kennedy@Sun.COM 	krwlock_t	un_pernode_dirty_mx[MD_MNMAXSIDES];
347*8452SJohn.Wren.Kennedy@Sun.COM 	ushort_t	un_rr_clean_start_bit;  /* where to start next clean */
348*8452SJohn.Wren.Kennedy@Sun.COM 
349*8452SJohn.Wren.Kennedy@Sun.COM #ifdef	_KERNEL
350*8452SJohn.Wren.Kennedy@Sun.COM 	ddi_taskq_t	*un_drl_task;		/* deferred RR_CLEAN taskq */
351*8452SJohn.Wren.Kennedy@Sun.COM #else
352*8452SJohn.Wren.Kennedy@Sun.COM 	void		*un_drl_task;		/* deferred RR_CLEAN taskq */
353*8452SJohn.Wren.Kennedy@Sun.COM #endif	/* _KERNEL */
354*8452SJohn.Wren.Kennedy@Sun.COM 	uint_t		un_waiting_to_clear;	/* Blocked waiting to clear */
355*8452SJohn.Wren.Kennedy@Sun.COM 
3560Sstevel@tonic-gate }mm_mirror_ic_t;
3570Sstevel@tonic-gate 
3580Sstevel@tonic-gate #define	MM_MN_OWNER_SENT	0x0001		/* RPC in progress */
3590Sstevel@tonic-gate #define	MM_MN_BECOME_OWNER	0x0002		/* Ownership change in prog. */
3600Sstevel@tonic-gate #define	MM_MN_PREVENT_CHANGE	0x0004		/* Disallow ownership change */
3610Sstevel@tonic-gate 
3620Sstevel@tonic-gate typedef struct mm_unit {
3630Sstevel@tonic-gate 	mdc_unit_t	c;			/* common stuff */
3640Sstevel@tonic-gate 
3650Sstevel@tonic-gate 	int		un_last_read;		/* last submirror index read */
3660Sstevel@tonic-gate 	uint_t		un_changecnt;
3670Sstevel@tonic-gate 	ushort_t	un_nsm;			/* number of submirrors */
3680Sstevel@tonic-gate 	mm_submirror_t	un_sm[NMIRROR];
3696901Sjkennedy 	int		un_overlap_tree_flag;
3700Sstevel@tonic-gate 	mm_rd_opt_t	un_read_option;		/* mirror read option */
3710Sstevel@tonic-gate 	mm_wr_opt_t	un_write_option;	/* mirror write option */
3720Sstevel@tonic-gate 	mm_pass_num_t	un_pass_num;		/* resync pass number */
3730Sstevel@tonic-gate 	/*
3740Sstevel@tonic-gate 	 * following used to keep dirty bitmaps
3750Sstevel@tonic-gate 	 */
3760Sstevel@tonic-gate 	uint_t		un_resync_flg;
3770Sstevel@tonic-gate 	uint_t		un_waiting_to_mark;
3780Sstevel@tonic-gate 	uint_t		un_waiting_to_commit;
3790Sstevel@tonic-gate 	uint_t		un_rrd_blksize;	  /* The blocksize of the dirty bits */
3800Sstevel@tonic-gate 	uint_t		un_rrd_num;	  /* The number of resync regions */
3810Sstevel@tonic-gate 	mddb_recid_t	un_rr_dirty_recid; /* resync region bm db record id */
3820Sstevel@tonic-gate 	/*
3830Sstevel@tonic-gate 	 * following stuff is private to resync process
3840Sstevel@tonic-gate 	 */
3850Sstevel@tonic-gate 	int 		un_rs_copysize;
3860Sstevel@tonic-gate 	int 		un_rs_dests;		/* destinations */
3870Sstevel@tonic-gate 	diskaddr_t	un_rs_resync_done;	/* used for percent done */
3880Sstevel@tonic-gate 	diskaddr_t	un_rs_resync_2_do;	/* user for percent done */
3890Sstevel@tonic-gate 	int		un_rs_dropped_lock;
3900Sstevel@tonic-gate 	uint_t		un_rs_type;		/* type of resync */
3910Sstevel@tonic-gate 	/*
3920Sstevel@tonic-gate 	 * Incore only elements
3930Sstevel@tonic-gate 	 */
3940Sstevel@tonic-gate 	mm_submirror_ic_t un_smic[NMIRROR];	/* NMIRROR elements array */
3950Sstevel@tonic-gate 	mm_mirror_ic_t	un_mmic;
3960Sstevel@tonic-gate 	kmutex_t	un_rrp_inflight_mx;
3970Sstevel@tonic-gate 	/*
3980Sstevel@tonic-gate 	 * resync thread control
3990Sstevel@tonic-gate 	 */
4000Sstevel@tonic-gate 	kthread_t	*un_rs_thread;		/* Resync thread ID */
4010Sstevel@tonic-gate 	kmutex_t	un_rs_thread_mx;	/* Thread cv mutex */
4020Sstevel@tonic-gate 	kcondvar_t	un_rs_thread_cv;	/* Cond. Var. for thread */
4030Sstevel@tonic-gate 	uint_t		un_rs_thread_flags;	/* Thread control flags */
4046901Sjkennedy 	md_mps_t	*un_rs_prev_overlap;	/* existing overlap request */
4050Sstevel@tonic-gate 	timeout_id_t	un_rs_resync_to_id;	/* resync progress timeout */
4060Sstevel@tonic-gate 	kmutex_t	un_rs_progress_mx;	/* Resync progress mutex */
4070Sstevel@tonic-gate 	kcondvar_t	un_rs_progress_cv;	/* Cond. Var. for progress */
4080Sstevel@tonic-gate 	uint_t		un_rs_progress_flags;	/* Thread control flags */
4090Sstevel@tonic-gate 	void		*un_rs_msg;		/* Intra-node resync message */
4100Sstevel@tonic-gate } mm_unit_t;
4110Sstevel@tonic-gate 
4126901Sjkennedy #define	un_overlap_tree_mx	un_mmic.un_overlap_tree_mx
4136901Sjkennedy #define	un_overlap_tree_cv	un_mmic.un_overlap_tree_cv
4146901Sjkennedy #define	un_overlap_root		un_mmic.un_overlap_root
4150Sstevel@tonic-gate #define	un_resync_mx		un_mmic.un_resync_mx
4160Sstevel@tonic-gate #define	un_resync_cv		un_mmic.un_resync_cv
4170Sstevel@tonic-gate #define	un_outstanding_writes	un_mmic.un_outstanding_writes
4180Sstevel@tonic-gate #define	un_goingclean_bm	un_mmic.un_goingclean_bm
4190Sstevel@tonic-gate #define	un_goingdirty_bm	un_mmic.un_goingdirty_bm
4200Sstevel@tonic-gate #define	un_dirty_bm		un_mmic.un_dirty_bm
4210Sstevel@tonic-gate #define	un_resync_bm		un_mmic.un_resync_bm
4220Sstevel@tonic-gate #define	un_rs_buffer		un_mmic.un_rs_buffer
4230Sstevel@tonic-gate #define	un_suspend_wr_mx	un_mmic.un_suspend_wr_mx
4240Sstevel@tonic-gate #define	un_suspend_wr_cv	un_mmic.un_suspend_wr_cv
4250Sstevel@tonic-gate #define	un_suspend_wr_flag	un_mmic.un_suspend_wr_flag
4260Sstevel@tonic-gate #define	un_mirror_owner		un_mmic.un_mirror_owner
4270Sstevel@tonic-gate #define	un_resync_startbl	un_mmic.un_resync_startbl
4280Sstevel@tonic-gate #define	un_owner_mx		un_mmic.un_owner_mx
4290Sstevel@tonic-gate #define	un_owner_state		un_mmic.un_owner_state
4300Sstevel@tonic-gate #define	un_mirror_reqs		un_mmic.un_mirror_reqs
4310Sstevel@tonic-gate #define	un_mirror_reqs_done	un_mmic.un_mirror_reqs_done
4320Sstevel@tonic-gate #define	un_mirror_owner_status	un_mmic.un_mirror_owner_status
4330Sstevel@tonic-gate #define	un_dmr_mx		un_mmic.un_dmr_mx
4340Sstevel@tonic-gate #define	un_dmr_cv		un_mmic.un_dmr_cv
4350Sstevel@tonic-gate #define	un_dmr_last_read	un_mmic.un_dmr_last_read
4360Sstevel@tonic-gate #define	un_rs_cprinfo		un_mmic.un_rs_cprinfo
4370Sstevel@tonic-gate #define	un_rs_cpr_mx		un_mmic.un_rs_cpr_mx
438*8452SJohn.Wren.Kennedy@Sun.COM #define	un_prr_cpr_mx		un_mmic.un_prr_cpr_mx
4390Sstevel@tonic-gate #define	un_resync_completed	un_mmic.un_resync_completed
4400Sstevel@tonic-gate #define	un_abr_count		un_mmic.un_abr_count
441*8452SJohn.Wren.Kennedy@Sun.COM #define	un_pernode_dirty_bm	un_mmic.un_pernode_dirty_bm
442*8452SJohn.Wren.Kennedy@Sun.COM #define	un_pernode_dirty_sum	un_mmic.un_pernode_dirty_sum
443*8452SJohn.Wren.Kennedy@Sun.COM #define	un_pernode_dirty_mx	un_mmic.un_pernode_dirty_mx
444*8452SJohn.Wren.Kennedy@Sun.COM #define	un_rr_clean_start_bit	un_mmic.un_rr_clean_start_bit
445*8452SJohn.Wren.Kennedy@Sun.COM #define	un_drl_task		un_mmic.un_drl_task
446*8452SJohn.Wren.Kennedy@Sun.COM #define	un_waiting_to_clear	un_mmic.un_waiting_to_clear
4470Sstevel@tonic-gate 
4480Sstevel@tonic-gate #define	MM_RF_GATECLOSED	0x0001
4490Sstevel@tonic-gate #define	MM_RF_COMMIT_NEEDED	0x0002
4500Sstevel@tonic-gate #define	MM_RF_COMMITING		0x0004
4510Sstevel@tonic-gate #define	MM_RF_STALL_CLEAN	(MM_RF_COMMITING | \
4520Sstevel@tonic-gate 				    MM_RF_COMMIT_NEEDED | \
4530Sstevel@tonic-gate 				    MM_RF_GATECLOSED)
4540Sstevel@tonic-gate 
4550Sstevel@tonic-gate 
4560Sstevel@tonic-gate #define	MD_MN_MIRROR_UNOWNED	0
4570Sstevel@tonic-gate #define	MD_MN_MIRROR_OWNER(un)	 (un->un_mirror_owner == md_mn_mynode_id)
4580Sstevel@tonic-gate #define	MD_MN_NO_MIRROR_OWNER(un)	\
4590Sstevel@tonic-gate 	(un->un_mirror_owner == MD_MN_MIRROR_UNOWNED)
4600Sstevel@tonic-gate 
4610Sstevel@tonic-gate typedef struct err_comp {
4620Sstevel@tonic-gate 	struct err_comp	*ec_next;
4630Sstevel@tonic-gate 	int		ec_smi;
4640Sstevel@tonic-gate 	int		ec_ci;
4650Sstevel@tonic-gate } err_comp_t;
4660Sstevel@tonic-gate 
4670Sstevel@tonic-gate extern	int	md_min_rr_size;
4680Sstevel@tonic-gate extern	int	md_def_num_rr;
4690Sstevel@tonic-gate 
4700Sstevel@tonic-gate /* Optimized resync records controllers */
4710Sstevel@tonic-gate #define	MD_MIN_RR_SIZE		(md_min_rr_size)
4720Sstevel@tonic-gate #define	MD_DEF_NUM_RR		(md_def_num_rr)
4730Sstevel@tonic-gate #define	MD_MAX_NUM_RR		(4192*NBBY - sizeof (struct optim_resync))
4740Sstevel@tonic-gate 
4750Sstevel@tonic-gate /* default resync buffer size */
476456Stn143363 #define	MD_DEF_RESYNC_BUF_SIZE	(1024)
4770Sstevel@tonic-gate 
4780Sstevel@tonic-gate /* Structure for optimized resync records */
4790Sstevel@tonic-gate #define	OR_MAGIC	0xFECA	/* Only missing the L */
4800Sstevel@tonic-gate typedef struct optim_resync {
4810Sstevel@tonic-gate 	uint_t	or_revision;
4820Sstevel@tonic-gate 	uint_t	or_magic;
4830Sstevel@tonic-gate 	uint_t	or_blksize;
4840Sstevel@tonic-gate 	uint_t	or_num;
4850Sstevel@tonic-gate 	uchar_t	or_rr[1];
4860Sstevel@tonic-gate } optim_resync_t;
4870Sstevel@tonic-gate 
4880Sstevel@tonic-gate /* Type 2 for mirror records */
4890Sstevel@tonic-gate #define	MIRROR_REC	1
4900Sstevel@tonic-gate #define	RESYNC_REC	2
4910Sstevel@tonic-gate 
4920Sstevel@tonic-gate #ifdef _KERNEL
4930Sstevel@tonic-gate 
4940Sstevel@tonic-gate #define	NO_SUBMIRRORS	(0)
4950Sstevel@tonic-gate #define	ALL_SUBMIRRORS	(0xFFF)
4960Sstevel@tonic-gate #define	SMI2BIT(smi)	(1 << (smi))
4970Sstevel@tonic-gate 
4980Sstevel@tonic-gate /* For use with mirror_other_sources() */
4990Sstevel@tonic-gate #define	WHOLE_SM	(-1)
5000Sstevel@tonic-gate 
5010Sstevel@tonic-gate #define	BLK_TO_RR(i, b, un)  {\
5020Sstevel@tonic-gate 	(i) = ((b) / ((un))->un_rrd_blksize); \
5030Sstevel@tonic-gate 	if ((i) > ((un))->un_rrd_num) \
5040Sstevel@tonic-gate 		{ panic("md: BLK_TO_RR"); } \
5050Sstevel@tonic-gate }
5060Sstevel@tonic-gate 
5070Sstevel@tonic-gate #define	RR_TO_BLK(b, i, un) \
5080Sstevel@tonic-gate 	(b) = ((i) * ((un))->un_rrd_blksize)
5090Sstevel@tonic-gate 
5100Sstevel@tonic-gate #define	IS_GOING_DIRTY(i, un)	(isset((un)->un_goingdirty_bm, (i)))
5110Sstevel@tonic-gate #define	CLR_GOING_DIRTY(i, un)	(clrbit((un)->un_goingdirty_bm, (i)))
5120Sstevel@tonic-gate #define	SET_GOING_DIRTY(i, un)	(setbit((un)->un_goingdirty_bm, (i)))
5130Sstevel@tonic-gate 
5140Sstevel@tonic-gate #define	IS_GOING_CLEAN(i, un)	(isset((un)->un_goingclean_bm, (i)))
5150Sstevel@tonic-gate #define	CLR_GOING_CLEAN(i, un)	(clrbit((un)->un_goingclean_bm, (i)))
5160Sstevel@tonic-gate #define	SET_GOING_CLEAN(i, un)	(setbit((un)->un_goingclean_bm, (i)))
5170Sstevel@tonic-gate 
5180Sstevel@tonic-gate #define	IS_REGION_DIRTY(i, un)	(isset((un)->un_dirty_bm, (i)))
5190Sstevel@tonic-gate #define	CLR_REGION_DIRTY(i, un)	(clrbit((un)->un_dirty_bm, (i)))
5200Sstevel@tonic-gate #define	SET_REGION_DIRTY(i, un)	(setbit((un)->un_dirty_bm, (i)))
5210Sstevel@tonic-gate 
5220Sstevel@tonic-gate #define	IS_KEEPDIRTY(i, un)	(isset((un)->un_resync_bm, (i)))
5230Sstevel@tonic-gate #define	CLR_KEEPDIRTY(i, un)	(clrbit((un)->un_resync_bm, (i)))
5240Sstevel@tonic-gate 
525*8452SJohn.Wren.Kennedy@Sun.COM #define	IS_PERNODE_DIRTY(n, i, un) \
526*8452SJohn.Wren.Kennedy@Sun.COM 	(isset((un)->un_pernode_dirty_bm[(n)-1], (i)))
527*8452SJohn.Wren.Kennedy@Sun.COM #define	CLR_PERNODE_DIRTY(n, i, un) \
528*8452SJohn.Wren.Kennedy@Sun.COM 	(clrbit((un)->un_pernode_dirty_bm[(n)-1], (i)))
529*8452SJohn.Wren.Kennedy@Sun.COM #define	SET_PERNODE_DIRTY(n, i, un) \
530*8452SJohn.Wren.Kennedy@Sun.COM 	(setbit((un)->un_pernode_dirty_bm[(n)-1], (i)))
5310Sstevel@tonic-gate 
5320Sstevel@tonic-gate /*
5330Sstevel@tonic-gate  * Write-On-Write handling.
5340Sstevel@tonic-gate  *   flags for md_mirror_wow_flg
5350Sstevel@tonic-gate  *   structure for quing copy-writes
5360Sstevel@tonic-gate  *   macros for relative locating of header and buffer
5370Sstevel@tonic-gate  */
5380Sstevel@tonic-gate #define	WOW_DISABLE	0x0001	/* turn off WOW detection */
5390Sstevel@tonic-gate #define	WOW_PHYS_ENABLE	0x0020	/* turn on WOW for PHYS */
5400Sstevel@tonic-gate #define	WOW_LOGIT	0x0002	/* log non-disabled WOW detections */
5410Sstevel@tonic-gate #define	WOW_NOCOPY	0x0004	/* repeat normal write on WOW detection */
5420Sstevel@tonic-gate 
5430Sstevel@tonic-gate typedef	struct wowhdr {
5440Sstevel@tonic-gate 	DAEMON_QUEUE
5450Sstevel@tonic-gate 	md_mps_t	*wow_ps;
5460Sstevel@tonic-gate 	int		wow_offset;
5470Sstevel@tonic-gate } wowhdr_t;
5480Sstevel@tonic-gate 
5490Sstevel@tonic-gate #define	WOWBUF_HDR(wowbuf)	((void *)(wowbuf-sizeof (wowhdr_t)))
5500Sstevel@tonic-gate #define	WOWHDR_BUF(wowhdr)	((char *)wowhdr+sizeof (wowhdr_t))
5510Sstevel@tonic-gate 
5520Sstevel@tonic-gate /*
5530Sstevel@tonic-gate  * Structure used to to save information about DMR reads.  Used to save
5540Sstevel@tonic-gate  * the count of all DMR reads and the timestamp of the last one executed.
5550Sstevel@tonic-gate  * We declare a global with this structure and it can be read by a debugger to
5560Sstevel@tonic-gate  * verify that the DMR ioctl has been executed and the number of times that it
5570Sstevel@tonic-gate  * has been executed.
5580Sstevel@tonic-gate  */
5590Sstevel@tonic-gate typedef struct dmr_stats {
5600Sstevel@tonic-gate 	uint_t		dmr_count;
5610Sstevel@tonic-gate 	struct timeval	dmr_timestamp;
5620Sstevel@tonic-gate } dmr_stats_t;
5630Sstevel@tonic-gate 
5640Sstevel@tonic-gate /* Externals from mirror.c */
5650Sstevel@tonic-gate extern mddb_recid_t	mirror_get_sm_unit(md_dev64_t);
5660Sstevel@tonic-gate extern void		mirror_release_sm_unit(md_dev64_t);
5670Sstevel@tonic-gate 
5680Sstevel@tonic-gate extern void		mirror_set_sm_state(mm_submirror_t *,
5690Sstevel@tonic-gate 				mm_submirror_ic_t *, sm_state_t, int);
5700Sstevel@tonic-gate 
5710Sstevel@tonic-gate extern void		mirror_commit(mm_unit_t *, int, mddb_recid_t *);
5720Sstevel@tonic-gate extern int		poke_hotspares(void);
5730Sstevel@tonic-gate extern void		build_submirror(mm_unit_t *, int, int);
5740Sstevel@tonic-gate extern int		mirror_build_incore(mm_unit_t *, int);
5750Sstevel@tonic-gate extern void		reset_mirror(mm_unit_t *, minor_t, int);
5760Sstevel@tonic-gate extern int		mirror_internal_open(minor_t, int, int, int, IOLOCK *);
5770Sstevel@tonic-gate extern int		mirror_internal_close(minor_t, int, int, IOLOCK *);
5780Sstevel@tonic-gate extern void		set_sm_comp_state(mm_unit_t *, int, int, int,
5790Sstevel@tonic-gate 			    mddb_recid_t *, uint_t, IOLOCK *);
5800Sstevel@tonic-gate extern int		mirror_other_sources(mm_unit_t *, int, int, int);
5810Sstevel@tonic-gate extern int		mirror_resync_message(md_mn_rs_params_t *, IOLOCK *);
5820Sstevel@tonic-gate extern void		md_mirror_strategy(buf_t *, int, void *);
5830Sstevel@tonic-gate extern int		mirror_directed_read(dev_t, vol_directed_rd_t *, int);
5840Sstevel@tonic-gate extern void		mirror_check_failfast(minor_t mnum);
5850Sstevel@tonic-gate extern int		check_comp_4_hotspares(mm_unit_t *, int, int, uint_t,
5860Sstevel@tonic-gate 			    mddb_recid_t, IOLOCK *);
5876901Sjkennedy extern void		mirror_overlap_tree_remove(md_mps_t *ps);
5880Sstevel@tonic-gate extern void		mirror_child_init(md_mcs_t *cs);
5890Sstevel@tonic-gate 
5900Sstevel@tonic-gate /* Externals from mirror_ioctl.c */
5910Sstevel@tonic-gate extern void		reset_comp_states(mm_submirror_t *,
5920Sstevel@tonic-gate 			    mm_submirror_ic_t *);
5930Sstevel@tonic-gate extern int		mirror_grow_unit(mm_unit_t *un, md_error_t *ep);
5940Sstevel@tonic-gate extern int		md_mirror_ioctl(dev_t dev, int cmd, void *data,
5950Sstevel@tonic-gate 			    int mode, IOLOCK *lockp);
5960Sstevel@tonic-gate extern mm_unit_t	*mirror_getun(minor_t, md_error_t *, int, IOLOCK *);
5970Sstevel@tonic-gate extern void		mirror_get_status(mm_unit_t *un, IOLOCK *lockp);
5980Sstevel@tonic-gate extern int		mirror_choose_owner(mm_unit_t *un, md_mn_req_owner_t *);
5990Sstevel@tonic-gate 
6000Sstevel@tonic-gate /* rename named service functions */
6010Sstevel@tonic-gate md_ren_list_svc_t	mirror_rename_listkids;
6020Sstevel@tonic-gate md_ren_svc_t		mirror_rename_check;
6030Sstevel@tonic-gate md_ren_roleswap_svc_t	mirror_renexch_update_kids;
6040Sstevel@tonic-gate md_ren_roleswap_svc_t	mirror_exchange_parent_update_to;
6050Sstevel@tonic-gate md_ren_roleswap_svc_t	mirror_exchange_self_update_from_down;
6060Sstevel@tonic-gate 
6070Sstevel@tonic-gate /* Externals from mirror_resync.c */
6080Sstevel@tonic-gate extern int		unit_setup_resync(mm_unit_t *, int);
6090Sstevel@tonic-gate extern int		mirror_resync_unit(minor_t mnum, md_resync_ioctl_t *ri,
6100Sstevel@tonic-gate 			    md_error_t *ep, IOLOCK *);
6110Sstevel@tonic-gate extern int		mirror_ioctl_resync(md_resync_ioctl_t *p, IOLOCK *);
6120Sstevel@tonic-gate extern int		mirror_mark_resync_region(mm_unit_t *, diskaddr_t,
613*8452SJohn.Wren.Kennedy@Sun.COM 				diskaddr_t, md_mn_nodeid_t);
6140Sstevel@tonic-gate extern void		resync_start_timeout(set_t setno);
6150Sstevel@tonic-gate extern int		mirror_resize_resync_regions(mm_unit_t *, diskaddr_t);
6160Sstevel@tonic-gate extern int		mirror_add_resync_regions(mm_unit_t *, diskaddr_t);
6170Sstevel@tonic-gate extern int		mirror_probedevs(md_probedev_t *, IOLOCK *);
6180Sstevel@tonic-gate extern void		mirror_copy_rr(int, uchar_t *, uchar_t *);
6190Sstevel@tonic-gate extern void		mirror_process_unit_resync(mm_unit_t *);
620*8452SJohn.Wren.Kennedy@Sun.COM extern int		mirror_set_dirty_rr(md_mn_rr_dirty_params_t *);
621*8452SJohn.Wren.Kennedy@Sun.COM extern int		mirror_set_clean_rr(md_mn_rr_clean_params_t *);
6220Sstevel@tonic-gate #endif	/* _KERNEL */
6230Sstevel@tonic-gate 
6240Sstevel@tonic-gate #ifdef	__cplusplus
6250Sstevel@tonic-gate }
6260Sstevel@tonic-gate #endif
6270Sstevel@tonic-gate 
6280Sstevel@tonic-gate #endif	/* _SYS_MD_MIRROR_H */
629