md_mirror.h revision 8452:89d32dfdae6e
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/*
23 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#ifndef _SYS_MD_MIRROR_H
28#define	_SYS_MD_MIRROR_H
29
30#include <sys/callb.h>
31#include <sys/lvm/mdvar.h>
32#include <sys/lvm/md_mirror_shared.h>
33#include <sys/lvm/md_rename.h>
34#ifdef	_KERNEL
35#include <sys/sunddi.h>
36#endif
37
38#ifdef	__cplusplus
39extern "C" {
40#endif
41
42/*
43 * following bits are used in status word in the common section
44 * of unit structure
45 */
46#define	SMS_IS(sm, state) (((sm)->sm_state & (state)) != 0)
47#define	SMS_BY_INDEX_IS(un, index, state) \
48		(((un)->un_sm[(index)].sm_state & (state)) != 0)
49
50#define	SMS_BY_INDEX_IS_TARGET(un, index) \
51		((un)->un_sm[(index)].sm_flags & MD_SM_RESYNC_TARGET)
52
53#define	SUBMIRROR_IS_READABLE(un, isubmirror)				\
54	((((un)->un_sm[(isubmirror)].sm_state & SMS_IGNORE) == 0) &&	\
55	    ((un)->un_sm[(isubmirror)].sm_state & 			\
56	    (SMS_RUNNING | SMS_COMP_ERRED | SMS_COMP_RESYNC)))
57
58#define	SUBMIRROR_IS_WRITEABLE(un, isubmirror)			\
59	((un)->un_sm[(isubmirror)].sm_state &			\
60	    (SMS_RUNNING | SMS_COMP_ERRED | SMS_COMP_RESYNC |	\
61	    SMS_ATTACHED_RESYNC | SMS_OFFLINE_RESYNC))
62
63/*
64 * Default resync block size for MN resync messages
65 */
66#define	MD_DEF_RESYNC_BLK_SZ		8192
67
68/*
69 * macro to test if the current block is within the current resync region
70 */
71#define	IN_RESYNC_REGION(un, ps) \
72	((un->un_rs_prev_overlap != NULL) && (ps->ps_firstblk >= \
73	    un->un_rs_prev_overlap->ps_firstblk) && \
74	    (ps->ps_lastblk <=  un->un_rs_prev_overlap->ps_lastblk))
75/*
76 * Default resync update interval (in minutes).
77 */
78#define	MD_DEF_MIRROR_RESYNC_INTVL	5
79
80/*
81 * Defines for flags argument in function set_sm_comp_state()
82 */
83#define	MD_STATE_NO_XMIT	0x0000 /* Local action, (sent from master) */
84#define	MD_STATE_XMIT		0x0001 /* Non-local action, send to master */
85#define	MD_STATE_WMUPDATE	0x0002 /* Action because of watermark update */
86#define	MD_STATE_OCHELD		0x0004 /* open/close lock held */
87
88/*
89 * Defines for flags argument in function check_comp_4_hotspares()
90 */
91#define	MD_HOTSPARE_NO_XMIT	0x0000 /* Local action, (sent from master) */
92#define	MD_HOTSPARE_XMIT	0x0001 /* Non-local action, send to master */
93#define	MD_HOTSPARE_WMUPDATE	0x0002 /* Action because of watermark update */
94#define	MD_HOTSPARE_LINKHELD	0x0004 /* md_link_rw lock held */
95
96/*
97 * Defines for argument in function send_mn_resync_done_message()
98 */
99#define	RESYNC_ERR		0x1
100#define	CLEAR_OPT_NOT_DONE	0x2
101
102/*
103 * Defines for argument in function resync_read_blk_range()
104 */
105#define	MD_FIRST_RESYNC_NEXT	0x1
106#define	MD_SEND_MESS_XMIT	0x2
107#define	MD_RESYNC_FLAG_ERR	0x4
108
109/*
110 * Define for argument in function wait_for_overlaps()
111 */
112#define	MD_OVERLAP_ALLOW_REPEAT	0x1	/* Allow if ps already in tree */
113#define	MD_OVERLAP_NO_REPEAT	0	/* ps must not already be in tree */
114
115/*
116 * Define for max retries of mirror_owner
117 */
118#define	MD_OWNER_RETRIES	10
119
120/*
121 * mm_submirror32_od and mm_unit32_od are used only for 32 bit old format
122 */
123#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
124#pragma pack(4)
125#endif
126typedef struct  mm_submirror32_od {	/* submirrors */
127	mdkey_t		sm_key;
128	dev32_t		sm_dev;
129	sm_state_t	sm_state;
130	sm_flags_t	sm_flags;
131	caddr32_t	xx_sm_shared_by_blk;	/* really void *) */
132	caddr32_t	xx_sm_shared_by_indx;	/* really void *) */
133	caddr32_t	xx_sm_get_component_count;
134	caddr32_t	xx_sm_get_bcss;	/* block count skip size */
135	md_m_shared32_od_t sm_shared;	/* used for mirroring plain devices */
136	int		sm_hsp_id;	/* used for mirroring plain devices */
137	struct timeval32 sm_timestamp;	/* time of last state change */
138} mm_submirror32_od_t;
139
140typedef struct	mm_submirror {		/* submirrors */
141	mdkey_t		sm_key;
142	md_dev64_t	sm_dev;		/* 64 bit */
143	sm_state_t	sm_state;
144	sm_flags_t	sm_flags;
145	md_m_shared_t	sm_shared;	/* used for mirroring plain devices */
146	int		sm_hsp_id;	/* used for mirroring plain devices */
147	md_timeval32_t	sm_timestamp;	/* time of last state change, 32 bit */
148} mm_submirror_t;
149
150typedef struct mm_unit32_od {
151	mdc_unit32_od_t	c;			/* common stuff */
152
153	int		un_last_read;		/* last submirror index read */
154	uint_t		un_changecnt;
155	ushort_t	un_nsm;			/* number of submirrors */
156	mm_submirror32_od_t un_sm[NMIRROR];
157	int		un_overlap_tree_flag;
158	int		xx_un_overlap_tree_mx[2];	/* replaces mutex */
159	ushort_t	xx_un_overlap_tree_cv;
160	caddr32_t	xx_un_overlap_root;
161	mm_rd_opt_t	un_read_option;		/* mirror read option */
162	mm_wr_opt_t	un_write_option;	/* mirror write option */
163	mm_pass_num_t	un_pass_num;		/* resync pass number */
164	/*
165	 * following used to keep dirty bitmaps
166	 */
167	int		xx_un_resync_mx[2];	/* replaces mutex */
168	ushort_t	xx_un_resync_cv;
169	uint_t		un_resync_flg;
170	uint_t		un_waiting_to_mark;
171	uint_t		un_waiting_to_commit;
172	caddr32_t	xx_un_outstanding_writes;	/* outstanding write */
173	caddr32_t	xx_un_goingclean_bm;
174	caddr32_t	xx_un_goingdirty_bm;
175	caddr32_t	xx_un_dirty_bm;
176	caddr32_t	xx_un_resync_bm;
177	uint_t		un_rrd_blksize;	/* The blocksize of the dirty bits */
178	uint_t		un_rrd_num;	/* The number of resync regions */
179	mddb_recid_t	un_rr_dirty_recid;	/* resync region bm record id */
180	/*
181	 * following stuff is private to resync process
182	 */
183	int		un_rs_copysize;
184	int		un_rs_dests;	/* destinations */
185	daddr32_t	un_rs_resync_done;	/* used for percent done */
186	daddr32_t	un_rs_resync_2_do;	/* user for percent done */
187	int		un_rs_dropped_lock;
188	caddr32_t	un_rs_type;		/* type of resync in progress */
189	/*
190	 * Incore elements in this old structure are no longer referenced by
191	 * current 64 bit kernel.  Comment them out for maintenance purpose.
192	 *
193	 * 	mm_submirror_ic_t	un_smic[NMIRROR];
194	 * 	kmutex_t		un_ovrlap_chn_mx;
195	 * 	kcondvar_t		un_ovrlap_chn_cv;
196	 * 	struct md_mps		*un_ovrlap_chn;
197	 * 	kmutex_t		un_resync_mx;
198	 * 	kcondvar_t		un_resync_cv;
199	 * 	short			*un_outstanding_writes;
200	 * 	uchar_t			*un_goingclean_bm;
201	 * 	uchar_t			*un_goingdirty_bm;
202	 * 	uchar_t			*un_dirty_bm;
203	 * 	uchar_t			*un_resync_bm;
204	 * 	char			*un_rs_buffer;
205	 */
206} mm_unit32_od_t;
207#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
208#pragma pack()
209#endif
210
211/* Types of resync in progress (used for un_rs_type) */
212#define	MD_RS_NONE		0		/* No resync */
213#define	MD_RS_OPTIMIZED		0x0001		/* Optimized resync */
214#define	MD_RS_COMPONENT		0x0002		/* Component resync */
215#define	MD_RS_SUBMIRROR		0x0003		/* Submirror resync */
216#define	MD_RS_ABR		0x0004		/* Application based resync */
217
218/*
219 * un_rs_type is split into the following bitfields:
220 *
221 * 0-3	Resync type (as above)
222 * 4-7	Submirror index [0..3]
223 * 8-31	Component index
224 */
225#define	RS_TYPE_MASK	0xF
226#define	RS_SMI_MASK	0xF0
227#define	RS_CI_MASK	0x1FFF00
228
229#define	RS_TYPE(x)	((x) & RS_TYPE_MASK)
230#define	RS_SMI(x)	(((x) & RS_SMI_MASK) >> 4)
231#define	RS_CI(x)	(((x) & RS_CI_MASK) >> 8)
232
233#define	SET_RS_TYPE(x, v)	{					\
234				    (x) &= ~RS_TYPE_MASK;		\
235				    (x) |= ((v) & RS_TYPE_MASK);	\
236				}
237#define	SET_RS_TYPE_NONE(x)	{					\
238				    (x) &= ~RS_TYPE_MASK;		\
239				}
240#define	SET_RS_SMI(x, v)	{					\
241				    (x) &= ~RS_SMI_MASK; 		\
242				    (x) |= (((v) << 4) & RS_SMI_MASK);	\
243				}
244#define	SET_RS_CI(x, v)		{					\
245				    (x) &= ~RS_CI_MASK;			\
246				    (x) |= (((v) << 8) & RS_CI_MASK);	\
247				}
248
249typedef struct	mm_submirror_ic {
250	intptr_t	(*sm_shared_by_blk)(md_dev64_t, void *,
251				diskaddr_t, u_longlong_t *);
252	intptr_t	(*sm_shared_by_indx)(md_dev64_t, void *, int);
253	int		(*sm_get_component_count)(md_dev64_t, void *);
254	int		(*sm_get_bcss)(md_dev64_t, void *, int, diskaddr_t *,
255				size_t *, u_longlong_t *, u_longlong_t *);
256} mm_submirror_ic_t;
257
258typedef struct md_mps {
259	DAEMON_QUEUE
260	buf_t		*ps_bp;
261	struct mm_unit	*ps_un;
262	mdi_unit_t	*ps_ui;
263	uint_t		 ps_childbflags;
264	caddr_t		 ps_addr;
265	diskaddr_t	 ps_firstblk;
266	diskaddr_t	 ps_lastblk;
267	uint_t		 ps_flags;
268	uint_t		 ps_allfrom_sm;		/* entire read came from here */
269	uint_t		 ps_writable_sm;
270	uint_t		 ps_current_sm;
271	uint_t		 ps_active_cnt;
272	int		 ps_frags;
273	uint_t		 ps_changecnt;
274	struct md_mps	*ps_unused1;
275	struct md_mps	*ps_unused2;
276	void		 (*ps_call)();
277	kmutex_t	 ps_mx;
278	avl_node_t	ps_overlap_node;
279} md_mps_t;
280
281#define	MD_MPS_ON_OVERLAP	0x0001
282#define	MD_MPS_ERROR		0x0002
283#define	MD_MPS_WRITE_AFTER_READ	0x0004
284#define	MD_MPS_WOW		0x0008
285#define	MD_MPS_DONTFREE		0x0010
286#define	MD_MPS_DONE		0x0020
287#define	MD_MPS_MAPPED		0x0040		/* re: MD_STR_MAPPED	*/
288#define	MD_MPS_NOBLOCK		0x0080		/* re: MD_NOBLOCK	*/
289#define	MD_MPS_ABR		0x0100		/* re: MD_STR_ABR	*/
290#define	MD_MPS_DMR		0x0200		/* re: MD_STR_DMR	*/
291#define	MD_MPS_WMUPDATE		0x0400		/* re: MD_STR_WMUPDATE	*/
292#define	MD_MPS_DIRTY_RD		0x0800		/* re: MD_STR_DIRTY_RD	*/
293#define	MD_MPS_RESYNC_READ	0x1000
294#define	MD_MPS_FLAG_ERROR	0x2000		/* re: MD_STR_FLAG_ERR	*/
295#define	MD_MPS_BLOCKABLE_IO	0x4000		/* re: MD_STR_BLOCK_OK  */
296
297#define	MPS_FREE(kc, ps)			\
298{						\
299	if ((ps)->ps_flags & MD_MPS_DONTFREE)	\
300		(ps)->ps_flags |= MD_MPS_DONE;	\
301	else					\
302		kmem_cache_free((kc), (ps));	\
303}
304
305typedef struct md_mcs {
306	DAEMON_QUEUE
307	md_mps_t	*cs_ps;
308	minor_t		 cs_mdunit;
309	/* Add new structure members HERE!! */
310	buf_t		 cs_buf;
311	/*  DO NOT add structure members here; cs_buf is dynamically sized */
312} md_mcs_t;
313
314typedef struct  mm_mirror_ic {
315	kmutex_t	un_overlap_tree_mx;
316	kcondvar_t	un_overlap_tree_cv;
317	avl_tree_t	un_overlap_root;
318	kmutex_t	un_resync_mx;
319	kcondvar_t	un_resync_cv;
320	short		*un_outstanding_writes; /* outstanding write array */
321	uchar_t		*un_goingclean_bm;
322	uchar_t		*un_goingdirty_bm;
323	uchar_t		*un_dirty_bm;
324	uchar_t		*un_resync_bm;
325	char		*un_rs_buffer;
326	int		un_suspend_wr_flag;
327	kmutex_t	un_suspend_wr_mx;
328	kcondvar_t	un_suspend_wr_cv;
329	md_mn_nodeid_t	un_mirror_owner;	/* Node which owns mirror */
330	diskaddr_t	un_resync_startbl;	/* Start block for resync */
331	kmutex_t	un_owner_mx;		/* Mutex for un_owner_state */
332	uint_t		un_owner_state;		/* See below */
333	uint_t		un_mirror_owner_status;	/* status for ioctl request */
334	kmutex_t	un_dmr_mx;		/* mutex for DMR requests */
335	kcondvar_t	un_dmr_cv;		/* condvar for DMR requests */
336	int		un_dmr_last_read;	/* last DMR submirror read */
337	callb_cpr_t	un_rs_cprinfo;		/* CPR info for resync thread */
338	kmutex_t	un_rs_cpr_mx;		/* mutex for resync CPR info */
339	kmutex_t	un_prr_cpr_mx;		/* mutex for prr CPR info */
340	uint_t		un_resync_completed;	/* type of last resync */
341	int		un_abr_count;		/* count of sp's with abr set */
342
343	uchar_t		*un_pernode_dirty_bm[MD_MNMAXSIDES];
344	uchar_t		*un_pernode_dirty_sum;
345
346	krwlock_t	un_pernode_dirty_mx[MD_MNMAXSIDES];
347	ushort_t	un_rr_clean_start_bit;  /* where to start next clean */
348
349#ifdef	_KERNEL
350	ddi_taskq_t	*un_drl_task;		/* deferred RR_CLEAN taskq */
351#else
352	void		*un_drl_task;		/* deferred RR_CLEAN taskq */
353#endif	/* _KERNEL */
354	uint_t		un_waiting_to_clear;	/* Blocked waiting to clear */
355
356}mm_mirror_ic_t;
357
358#define	MM_MN_OWNER_SENT	0x0001		/* RPC in progress */
359#define	MM_MN_BECOME_OWNER	0x0002		/* Ownership change in prog. */
360#define	MM_MN_PREVENT_CHANGE	0x0004		/* Disallow ownership change */
361
362typedef struct mm_unit {
363	mdc_unit_t	c;			/* common stuff */
364
365	int		un_last_read;		/* last submirror index read */
366	uint_t		un_changecnt;
367	ushort_t	un_nsm;			/* number of submirrors */
368	mm_submirror_t	un_sm[NMIRROR];
369	int		un_overlap_tree_flag;
370	mm_rd_opt_t	un_read_option;		/* mirror read option */
371	mm_wr_opt_t	un_write_option;	/* mirror write option */
372	mm_pass_num_t	un_pass_num;		/* resync pass number */
373	/*
374	 * following used to keep dirty bitmaps
375	 */
376	uint_t		un_resync_flg;
377	uint_t		un_waiting_to_mark;
378	uint_t		un_waiting_to_commit;
379	uint_t		un_rrd_blksize;	  /* The blocksize of the dirty bits */
380	uint_t		un_rrd_num;	  /* The number of resync regions */
381	mddb_recid_t	un_rr_dirty_recid; /* resync region bm db record id */
382	/*
383	 * following stuff is private to resync process
384	 */
385	int 		un_rs_copysize;
386	int 		un_rs_dests;		/* destinations */
387	diskaddr_t	un_rs_resync_done;	/* used for percent done */
388	diskaddr_t	un_rs_resync_2_do;	/* user for percent done */
389	int		un_rs_dropped_lock;
390	uint_t		un_rs_type;		/* type of resync */
391	/*
392	 * Incore only elements
393	 */
394	mm_submirror_ic_t un_smic[NMIRROR];	/* NMIRROR elements array */
395	mm_mirror_ic_t	un_mmic;
396	kmutex_t	un_rrp_inflight_mx;
397	/*
398	 * resync thread control
399	 */
400	kthread_t	*un_rs_thread;		/* Resync thread ID */
401	kmutex_t	un_rs_thread_mx;	/* Thread cv mutex */
402	kcondvar_t	un_rs_thread_cv;	/* Cond. Var. for thread */
403	uint_t		un_rs_thread_flags;	/* Thread control flags */
404	md_mps_t	*un_rs_prev_overlap;	/* existing overlap request */
405	timeout_id_t	un_rs_resync_to_id;	/* resync progress timeout */
406	kmutex_t	un_rs_progress_mx;	/* Resync progress mutex */
407	kcondvar_t	un_rs_progress_cv;	/* Cond. Var. for progress */
408	uint_t		un_rs_progress_flags;	/* Thread control flags */
409	void		*un_rs_msg;		/* Intra-node resync message */
410} mm_unit_t;
411
412#define	un_overlap_tree_mx	un_mmic.un_overlap_tree_mx
413#define	un_overlap_tree_cv	un_mmic.un_overlap_tree_cv
414#define	un_overlap_root		un_mmic.un_overlap_root
415#define	un_resync_mx		un_mmic.un_resync_mx
416#define	un_resync_cv		un_mmic.un_resync_cv
417#define	un_outstanding_writes	un_mmic.un_outstanding_writes
418#define	un_goingclean_bm	un_mmic.un_goingclean_bm
419#define	un_goingdirty_bm	un_mmic.un_goingdirty_bm
420#define	un_dirty_bm		un_mmic.un_dirty_bm
421#define	un_resync_bm		un_mmic.un_resync_bm
422#define	un_rs_buffer		un_mmic.un_rs_buffer
423#define	un_suspend_wr_mx	un_mmic.un_suspend_wr_mx
424#define	un_suspend_wr_cv	un_mmic.un_suspend_wr_cv
425#define	un_suspend_wr_flag	un_mmic.un_suspend_wr_flag
426#define	un_mirror_owner		un_mmic.un_mirror_owner
427#define	un_resync_startbl	un_mmic.un_resync_startbl
428#define	un_owner_mx		un_mmic.un_owner_mx
429#define	un_owner_state		un_mmic.un_owner_state
430#define	un_mirror_reqs		un_mmic.un_mirror_reqs
431#define	un_mirror_reqs_done	un_mmic.un_mirror_reqs_done
432#define	un_mirror_owner_status	un_mmic.un_mirror_owner_status
433#define	un_dmr_mx		un_mmic.un_dmr_mx
434#define	un_dmr_cv		un_mmic.un_dmr_cv
435#define	un_dmr_last_read	un_mmic.un_dmr_last_read
436#define	un_rs_cprinfo		un_mmic.un_rs_cprinfo
437#define	un_rs_cpr_mx		un_mmic.un_rs_cpr_mx
438#define	un_prr_cpr_mx		un_mmic.un_prr_cpr_mx
439#define	un_resync_completed	un_mmic.un_resync_completed
440#define	un_abr_count		un_mmic.un_abr_count
441#define	un_pernode_dirty_bm	un_mmic.un_pernode_dirty_bm
442#define	un_pernode_dirty_sum	un_mmic.un_pernode_dirty_sum
443#define	un_pernode_dirty_mx	un_mmic.un_pernode_dirty_mx
444#define	un_rr_clean_start_bit	un_mmic.un_rr_clean_start_bit
445#define	un_drl_task		un_mmic.un_drl_task
446#define	un_waiting_to_clear	un_mmic.un_waiting_to_clear
447
448#define	MM_RF_GATECLOSED	0x0001
449#define	MM_RF_COMMIT_NEEDED	0x0002
450#define	MM_RF_COMMITING		0x0004
451#define	MM_RF_STALL_CLEAN	(MM_RF_COMMITING | \
452				    MM_RF_COMMIT_NEEDED | \
453				    MM_RF_GATECLOSED)
454
455
456#define	MD_MN_MIRROR_UNOWNED	0
457#define	MD_MN_MIRROR_OWNER(un)	 (un->un_mirror_owner == md_mn_mynode_id)
458#define	MD_MN_NO_MIRROR_OWNER(un)	\
459	(un->un_mirror_owner == MD_MN_MIRROR_UNOWNED)
460
461typedef struct err_comp {
462	struct err_comp	*ec_next;
463	int		ec_smi;
464	int		ec_ci;
465} err_comp_t;
466
467extern	int	md_min_rr_size;
468extern	int	md_def_num_rr;
469
470/* Optimized resync records controllers */
471#define	MD_MIN_RR_SIZE		(md_min_rr_size)
472#define	MD_DEF_NUM_RR		(md_def_num_rr)
473#define	MD_MAX_NUM_RR		(4192*NBBY - sizeof (struct optim_resync))
474
475/* default resync buffer size */
476#define	MD_DEF_RESYNC_BUF_SIZE	(1024)
477
478/* Structure for optimized resync records */
479#define	OR_MAGIC	0xFECA	/* Only missing the L */
480typedef struct optim_resync {
481	uint_t	or_revision;
482	uint_t	or_magic;
483	uint_t	or_blksize;
484	uint_t	or_num;
485	uchar_t	or_rr[1];
486} optim_resync_t;
487
488/* Type 2 for mirror records */
489#define	MIRROR_REC	1
490#define	RESYNC_REC	2
491
492#ifdef _KERNEL
493
494#define	NO_SUBMIRRORS	(0)
495#define	ALL_SUBMIRRORS	(0xFFF)
496#define	SMI2BIT(smi)	(1 << (smi))
497
498/* For use with mirror_other_sources() */
499#define	WHOLE_SM	(-1)
500
501#define	BLK_TO_RR(i, b, un)  {\
502	(i) = ((b) / ((un))->un_rrd_blksize); \
503	if ((i) > ((un))->un_rrd_num) \
504		{ panic("md: BLK_TO_RR"); } \
505}
506
507#define	RR_TO_BLK(b, i, un) \
508	(b) = ((i) * ((un))->un_rrd_blksize)
509
510#define	IS_GOING_DIRTY(i, un)	(isset((un)->un_goingdirty_bm, (i)))
511#define	CLR_GOING_DIRTY(i, un)	(clrbit((un)->un_goingdirty_bm, (i)))
512#define	SET_GOING_DIRTY(i, un)	(setbit((un)->un_goingdirty_bm, (i)))
513
514#define	IS_GOING_CLEAN(i, un)	(isset((un)->un_goingclean_bm, (i)))
515#define	CLR_GOING_CLEAN(i, un)	(clrbit((un)->un_goingclean_bm, (i)))
516#define	SET_GOING_CLEAN(i, un)	(setbit((un)->un_goingclean_bm, (i)))
517
518#define	IS_REGION_DIRTY(i, un)	(isset((un)->un_dirty_bm, (i)))
519#define	CLR_REGION_DIRTY(i, un)	(clrbit((un)->un_dirty_bm, (i)))
520#define	SET_REGION_DIRTY(i, un)	(setbit((un)->un_dirty_bm, (i)))
521
522#define	IS_KEEPDIRTY(i, un)	(isset((un)->un_resync_bm, (i)))
523#define	CLR_KEEPDIRTY(i, un)	(clrbit((un)->un_resync_bm, (i)))
524
525#define	IS_PERNODE_DIRTY(n, i, un) \
526	(isset((un)->un_pernode_dirty_bm[(n)-1], (i)))
527#define	CLR_PERNODE_DIRTY(n, i, un) \
528	(clrbit((un)->un_pernode_dirty_bm[(n)-1], (i)))
529#define	SET_PERNODE_DIRTY(n, i, un) \
530	(setbit((un)->un_pernode_dirty_bm[(n)-1], (i)))
531
532/*
533 * Write-On-Write handling.
534 *   flags for md_mirror_wow_flg
535 *   structure for quing copy-writes
536 *   macros for relative locating of header and buffer
537 */
538#define	WOW_DISABLE	0x0001	/* turn off WOW detection */
539#define	WOW_PHYS_ENABLE	0x0020	/* turn on WOW for PHYS */
540#define	WOW_LOGIT	0x0002	/* log non-disabled WOW detections */
541#define	WOW_NOCOPY	0x0004	/* repeat normal write on WOW detection */
542
543typedef	struct wowhdr {
544	DAEMON_QUEUE
545	md_mps_t	*wow_ps;
546	int		wow_offset;
547} wowhdr_t;
548
549#define	WOWBUF_HDR(wowbuf)	((void *)(wowbuf-sizeof (wowhdr_t)))
550#define	WOWHDR_BUF(wowhdr)	((char *)wowhdr+sizeof (wowhdr_t))
551
552/*
553 * Structure used to to save information about DMR reads.  Used to save
554 * the count of all DMR reads and the timestamp of the last one executed.
555 * We declare a global with this structure and it can be read by a debugger to
556 * verify that the DMR ioctl has been executed and the number of times that it
557 * has been executed.
558 */
559typedef struct dmr_stats {
560	uint_t		dmr_count;
561	struct timeval	dmr_timestamp;
562} dmr_stats_t;
563
564/* Externals from mirror.c */
565extern mddb_recid_t	mirror_get_sm_unit(md_dev64_t);
566extern void		mirror_release_sm_unit(md_dev64_t);
567
568extern void		mirror_set_sm_state(mm_submirror_t *,
569				mm_submirror_ic_t *, sm_state_t, int);
570
571extern void		mirror_commit(mm_unit_t *, int, mddb_recid_t *);
572extern int		poke_hotspares(void);
573extern void		build_submirror(mm_unit_t *, int, int);
574extern int		mirror_build_incore(mm_unit_t *, int);
575extern void		reset_mirror(mm_unit_t *, minor_t, int);
576extern int		mirror_internal_open(minor_t, int, int, int, IOLOCK *);
577extern int		mirror_internal_close(minor_t, int, int, IOLOCK *);
578extern void		set_sm_comp_state(mm_unit_t *, int, int, int,
579			    mddb_recid_t *, uint_t, IOLOCK *);
580extern int		mirror_other_sources(mm_unit_t *, int, int, int);
581extern int		mirror_resync_message(md_mn_rs_params_t *, IOLOCK *);
582extern void		md_mirror_strategy(buf_t *, int, void *);
583extern int		mirror_directed_read(dev_t, vol_directed_rd_t *, int);
584extern void		mirror_check_failfast(minor_t mnum);
585extern int		check_comp_4_hotspares(mm_unit_t *, int, int, uint_t,
586			    mddb_recid_t, IOLOCK *);
587extern void		mirror_overlap_tree_remove(md_mps_t *ps);
588extern void		mirror_child_init(md_mcs_t *cs);
589
590/* Externals from mirror_ioctl.c */
591extern void		reset_comp_states(mm_submirror_t *,
592			    mm_submirror_ic_t *);
593extern int		mirror_grow_unit(mm_unit_t *un, md_error_t *ep);
594extern int		md_mirror_ioctl(dev_t dev, int cmd, void *data,
595			    int mode, IOLOCK *lockp);
596extern mm_unit_t	*mirror_getun(minor_t, md_error_t *, int, IOLOCK *);
597extern void		mirror_get_status(mm_unit_t *un, IOLOCK *lockp);
598extern int		mirror_choose_owner(mm_unit_t *un, md_mn_req_owner_t *);
599
600/* rename named service functions */
601md_ren_list_svc_t	mirror_rename_listkids;
602md_ren_svc_t		mirror_rename_check;
603md_ren_roleswap_svc_t	mirror_renexch_update_kids;
604md_ren_roleswap_svc_t	mirror_exchange_parent_update_to;
605md_ren_roleswap_svc_t	mirror_exchange_self_update_from_down;
606
607/* Externals from mirror_resync.c */
608extern int		unit_setup_resync(mm_unit_t *, int);
609extern int		mirror_resync_unit(minor_t mnum, md_resync_ioctl_t *ri,
610			    md_error_t *ep, IOLOCK *);
611extern int		mirror_ioctl_resync(md_resync_ioctl_t *p, IOLOCK *);
612extern int		mirror_mark_resync_region(mm_unit_t *, diskaddr_t,
613				diskaddr_t, md_mn_nodeid_t);
614extern void		resync_start_timeout(set_t setno);
615extern int		mirror_resize_resync_regions(mm_unit_t *, diskaddr_t);
616extern int		mirror_add_resync_regions(mm_unit_t *, diskaddr_t);
617extern int		mirror_probedevs(md_probedev_t *, IOLOCK *);
618extern void		mirror_copy_rr(int, uchar_t *, uchar_t *);
619extern void		mirror_process_unit_resync(mm_unit_t *);
620extern int		mirror_set_dirty_rr(md_mn_rr_dirty_params_t *);
621extern int		mirror_set_clean_rr(md_mn_rr_clean_params_t *);
622#endif	/* _KERNEL */
623
624#ifdef	__cplusplus
625}
626#endif
627
628#endif	/* _SYS_MD_MIRROR_H */
629