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