1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #ifndef _SYS_MDVAR_H 28*0Sstevel@tonic-gate #define _SYS_MDVAR_H 29*0Sstevel@tonic-gate 30*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 31*0Sstevel@tonic-gate 32*0Sstevel@tonic-gate #include <sys/types.h> 33*0Sstevel@tonic-gate #include <sys/kmem.h> 34*0Sstevel@tonic-gate #include <sys/mkdev.h> 35*0Sstevel@tonic-gate #include <sys/param.h> 36*0Sstevel@tonic-gate #include <sys/systm.h> 37*0Sstevel@tonic-gate #include <sys/t_lock.h> 38*0Sstevel@tonic-gate #include <sys/open.h> 39*0Sstevel@tonic-gate #include <sys/devops.h> 40*0Sstevel@tonic-gate #include <sys/modctl.h> 41*0Sstevel@tonic-gate #ifdef DEBUG 42*0Sstevel@tonic-gate #include <sys/thread.h> 43*0Sstevel@tonic-gate #endif 44*0Sstevel@tonic-gate #include <sys/kstat.h> 45*0Sstevel@tonic-gate #include <sys/efi_partition.h> 46*0Sstevel@tonic-gate #include <sys/byteorder.h> 47*0Sstevel@tonic-gate #include <sys/door.h> 48*0Sstevel@tonic-gate 49*0Sstevel@tonic-gate #include <sys/lvm/mdmn_commd.h> 50*0Sstevel@tonic-gate #include <sys/lvm/mdio.h> 51*0Sstevel@tonic-gate #include <sys/lvm/md_mdiox.h> 52*0Sstevel@tonic-gate #include <sys/lvm/md_mddb.h> 53*0Sstevel@tonic-gate #include <sys/lvm/md_notify.h> 54*0Sstevel@tonic-gate 55*0Sstevel@tonic-gate #ifdef __cplusplus 56*0Sstevel@tonic-gate extern "C" { 57*0Sstevel@tonic-gate #endif 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate /* 60*0Sstevel@tonic-gate * defaults 61*0Sstevel@tonic-gate */ 62*0Sstevel@tonic-gate #define NMD_DEFAULT 128 /* number of metadevices */ 63*0Sstevel@tonic-gate #define MD_NOPS 25 /* number of misc modules */ 64*0Sstevel@tonic-gate #define MAXBOOTLIST 64 65*0Sstevel@tonic-gate 66*0Sstevel@tonic-gate /* 67*0Sstevel@tonic-gate * Needed for backwards-compatibility with metadevices created under 68*0Sstevel@tonic-gate * 2.6 or earlier. Back then, a krwlock_t was twelve bytes. More 69*0Sstevel@tonic-gate * recently, it's four bytes. Since these get included in structures 70*0Sstevel@tonic-gate * written out to disk, we have to make sure we're using the largest 71*0Sstevel@tonic-gate * size. Things will get interesting if krwlock_t ever gets bigger 72*0Sstevel@tonic-gate * than twelve bytes. 73*0Sstevel@tonic-gate */ 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gate typedef union _md_krwlock { 76*0Sstevel@tonic-gate krwlock_t lock; 77*0Sstevel@tonic-gate struct { 78*0Sstevel@tonic-gate void *_opaque[3]; 79*0Sstevel@tonic-gate } xx; 80*0Sstevel@tonic-gate } md_krwlock_t; 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gate typedef struct { 83*0Sstevel@tonic-gate kmutex_t md_io_mx; /* counter mutex */ 84*0Sstevel@tonic-gate kcondvar_t md_io_cv; /* ioctl wait on if draining */ 85*0Sstevel@tonic-gate long io_cnt; /* number of I/Os */ 86*0Sstevel@tonic-gate long io_state; /* !0 if waiting on zero */ 87*0Sstevel@tonic-gate } md_set_io_t; 88*0Sstevel@tonic-gate 89*0Sstevel@tonic-gate typedef enum set_iostate { 90*0Sstevel@tonic-gate MD_SET_ACTIVE = 1, 91*0Sstevel@tonic-gate MD_SET_RELEASE = 2 92*0Sstevel@tonic-gate }set_iostate_t; 93*0Sstevel@tonic-gate 94*0Sstevel@tonic-gate /* 95*0Sstevel@tonic-gate * for md_dev64_t translation 96*0Sstevel@tonic-gate */ 97*0Sstevel@tonic-gate struct md_xlate_table { 98*0Sstevel@tonic-gate dev32_t mini_devt; 99*0Sstevel@tonic-gate dev32_t targ_devt; 100*0Sstevel@tonic-gate }; 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gate extern struct md_xlate_table *md_tuple_table; 103*0Sstevel@tonic-gate 104*0Sstevel@tonic-gate /* 105*0Sstevel@tonic-gate * for major number translation 106*0Sstevel@tonic-gate */ 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gate struct md_xlate_major_table { 109*0Sstevel@tonic-gate char *drv_name; 110*0Sstevel@tonic-gate major_t targ_maj; 111*0Sstevel@tonic-gate }; 112*0Sstevel@tonic-gate 113*0Sstevel@tonic-gate extern struct md_xlate_major_table *md_major_tuple_table; 114*0Sstevel@tonic-gate 115*0Sstevel@tonic-gate extern int md_tuple_length; 116*0Sstevel@tonic-gate extern uint_t md_majortab_len; 117*0Sstevel@tonic-gate extern int md_in_upgrade; 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gate extern md_mn_nodeid_t md_mn_mynode_id; 120*0Sstevel@tonic-gate 121*0Sstevel@tonic-gate #define MD_UPGRADE (md_in_upgrade == 1) 122*0Sstevel@tonic-gate 123*0Sstevel@tonic-gate /* 124*0Sstevel@tonic-gate * Flags used during upgrade: 125*0Sstevel@tonic-gate * 126*0Sstevel@tonic-gate * md_keep_repl_state flag means that mddb should be kept in the format 127*0Sstevel@tonic-gate * that was found on disk (non-device id format vs. device id format). 128*0Sstevel@tonic-gate * This is used during the upgrade process when install is probing 129*0Sstevel@tonic-gate * for root disks so that the user can choose the one to be upgraded. 130*0Sstevel@tonic-gate * 131*0Sstevel@tonic-gate * md_devid_destroy flag is used to destroy device ids stored in the 132*0Sstevel@tonic-gate * metadevice state database (mddb). 133*0Sstevel@tonic-gate * 134*0Sstevel@tonic-gate * The md_devid_destroy flag is to be used only in a catastrophic failure 135*0Sstevel@tonic-gate * case. An example of this would be if a user upgrades firmware on all 136*0Sstevel@tonic-gate * disks where this causes the disks to now have different device id's. 137*0Sstevel@tonic-gate * The user would not be able to boot a mirror'd root filesystem since the 138*0Sstevel@tonic-gate * system would recognize none of the device id's stored in the mddb. 139*0Sstevel@tonic-gate * This flag would destroy all device id information stored in the mddb and 140*0Sstevel@tonic-gate * if the md_keep_repl_state flag was not set, the mddb would be reconverted 141*0Sstevel@tonic-gate * to device id format on SLVM startup and all of the device id 142*0Sstevel@tonic-gate * information would be regenerated. 143*0Sstevel@tonic-gate * 144*0Sstevel@tonic-gate * If the md_devid_destroy flag is set and the md_keep_repl_state flag is 145*0Sstevel@tonic-gate * set, the mddb's would have their device id information destroyed and 146*0Sstevel@tonic-gate * would be left in non-devid format since the device id information would 147*0Sstevel@tonic-gate * not be regenerated. 148*0Sstevel@tonic-gate * 149*0Sstevel@tonic-gate * This flag is not documented anywhere and is only to be used as a last 150*0Sstevel@tonic-gate * resort as in the described case or if a device driver has a bug where 151*0Sstevel@tonic-gate * device id's are found to not be unique. If device id's aren't unique, 152*0Sstevel@tonic-gate * the user could run without device id's until a patch is released for 153*0Sstevel@tonic-gate * that driver. 154*0Sstevel@tonic-gate */ 155*0Sstevel@tonic-gate extern int md_keep_repl_state; 156*0Sstevel@tonic-gate extern int md_devid_destroy; 157*0Sstevel@tonic-gate extern int mdmn_door_did; 158*0Sstevel@tonic-gate #ifdef _KERNEL 159*0Sstevel@tonic-gate extern door_handle_t mdmn_door_handle; 160*0Sstevel@tonic-gate #endif /* _KERNEL */ 161*0Sstevel@tonic-gate 162*0Sstevel@tonic-gate /* 163*0Sstevel@tonic-gate * An io_lock mechanism for raid, the MD_UL_XXXX bits are used for 164*0Sstevel@tonic-gate * convenience. 165*0Sstevel@tonic-gate */ 166*0Sstevel@tonic-gate typedef struct md_io_lock { 167*0Sstevel@tonic-gate ulong_t io_readercnt; /* number of unit readers */ 168*0Sstevel@tonic-gate ulong_t io_wanabecnt; /* # pending on becoming unit writer */ 169*0Sstevel@tonic-gate ulong_t io_lock; 170*0Sstevel@tonic-gate void *io_list_front; 171*0Sstevel@tonic-gate void *io_list_back; 172*0Sstevel@tonic-gate kmutex_t io_mx; 173*0Sstevel@tonic-gate kcondvar_t io_cv; 174*0Sstevel@tonic-gate kmutex_t io_list_mutex; /* list of waiting io */ 175*0Sstevel@tonic-gate kthread_id_t io_owner; /* writer thread */ 176*0Sstevel@tonic-gate } md_io_lock_t; 177*0Sstevel@tonic-gate 178*0Sstevel@tonic-gate /* 179*0Sstevel@tonic-gate * The following flags are in un_flag field of mdc_unit struct. 180*0Sstevel@tonic-gate */ 181*0Sstevel@tonic-gate #define MD_LABELED 0x1 /* First sector of the metadevice is a label */ 182*0Sstevel@tonic-gate #define MD_EFILABEL 0x2 /* This md has an EFI label and no vtoc */ 183*0Sstevel@tonic-gate 184*0Sstevel@tonic-gate /* 185*0Sstevel@tonic-gate * This is the number of bytes a DKIOCGETEFI ioctl returns 186*0Sstevel@tonic-gate * For now it's one time the header and once the size for a partition info 187*0Sstevel@tonic-gate */ 188*0Sstevel@tonic-gate #define MD_EFI_LABEL_SIZE (sizeof (efi_gpt_t) + sizeof (efi_gpe_t)) 189*0Sstevel@tonic-gate 190*0Sstevel@tonic-gate /* This is the number of bytes consumed by efi_gpe_PartitionName */ 191*0Sstevel@tonic-gate #define MD_EFI_PARTNAME_BYTES (EFI_PART_NAME_LEN * sizeof (ushort_t)) 192*0Sstevel@tonic-gate 193*0Sstevel@tonic-gate typedef enum hs_cmds { 194*0Sstevel@tonic-gate HS_GET, HS_FREE, HS_BAD, HSP_INCREF, HSP_DECREF, HS_MKDEV 195*0Sstevel@tonic-gate } hs_cmds_t; 196*0Sstevel@tonic-gate 197*0Sstevel@tonic-gate typedef struct md_link { 198*0Sstevel@tonic-gate struct md_link *ln_next; 199*0Sstevel@tonic-gate set_t ln_setno; 200*0Sstevel@tonic-gate uint_t ln_id; 201*0Sstevel@tonic-gate } md_link_t; 202*0Sstevel@tonic-gate 203*0Sstevel@tonic-gate typedef struct mdi_unit { 204*0Sstevel@tonic-gate md_link_t ui_link; 205*0Sstevel@tonic-gate ulong_t ui_readercnt; /* number of unit readers */ 206*0Sstevel@tonic-gate ulong_t ui_wanabecnt; /* # pending on becoming unit writer */ 207*0Sstevel@tonic-gate ulong_t ui_lock; 208*0Sstevel@tonic-gate kmutex_t ui_mx; 209*0Sstevel@tonic-gate kcondvar_t ui_cv; 210*0Sstevel@tonic-gate int ui_opsindex; 211*0Sstevel@tonic-gate uint_t ui_ocnt[OTYPCNT]; /* open counts */ 212*0Sstevel@tonic-gate md_io_lock_t *ui_io_lock; /* pointer to io lock */ 213*0Sstevel@tonic-gate kstat_t *ui_kstat; /* kernel statistics */ 214*0Sstevel@tonic-gate kthread_id_t ui_owner; /* writer thread */ 215*0Sstevel@tonic-gate uint_t ui_tstate; /* transient state bits */ 216*0Sstevel@tonic-gate uint_t ui_capab; /* Capability bits supported */ 217*0Sstevel@tonic-gate } mdi_unit_t; 218*0Sstevel@tonic-gate 219*0Sstevel@tonic-gate /* 220*0Sstevel@tonic-gate * Following are used with ui_lock 221*0Sstevel@tonic-gate * which is in the unit incore structure. 222*0Sstevel@tonic-gate */ 223*0Sstevel@tonic-gate #define MD_UL_WRITER 0x0001 /* Stall all new strategy calls */ 224*0Sstevel@tonic-gate #define MD_UL_WANABEWRITER 0x0002 225*0Sstevel@tonic-gate #define MD_UL_OPENORCLOSE 0x0004 226*0Sstevel@tonic-gate 227*0Sstevel@tonic-gate #define MD_UL_OPEN 0x0008 /* unit is open */ 228*0Sstevel@tonic-gate #define MD_UL_EXCL 0x0010 /* unit is open exclusively */ 229*0Sstevel@tonic-gate 230*0Sstevel@tonic-gate /* 231*0Sstevel@tonic-gate * The softpart open code may do an I/O to validate the watermarks 232*0Sstevel@tonic-gate * and should hold no open locks during this I/O. So, mark the unit 233*0Sstevel@tonic-gate * as OPENINPROGRESS and drop the locks. This will keep any other 234*0Sstevel@tonic-gate * softpart open's waiting until the validate has completed. 235*0Sstevel@tonic-gate */ 236*0Sstevel@tonic-gate #define MD_UL_OPENINPROGRESS 0x0020 /* Open in Progress */ 237*0Sstevel@tonic-gate 238*0Sstevel@tonic-gate /* 239*0Sstevel@tonic-gate * Following are used with ui_tstate to specify any transient states which 240*0Sstevel@tonic-gate * occur during metadevice operation. These are not written to the metadb as 241*0Sstevel@tonic-gate * they do not represent a failure of the underlying metadevice. 242*0Sstevel@tonic-gate * Transient errors are stored in the lower 16 bits and other transient 243*0Sstevel@tonic-gate * state is stored in the upper 16 bits. 244*0Sstevel@tonic-gate * MD_NOTOPENABLE should contain all the states that are set prior to an 245*0Sstevel@tonic-gate * open (by snarf) and that indicate that a metadevice cannot be opened. 246*0Sstevel@tonic-gate */ 247*0Sstevel@tonic-gate #define MD_DEV_ERRORED 0x0000ffff /* ui_tstate error bits */ 248*0Sstevel@tonic-gate #define MD_EOF_METADEVICE 0x00000001 /* EOF'd metadevice */ 249*0Sstevel@tonic-gate #define MD_64MD_ON_32KERNEL 0x00000002 /* 64bit metadev on 32bit kernel */ 250*0Sstevel@tonic-gate #define MD_INACCESSIBLE 0x00000004 /* metadevice unavailable */ 251*0Sstevel@tonic-gate #define MD_RETRYING 0x00010000 /* retrying errored failfast I/O */ 252*0Sstevel@tonic-gate #define MD_OPENLOCKED 0x00020000 /* MN: open locked before removing */ 253*0Sstevel@tonic-gate #define MD_ERR_PENDING 0x00040000 /* MN: error pending */ 254*0Sstevel@tonic-gate #define MD_ABR_CAP 0x00080000 /* MN: Application Based Recovery */ 255*0Sstevel@tonic-gate #define MD_DMR_CAP 0x00100000 /* MN: Directed Mirror Read */ 256*0Sstevel@tonic-gate #define MD_RELEASE_IOERR_DONE 0x00200000 /* ioerr console message done */ 257*0Sstevel@tonic-gate #define MD_RESYNC_NOT_DONE 0x00400000 /* resync not done yet */ 258*0Sstevel@tonic-gate 259*0Sstevel@tonic-gate /* A metadevice cannot be opened when these states are set */ 260*0Sstevel@tonic-gate #define MD_NOTOPENABLE (MD_EOF_METADEVICE|MD_64MD_ON_32KERNEL) 261*0Sstevel@tonic-gate 262*0Sstevel@tonic-gate typedef struct md_ioctl_lock { 263*0Sstevel@tonic-gate int l_flags; /* locks held */ 264*0Sstevel@tonic-gate mdi_unit_t *l_ui; /* unit for which lock is held */ 265*0Sstevel@tonic-gate } md_ioctl_lock_t; 266*0Sstevel@tonic-gate 267*0Sstevel@tonic-gate #define MD_MASTER_DROPPED 0x0001 268*0Sstevel@tonic-gate #define MD_READER_HELD 0x0002 269*0Sstevel@tonic-gate #define MD_WRITER_HELD 0x0004 270*0Sstevel@tonic-gate #define MD_IO_HELD 0x0008 271*0Sstevel@tonic-gate #define MD_ARRAY_READER 0x0010 272*0Sstevel@tonic-gate #define MD_ARRAY_WRITER 0x0020 273*0Sstevel@tonic-gate #define STALE_OK 0x0100 274*0Sstevel@tonic-gate #define NO_OLD 0x0200 275*0Sstevel@tonic-gate #define NO_LOCK 0x0400 276*0Sstevel@tonic-gate #define MD_MT_IOCTL 0x80000 /* MD_GBL_IOCTL_LOCK not set */ 277*0Sstevel@tonic-gate #define IOLOCK md_ioctl_lock_t 278*0Sstevel@tonic-gate 279*0Sstevel@tonic-gate #define WR_LOCK MD_WRITER_HELD 280*0Sstevel@tonic-gate #define RD_LOCK MD_READER_HELD | STALE_OK 281*0Sstevel@tonic-gate #define ARRAY_WRITER MD_ARRAY_WRITER 282*0Sstevel@tonic-gate #define ARRAY_READER MD_ARRAY_READER 283*0Sstevel@tonic-gate #define WRITERS MD_WRITER_HELD | MD_IO_HELD | MD_ARRAY_WRITER 284*0Sstevel@tonic-gate #define READERS RD_LOCK | MD_ARRAY_READER 285*0Sstevel@tonic-gate 286*0Sstevel@tonic-gate #define IOLOCK_RETURN_IOCTLEND(code, lock) \ 287*0Sstevel@tonic-gate md_ioctl_lock_exit((code), (lock)->l_flags, (lock)->l_ui, TRUE) 288*0Sstevel@tonic-gate 289*0Sstevel@tonic-gate #define IOLOCK_RETURN(code, lock) \ 290*0Sstevel@tonic-gate md_ioctl_lock_exit((code), (lock)->l_flags, (lock)->l_ui, FALSE) 291*0Sstevel@tonic-gate 292*0Sstevel@tonic-gate #define IOLOCK_RETURN_RELEASE(code, lock) \ 293*0Sstevel@tonic-gate md_ioctl_releaselocks((code), (lock)->l_flags, (lock)->l_ui) 294*0Sstevel@tonic-gate 295*0Sstevel@tonic-gate #define IOLOCK_RETURN_REACQUIRE(lock) \ 296*0Sstevel@tonic-gate md_ioctl_reacquirelocks((lock)->l_flags, (lock)->l_ui) 297*0Sstevel@tonic-gate 298*0Sstevel@tonic-gate #define IOLOCK_INIT(lock) bzero((caddr_t)(lock), sizeof (*(lock))) 299*0Sstevel@tonic-gate /* 300*0Sstevel@tonic-gate * checks to be sure locks are held 301*0Sstevel@tonic-gate */ 302*0Sstevel@tonic-gate #define UNIT_WRITER_HELD(un) \ 303*0Sstevel@tonic-gate (MDI_UNIT(MD_SID(un))->ui_lock & MD_UL_WRITER) 304*0Sstevel@tonic-gate #define UNIT_READER_HELD(un) \ 305*0Sstevel@tonic-gate (MDI_UNIT(MD_SID(un))->ui_readercnt != 0) 306*0Sstevel@tonic-gate #define IO_WRITER_HELD(un) \ 307*0Sstevel@tonic-gate (MDI_UNIT(MD_SID(un))->ui_io_lock->io_lock & MD_UL_WRITER) 308*0Sstevel@tonic-gate #define IO_READER_HELD(un) \ 309*0Sstevel@tonic-gate (MDI_UNIT(MD_SID(un))->ui_io_lock->io_readercnt != 0) 310*0Sstevel@tonic-gate 311*0Sstevel@tonic-gate #ifdef DEBUG 312*0Sstevel@tonic-gate #define STAT_INC(statvar) \ 313*0Sstevel@tonic-gate statvar++ 314*0Sstevel@tonic-gate #define STAT_DEC(statvar) \ 315*0Sstevel@tonic-gate statvar-- 316*0Sstevel@tonic-gate #define STAT_ZERO(statvar) \ 317*0Sstevel@tonic-gate statvar = 0; 318*0Sstevel@tonic-gate #define STAT_MAX(statmax, statvar) \ 319*0Sstevel@tonic-gate { \ 320*0Sstevel@tonic-gate statvar++; \ 321*0Sstevel@tonic-gate if (statvar > statmax) \ 322*0Sstevel@tonic-gate statmax = statvar; \ 323*0Sstevel@tonic-gate } 324*0Sstevel@tonic-gate #define STAT_CHECK(statvar, value) \ 325*0Sstevel@tonic-gate { \ 326*0Sstevel@tonic-gate if (value) \ 327*0Sstevel@tonic-gate statvar++; \ 328*0Sstevel@tonic-gate } 329*0Sstevel@tonic-gate #else 330*0Sstevel@tonic-gate #define STAT_INC(statvar) 331*0Sstevel@tonic-gate #define STAT_DEC(statvar) 332*0Sstevel@tonic-gate #define STAT_ZERO(statvar) 333*0Sstevel@tonic-gate #define STAT_MAX(statmax, statvar) 334*0Sstevel@tonic-gate #define STAT_CHECK(statvar, value) 335*0Sstevel@tonic-gate #endif 336*0Sstevel@tonic-gate /* 337*0Sstevel@tonic-gate * bit map related macros 338*0Sstevel@tonic-gate */ 339*0Sstevel@tonic-gate #define setbit(a, i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY)) 340*0Sstevel@tonic-gate #define clrbit(a, i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) 341*0Sstevel@tonic-gate #define isset(a, i) ((a)[(i)/NBBY] & (1<<((i)%NBBY))) 342*0Sstevel@tonic-gate #define isclr(a, i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) 343*0Sstevel@tonic-gate 344*0Sstevel@tonic-gate typedef struct daemon_queue { 345*0Sstevel@tonic-gate int maxq_len; 346*0Sstevel@tonic-gate int qlen; 347*0Sstevel@tonic-gate int treqs; /* total number of requests */ 348*0Sstevel@tonic-gate struct daemon_queue *dq_next; 349*0Sstevel@tonic-gate struct daemon_queue *dq_prev; 350*0Sstevel@tonic-gate void (*dq_call)(); 351*0Sstevel@tonic-gate } daemon_queue_t; 352*0Sstevel@tonic-gate 353*0Sstevel@tonic-gate #define DAEMON_QUEUE daemon_queue_t dq; 354*0Sstevel@tonic-gate 355*0Sstevel@tonic-gate #ifdef _KERNEL 356*0Sstevel@tonic-gate #include <sys/buf.h> 357*0Sstevel@tonic-gate #include <sys/dkio.h> 358*0Sstevel@tonic-gate #include <sys/vtoc.h> 359*0Sstevel@tonic-gate 360*0Sstevel@tonic-gate #define MD_DEV2SET(d) (MD_MIN2SET(md_getminor(d))) 361*0Sstevel@tonic-gate 362*0Sstevel@tonic-gate #define MD_UNIT(m) (md_set[MD_MIN2SET(m)].s_un[MD_MIN2UNIT(m)]) 363*0Sstevel@tonic-gate #define MDI_UNIT(m) ((mdi_unit_t *) \ 364*0Sstevel@tonic-gate md_set[MD_MIN2SET(m)].s_ui[MD_MIN2UNIT(m)]) 365*0Sstevel@tonic-gate #define MD_VOIDUNIT(m) (md_set[MD_MIN2SET(m)].s_un[MD_MIN2UNIT(m)]) 366*0Sstevel@tonic-gate #define MDI_VOIDUNIT(m) (md_set[MD_MIN2SET(m)].s_ui[MD_MIN2UNIT(m)]) 367*0Sstevel@tonic-gate 368*0Sstevel@tonic-gate /* 369*0Sstevel@tonic-gate * This is the current maximum number of real disks per Virtual Disk. 370*0Sstevel@tonic-gate */ 371*0Sstevel@tonic-gate extern uint_t md_mdelay; /* md_mirror timeout delay */ 372*0Sstevel@tonic-gate 373*0Sstevel@tonic-gate #define MD_ADM_MINOR L_MAXMIN32 /* the minor number for md_admin */ 374*0Sstevel@tonic-gate #define MD_MDELAY (md_mdelay) 375*0Sstevel@tonic-gate #define NUM_USEC_IN_SEC 1000000 /* 1 million usec in a second */ 376*0Sstevel@tonic-gate 377*0Sstevel@tonic-gate #define ANY_SERVICE -1 /* md_get_named_service() wild card */ 378*0Sstevel@tonic-gate 379*0Sstevel@tonic-gate /* 380*0Sstevel@tonic-gate * daemon threads are used in multiple places in md. The following set of 381*0Sstevel@tonic-gate * structures and routines allow a common way to create and initialize them. 382*0Sstevel@tonic-gate * 383*0Sstevel@tonic-gate * md_requestq_entry_t - entry of creating request queues. 384*0Sstevel@tonic-gate * struct mdq_anchor - request queue header 385*0Sstevel@tonic-gate * 386*0Sstevel@tonic-gate * Functions associated with request queues: 387*0Sstevel@tonic-gate * 388*0Sstevel@tonic-gate * int init_requestq_entry - 389*0Sstevel@tonic-gate * void daemon_request - put a request on the queue. 390*0Sstevel@tonic-gate */ 391*0Sstevel@tonic-gate 392*0Sstevel@tonic-gate typedef struct md_requestq_entry { 393*0Sstevel@tonic-gate struct mdq_anchor *dispq_headp; 394*0Sstevel@tonic-gate int *num_threadsp; /* threads servicing the queue */ 395*0Sstevel@tonic-gate } md_requestq_entry_t; 396*0Sstevel@tonic-gate 397*0Sstevel@tonic-gate #define NULL_REQUESTQ_ENTRY(rqp)\ 398*0Sstevel@tonic-gate ((rqp)->dispq_headp == NULL || (rqp)->num_threadsp == NULL) 399*0Sstevel@tonic-gate 400*0Sstevel@tonic-gate /* this typedef is used to differentiate between the two call styles */ 401*0Sstevel@tonic-gate typedef enum callstyle { 402*0Sstevel@tonic-gate REQ_OLD, 403*0Sstevel@tonic-gate REQ_NEW 404*0Sstevel@tonic-gate } callstyle_t; 405*0Sstevel@tonic-gate 406*0Sstevel@tonic-gate 407*0Sstevel@tonic-gate #define daemon_request_new daemon_request 408*0Sstevel@tonic-gate 409*0Sstevel@tonic-gate typedef struct mdq_anchor { 410*0Sstevel@tonic-gate DAEMON_QUEUE 411*0Sstevel@tonic-gate kcondvar_t a_cv; /* Request has been put on queue */ 412*0Sstevel@tonic-gate kmutex_t a_mx; 413*0Sstevel@tonic-gate } mdq_anchor_t; 414*0Sstevel@tonic-gate 415*0Sstevel@tonic-gate typedef struct daemon_request { 416*0Sstevel@tonic-gate DAEMON_QUEUE 417*0Sstevel@tonic-gate kmutex_t dr_mx; 418*0Sstevel@tonic-gate int dr_pending; 419*0Sstevel@tonic-gate timeout_id_t dr_timeout_id; 420*0Sstevel@tonic-gate } daemon_request_t; 421*0Sstevel@tonic-gate 422*0Sstevel@tonic-gate typedef struct sv_dev { 423*0Sstevel@tonic-gate set_t setno; 424*0Sstevel@tonic-gate side_t side; 425*0Sstevel@tonic-gate mdkey_t key; 426*0Sstevel@tonic-gate } sv_dev_t; 427*0Sstevel@tonic-gate 428*0Sstevel@tonic-gate /* 429*0Sstevel@tonic-gate * Types of device probes 430*0Sstevel@tonic-gate */ 431*0Sstevel@tonic-gate 432*0Sstevel@tonic-gate 433*0Sstevel@tonic-gate typedef struct probe_req { 434*0Sstevel@tonic-gate DAEMON_QUEUE 435*0Sstevel@tonic-gate minor_t mnum; /* mnum of the metadevice to probe */ 436*0Sstevel@tonic-gate void *private_handle; /* private handle */ 437*0Sstevel@tonic-gate intptr_t (*probe_fcn)(); /* type of probeing to be done */ 438*0Sstevel@tonic-gate } probe_req_t; 439*0Sstevel@tonic-gate 440*0Sstevel@tonic-gate /* Global flags */ 441*0Sstevel@tonic-gate #define MD_NO_GBL_LOCKS_HELD 0x0000 /* currently holding no global locks */ 442*0Sstevel@tonic-gate #define MD_GBL_DAEMONS_LIVE 0x0001 /* master daemon has been started. */ 443*0Sstevel@tonic-gate #define MD_GBL_DAEMONS_DIE 0x0002 444*0Sstevel@tonic-gate #define MD_GBL_HALTED 0x0004 /* driver is shut down */ 445*0Sstevel@tonic-gate 446*0Sstevel@tonic-gate /* Available bit was GBL_STALE 0x0008 */ 447*0Sstevel@tonic-gate 448*0Sstevel@tonic-gate #define MD_GBL_IOCTL_LOCK 0x0010 /* single-threads ioctls */ 449*0Sstevel@tonic-gate #define MD_GBL_HS_LOCK 0x0020 /* single-threads hotspares */ 450*0Sstevel@tonic-gate #define MD_GBL_OPEN 0x0040 /* admin is open */ 451*0Sstevel@tonic-gate #define MD_GBL_EXCL 0x0080 /* admin is open exclusively */ 452*0Sstevel@tonic-gate 453*0Sstevel@tonic-gate #define MD_OFLG_NULL 0x0000 /* Null flag */ 454*0Sstevel@tonic-gate #define MD_OFLG_CONT_ERRS 0x0001 /* Continue on open errors */ 455*0Sstevel@tonic-gate #define MD_OFLG_PROBEDEV 0x0002 /* force a simulated open */ 456*0Sstevel@tonic-gate #define MD_OFLG_ISINIT 0x0004 /* raid initialization */ 457*0Sstevel@tonic-gate #define MD_OFLG_FROMIOCTL 0x0008 /* Called from an ioctl handler */ 458*0Sstevel@tonic-gate 459*0Sstevel@tonic-gate 460*0Sstevel@tonic-gate typedef struct md_named_services { 461*0Sstevel@tonic-gate 462*0Sstevel@tonic-gate intptr_t (*md_service)(); 463*0Sstevel@tonic-gate char *md_name; 464*0Sstevel@tonic-gate } md_named_services_t; 465*0Sstevel@tonic-gate 466*0Sstevel@tonic-gate typedef enum md_snarfcmd {MD_SNARF_CLEANUP, MD_SNARF_DOIT} md_snarfcmd_t; 467*0Sstevel@tonic-gate 468*0Sstevel@tonic-gate typedef struct md_ops { 469*0Sstevel@tonic-gate int (*md_open)( 470*0Sstevel@tonic-gate dev_t *devp, 471*0Sstevel@tonic-gate int flag, 472*0Sstevel@tonic-gate int otyp, 473*0Sstevel@tonic-gate cred_t *credp, 474*0Sstevel@tonic-gate int md_oflags); 475*0Sstevel@tonic-gate int (*md_close)( 476*0Sstevel@tonic-gate dev_t dev, 477*0Sstevel@tonic-gate int flag, 478*0Sstevel@tonic-gate int otyp, 479*0Sstevel@tonic-gate cred_t *credp, 480*0Sstevel@tonic-gate int md_oflags); 481*0Sstevel@tonic-gate void (*md_strategy)( 482*0Sstevel@tonic-gate buf_t *bufp, 483*0Sstevel@tonic-gate int flag, 484*0Sstevel@tonic-gate void *private); 485*0Sstevel@tonic-gate int (*md_print)(); /* unused now */ 486*0Sstevel@tonic-gate int (*md_dump)( 487*0Sstevel@tonic-gate dev_t dev, 488*0Sstevel@tonic-gate caddr_t addr, 489*0Sstevel@tonic-gate daddr_t blkno, 490*0Sstevel@tonic-gate int nblk); 491*0Sstevel@tonic-gate int (*md_read)( 492*0Sstevel@tonic-gate dev_t dev, 493*0Sstevel@tonic-gate struct uio *uiop, 494*0Sstevel@tonic-gate cred_t *credp); 495*0Sstevel@tonic-gate int (*md_write)( 496*0Sstevel@tonic-gate dev_t dev, 497*0Sstevel@tonic-gate struct uio *uiop, 498*0Sstevel@tonic-gate cred_t *credp); 499*0Sstevel@tonic-gate int (*md_ioctl)( 500*0Sstevel@tonic-gate dev_t dev, 501*0Sstevel@tonic-gate int cmd, 502*0Sstevel@tonic-gate void *data, 503*0Sstevel@tonic-gate int mode, 504*0Sstevel@tonic-gate IOLOCK *lockp); 505*0Sstevel@tonic-gate int (*md_snarf)( 506*0Sstevel@tonic-gate md_snarfcmd_t cmd, 507*0Sstevel@tonic-gate set_t setno); 508*0Sstevel@tonic-gate int (*md_halt)(); 509*0Sstevel@tonic-gate int (*md_aread)( 510*0Sstevel@tonic-gate dev_t dev, 511*0Sstevel@tonic-gate struct aio_req *aiop, 512*0Sstevel@tonic-gate cred_t *credp); 513*0Sstevel@tonic-gate int (*md_awrite)( 514*0Sstevel@tonic-gate dev_t dev, 515*0Sstevel@tonic-gate struct aio_req *aiop, 516*0Sstevel@tonic-gate cred_t *credp); 517*0Sstevel@tonic-gate int (*md_imp_set)( 518*0Sstevel@tonic-gate set_t setno); 519*0Sstevel@tonic-gate md_named_services_t *md_services; 520*0Sstevel@tonic-gate md_krwlock_t md_link_rw; 521*0Sstevel@tonic-gate md_link_t *md_head; 522*0Sstevel@tonic-gate /* 523*0Sstevel@tonic-gate * NOTE: when TSlvm s10/onnv compatibility is not an issue: 524*0Sstevel@tonic-gate * o md_modid and md_locked should be deleted. 525*0Sstevel@tonic-gate * o md_mod should be added 526*0Sstevel@tonic-gate * ddi_modhandle_t md_mod; 527*0Sstevel@tonic-gate * and used instead of the md_mods array (md_mods should 528*0Sstevel@tonic-gate * be deleted). 529*0Sstevel@tonic-gate */ 530*0Sstevel@tonic-gate int md_modid; 531*0Sstevel@tonic-gate int md_locked; 532*0Sstevel@tonic-gate int md_selfindex; 533*0Sstevel@tonic-gate struct md_ops *md_next; 534*0Sstevel@tonic-gate md_driver_t md_driver; 535*0Sstevel@tonic-gate /* NOTE: TSlvm depends on offsets in and sizeof this structure */ 536*0Sstevel@tonic-gate } md_ops_t; 537*0Sstevel@tonic-gate 538*0Sstevel@tonic-gate /* macro to generate linkage for a md misc plugin module */ 539*0Sstevel@tonic-gate #define md_noop 540*0Sstevel@tonic-gate #define MD_PLUGIN_MISC_MODULE(desc, init_init, fini_uninit) \ 541*0Sstevel@tonic-gate static struct modlmisc modlmisc = { \ 542*0Sstevel@tonic-gate &mod_miscops, "Solaris Volume Manager " desc \ 543*0Sstevel@tonic-gate }; \ 544*0Sstevel@tonic-gate static struct modlinkage modlinkage = { \ 545*0Sstevel@tonic-gate MODREV_1, (void *)&modlmisc, NULL \ 546*0Sstevel@tonic-gate }; \ 547*0Sstevel@tonic-gate int \ 548*0Sstevel@tonic-gate _init(void) \ 549*0Sstevel@tonic-gate { \ 550*0Sstevel@tonic-gate int i; \ 551*0Sstevel@tonic-gate init_init; \ 552*0Sstevel@tonic-gate if ((i = mod_install(&modlinkage)) != 0) { \ 553*0Sstevel@tonic-gate fini_uninit; \ 554*0Sstevel@tonic-gate } \ 555*0Sstevel@tonic-gate return (i); \ 556*0Sstevel@tonic-gate } \ 557*0Sstevel@tonic-gate int \ 558*0Sstevel@tonic-gate _fini() \ 559*0Sstevel@tonic-gate { \ 560*0Sstevel@tonic-gate int i; \ 561*0Sstevel@tonic-gate if ((i = mod_remove(&modlinkage)) == 0) { \ 562*0Sstevel@tonic-gate fini_uninit; \ 563*0Sstevel@tonic-gate } \ 564*0Sstevel@tonic-gate return (i); \ 565*0Sstevel@tonic-gate } \ 566*0Sstevel@tonic-gate int \ 567*0Sstevel@tonic-gate _info(struct modinfo *modinfop) \ 568*0Sstevel@tonic-gate { \ 569*0Sstevel@tonic-gate return (mod_info(&modlinkage, modinfop)); \ 570*0Sstevel@tonic-gate } 571*0Sstevel@tonic-gate 572*0Sstevel@tonic-gate typedef enum md_haltcmd {MD_HALT_ALL, MD_HALT_CHECK, MD_HALT_DOIT, 573*0Sstevel@tonic-gate MD_HALT_CLOSE, MD_HALT_OPEN, MD_HALT_UNLOAD 574*0Sstevel@tonic-gate } md_haltcmd_t; 575*0Sstevel@tonic-gate 576*0Sstevel@tonic-gate /* 577*0Sstevel@tonic-gate * To support cpr (Energy Star) we need to know when the resync threads are 578*0Sstevel@tonic-gate * running to not allow suspention. 579*0Sstevel@tonic-gate */ 580*0Sstevel@tonic-gate typedef struct md_resync_thds_cnt { 581*0Sstevel@tonic-gate int md_raid_resync; /* count of active raid resync threads */ 582*0Sstevel@tonic-gate int md_mirror_resync; /* count of active mirror resync threads */ 583*0Sstevel@tonic-gate kmutex_t md_resync_mutex; /* protects both resync counts */ 584*0Sstevel@tonic-gate } md_resync_t; 585*0Sstevel@tonic-gate 586*0Sstevel@tonic-gate /* 587*0Sstevel@tonic-gate * flags used with call to individual strategy routines 588*0Sstevel@tonic-gate */ 589*0Sstevel@tonic-gate #define MD_STR_PASSEDON 0x0000ffff 590*0Sstevel@tonic-gate #define MD_STR_NOTTOP 0x00000001 591*0Sstevel@tonic-gate #define MD_STR_MAPPED 0x00000002 /* set when buf_t is mapped in */ 592*0Sstevel@tonic-gate #define MD_STR_ABR 0x00000004 /* use ABR to handle any recovery */ 593*0Sstevel@tonic-gate #define MD_STR_WMUPDATE 0x00000008 /* set if updating watermarks for sp */ 594*0Sstevel@tonic-gate #define MD_IO_COUNTED 0x00000400 /* io has been counted */ 595*0Sstevel@tonic-gate #define MD_NOBLOCK 0x00000800 /* do not block io durring release */ 596*0Sstevel@tonic-gate 597*0Sstevel@tonic-gate #define MD_STR_WAR 0x00010000 /* this write is write after read */ 598*0Sstevel@tonic-gate #define MD_STR_WOW 0x00020000 /* handling a write-on-write */ 599*0Sstevel@tonic-gate #define MD_STR_DMR 0x00040000 /* Directed Read request */ 600*0Sstevel@tonic-gate #define MD_STR_DIRTY_RD 0x00080000 /* Read of a dirty block */ 601*0Sstevel@tonic-gate #define MD_STR_FLAG_ERR 0x00100000 /* Flag any write error on this i/o */ 602*0Sstevel@tonic-gate 603*0Sstevel@tonic-gate /* 604*0Sstevel@tonic-gate * Bits for return value of md_getdevnum 605*0Sstevel@tonic-gate */ 606*0Sstevel@tonic-gate #define MD_TRUST_DEVT 1 607*0Sstevel@tonic-gate #define MD_NOTRUST_DEVT 0 608*0Sstevel@tonic-gate 609*0Sstevel@tonic-gate /* Flag for drivers to pass to kmem_cache_alloc() */ 610*0Sstevel@tonic-gate #define MD_ALLOCFLAGS (KM_PUSHPAGE | KM_SLEEP) 611*0Sstevel@tonic-gate 612*0Sstevel@tonic-gate /* Named services */ 613*0Sstevel@tonic-gate #define MD_CHECK_OFFLINE "check_offline" 614*0Sstevel@tonic-gate #define MD_INC_ABR_COUNT "inc abr count" 615*0Sstevel@tonic-gate #define MD_DEC_ABR_COUNT "dec abr count" 616*0Sstevel@tonic-gate 617*0Sstevel@tonic-gate /* Externals from md.c */ 618*0Sstevel@tonic-gate extern int md_snarf_db_set(set_t setno, md_error_t *ep); 619*0Sstevel@tonic-gate extern void get_info(struct dk_cinfo *, minor_t); 620*0Sstevel@tonic-gate extern void get_minfo(struct dk_minfo *, minor_t); 621*0Sstevel@tonic-gate extern int mdstrategy(buf_t *); 622*0Sstevel@tonic-gate extern int md_create_minor_node(set_t, minor_t); 623*0Sstevel@tonic-gate 624*0Sstevel@tonic-gate 625*0Sstevel@tonic-gate /* External from md_subr.c */ 626*0Sstevel@tonic-gate extern int md_inc_iocount(set_t); 627*0Sstevel@tonic-gate extern void md_inc_iocount_noblock(set_t); 628*0Sstevel@tonic-gate extern void md_dec_iocount(set_t); 629*0Sstevel@tonic-gate extern int md_isblock_setio(set_t); 630*0Sstevel@tonic-gate extern int md_block_setio(set_t); 631*0Sstevel@tonic-gate extern void md_clearblock_setio(set_t); 632*0Sstevel@tonic-gate extern void md_unblock_setio(set_t); 633*0Sstevel@tonic-gate extern int md_tas_block_setio(set_t); 634*0Sstevel@tonic-gate extern void md_biodone(struct buf *); 635*0Sstevel@tonic-gate extern void md_bioreset(struct buf *); 636*0Sstevel@tonic-gate extern md_dev64_t md_xlate_targ_2_mini(md_dev64_t); 637*0Sstevel@tonic-gate extern md_dev64_t md_xlate_mini_2_targ(md_dev64_t); 638*0Sstevel@tonic-gate extern void md_xlate_free(int); 639*0Sstevel@tonic-gate extern major_t md_targ_name_to_major(char *); 640*0Sstevel@tonic-gate extern char *md_targ_major_to_name(major_t); 641*0Sstevel@tonic-gate extern void md_majortab_free(); 642*0Sstevel@tonic-gate extern void md_set_status(int); 643*0Sstevel@tonic-gate extern void md_clr_status(int); 644*0Sstevel@tonic-gate extern int md_get_status(void); 645*0Sstevel@tonic-gate extern void md_set_setstatus(set_t, int); 646*0Sstevel@tonic-gate extern void md_clr_setstatus(set_t, int); 647*0Sstevel@tonic-gate extern uint_t md_get_setstatus(set_t); 648*0Sstevel@tonic-gate extern void *md_unit_readerlock(mdi_unit_t *); 649*0Sstevel@tonic-gate extern void *md_unit_writerlock(mdi_unit_t *); 650*0Sstevel@tonic-gate extern void md_unit_readerexit(mdi_unit_t *); 651*0Sstevel@tonic-gate extern void md_unit_writerexit(mdi_unit_t *); 652*0Sstevel@tonic-gate extern void md_ioctl_releaselocks(int, int, mdi_unit_t *); 653*0Sstevel@tonic-gate extern void md_ioctl_reacquirelocks(int, mdi_unit_t *); 654*0Sstevel@tonic-gate extern int md_ioctl_lock_exit(int, int, mdi_unit_t *, int); 655*0Sstevel@tonic-gate extern int md_ioctl_lock_enter(void); 656*0Sstevel@tonic-gate extern void *md_ioctl_readerlock(IOLOCK *, mdi_unit_t *); 657*0Sstevel@tonic-gate extern void md_ioctl_readerexit(IOLOCK *); 658*0Sstevel@tonic-gate extern void *md_ioctl_writerlock(IOLOCK *, mdi_unit_t *); 659*0Sstevel@tonic-gate extern void md_ioctl_writerexit(IOLOCK *); 660*0Sstevel@tonic-gate extern void md_ioctl_io_exit(IOLOCK *); 661*0Sstevel@tonic-gate extern void *md_ioctl_io_lock(IOLOCK *, mdi_unit_t *); 662*0Sstevel@tonic-gate extern void md_ioctl_droplocks(IOLOCK *); 663*0Sstevel@tonic-gate extern void md_array_writer(IOLOCK *); 664*0Sstevel@tonic-gate extern void md_array_reader(IOLOCK *); 665*0Sstevel@tonic-gate extern void *md_ioctl_openclose_enter(IOLOCK *, mdi_unit_t *); 666*0Sstevel@tonic-gate extern void md_ioctl_openclose_exit(IOLOCK *); 667*0Sstevel@tonic-gate extern void md_ioctl_openclose_exit_lh(IOLOCK *); 668*0Sstevel@tonic-gate extern void *md_unit_openclose_enter(mdi_unit_t *); 669*0Sstevel@tonic-gate extern void md_unit_openclose_exit(mdi_unit_t *); 670*0Sstevel@tonic-gate extern void md_unit_openclose_exit_lh(mdi_unit_t *); 671*0Sstevel@tonic-gate extern int md_unit_isopen(mdi_unit_t *ui); 672*0Sstevel@tonic-gate extern int md_unit_incopen(minor_t mnum, int flag, int otyp); 673*0Sstevel@tonic-gate extern int md_unit_decopen(minor_t mnum, int otyp); 674*0Sstevel@tonic-gate extern void *md_io_readerlock(mdi_unit_t *); 675*0Sstevel@tonic-gate extern void *md_io_writerlock(mdi_unit_t *); 676*0Sstevel@tonic-gate extern void md_io_readerexit(mdi_unit_t *); 677*0Sstevel@tonic-gate extern void md_io_writerexit(mdi_unit_t *); 678*0Sstevel@tonic-gate extern intptr_t (*md_get_named_service())(); 679*0Sstevel@tonic-gate extern int init_requestq(md_requestq_entry_t *, void (*)(), 680*0Sstevel@tonic-gate caddr_t, int, int); 681*0Sstevel@tonic-gate extern void daemon_request(mdq_anchor_t *, void(*)(), 682*0Sstevel@tonic-gate daemon_queue_t *, callstyle_t); 683*0Sstevel@tonic-gate extern void md_daemon(int, mdq_anchor_t *); 684*0Sstevel@tonic-gate extern void mddb_commitrec_wrapper(mddb_recid_t); 685*0Sstevel@tonic-gate extern void mddb_commitrecs_wrapper(mddb_recid_t *); 686*0Sstevel@tonic-gate extern void mddb_deleterec_wrapper(mddb_recid_t); 687*0Sstevel@tonic-gate extern void md_holdset_enter(set_t setno); 688*0Sstevel@tonic-gate extern void md_holdset_exit(set_t setno); 689*0Sstevel@tonic-gate extern int md_holdset_testandenter(set_t setno); 690*0Sstevel@tonic-gate extern void md_haltsnarf_enter(set_t setno); 691*0Sstevel@tonic-gate extern void md_haltsnarf_exit(set_t setno); 692*0Sstevel@tonic-gate extern void md_haltsnarf_wait(set_t setno); 693*0Sstevel@tonic-gate extern int md_halt_set(set_t setno, enum md_haltcmd cmd); 694*0Sstevel@tonic-gate extern int md_halt(int global_lock_flag); 695*0Sstevel@tonic-gate extern int md_layered_open(minor_t, md_dev64_t *, int); 696*0Sstevel@tonic-gate extern void md_layered_close(md_dev64_t, int); 697*0Sstevel@tonic-gate extern char *md_get_device_name(md_dev64_t); 698*0Sstevel@tonic-gate extern int errdone(mdi_unit_t *, struct buf *, int); 699*0Sstevel@tonic-gate extern int md_checkbuf(mdi_unit_t *, md_unit_t *, buf_t *); 700*0Sstevel@tonic-gate extern int md_start_daemons(int init_queues); 701*0Sstevel@tonic-gate extern int md_loadsubmod(set_t, char *, int); 702*0Sstevel@tonic-gate extern int md_getmodindex(md_driver_t *, int, int); 703*0Sstevel@tonic-gate extern void md_call_strategy(buf_t *, int, void *); 704*0Sstevel@tonic-gate extern int md_call_ioctl(md_dev64_t, int, void *, int, IOLOCK *); 705*0Sstevel@tonic-gate extern void md_rem_link(set_t, int, krwlock_t *, md_link_t **); 706*0Sstevel@tonic-gate extern int md_dev_exists(md_dev64_t); 707*0Sstevel@tonic-gate extern md_parent_t md_get_parent(md_dev64_t); 708*0Sstevel@tonic-gate extern void md_set_parent(md_dev64_t, md_parent_t); 709*0Sstevel@tonic-gate extern void md_reset_parent(md_dev64_t); 710*0Sstevel@tonic-gate extern int md_hot_spare_ifc(hs_cmds_t, mddb_recid_t, u_longlong_t, int, 711*0Sstevel@tonic-gate mddb_recid_t *, mdkey_t *, md_dev64_t *, diskaddr_t *); 712*0Sstevel@tonic-gate extern int md_notify_interface(md_event_cmds_t cmd, md_tags_t type, 713*0Sstevel@tonic-gate set_t set, md_dev64_t dev, md_event_type_t event); 714*0Sstevel@tonic-gate extern void svm_gen_sysevent(char *se_class, char *se_subclass, 715*0Sstevel@tonic-gate uint32_t tag, set_t setno, md_dev64_t devid); 716*0Sstevel@tonic-gate extern void md_create_unit_incore(minor_t, md_ops_t *, int); 717*0Sstevel@tonic-gate extern void md_destroy_unit_incore(minor_t, md_ops_t *); 718*0Sstevel@tonic-gate extern void md_rem_names(sv_dev_t *, int); 719*0Sstevel@tonic-gate struct uio; 720*0Sstevel@tonic-gate extern int md_chk_uio(struct uio *); 721*0Sstevel@tonic-gate extern char *md_shortname(minor_t mnum); 722*0Sstevel@tonic-gate extern char *md_devname(set_t setno, md_dev64_t dev, char *buf, 723*0Sstevel@tonic-gate size_t size); 724*0Sstevel@tonic-gate extern void md_minphys(buf_t *); 725*0Sstevel@tonic-gate extern void md_kstat_init(minor_t mnum); 726*0Sstevel@tonic-gate extern void md_kstat_init_ui(minor_t mnum, mdi_unit_t *ui); 727*0Sstevel@tonic-gate extern void md_kstat_destroy(minor_t mnum); 728*0Sstevel@tonic-gate extern void md_kstat_destroy_ui(mdi_unit_t *ui); 729*0Sstevel@tonic-gate extern void md_kstat_waitq_enter(mdi_unit_t *ui); 730*0Sstevel@tonic-gate extern void md_kstat_waitq_to_runq(mdi_unit_t *ui); 731*0Sstevel@tonic-gate extern void md_kstat_waitq_exit(mdi_unit_t *ui); 732*0Sstevel@tonic-gate extern void md_kstat_runq_enter(mdi_unit_t *ui); 733*0Sstevel@tonic-gate extern void md_kstat_runq_exit(mdi_unit_t *ui); 734*0Sstevel@tonic-gate extern void md_kstat_done(mdi_unit_t *ui, buf_t *bp, int war); 735*0Sstevel@tonic-gate extern pid_t md_getpid(void); 736*0Sstevel@tonic-gate extern proc_t *md_getproc(void); 737*0Sstevel@tonic-gate extern int md_checkpid(pid_t pid, proc_t *proc); 738*0Sstevel@tonic-gate extern char *md_strdup(char *cp); 739*0Sstevel@tonic-gate extern void freestr(char *cp); 740*0Sstevel@tonic-gate extern int md_check_ioctl_against_efi(int, ushort_t); 741*0Sstevel@tonic-gate extern mddb_recid_t md_vtoc_to_efi_record(mddb_recid_t, set_t); 742*0Sstevel@tonic-gate 743*0Sstevel@tonic-gate extern int mdmn_ksend_message(set_t, md_mn_msgtype_t, uint_t, char *, int, 744*0Sstevel@tonic-gate md_mn_kresult_t *); 745*0Sstevel@tonic-gate extern void mdmn_ksend_show_error(int, md_mn_kresult_t *, const char *); 746*0Sstevel@tonic-gate extern int mdmn_send_capability_message(minor_t, volcap_t, IOLOCK *); 747*0Sstevel@tonic-gate extern void mdmn_clear_all_capabilities(minor_t); 748*0Sstevel@tonic-gate extern int md_init_probereq(struct md_probedev_impl *p, 749*0Sstevel@tonic-gate daemon_queue_t **hdrpp); 750*0Sstevel@tonic-gate extern boolean_t callb_md_mrs_cpr(void *, int); 751*0Sstevel@tonic-gate 752*0Sstevel@tonic-gate /* Externals from md_ioctl.c */ 753*0Sstevel@tonic-gate extern int md_mn_is_commd_present(void); 754*0Sstevel@tonic-gate extern void md_mn_clear_commd_present(void); 755*0Sstevel@tonic-gate extern int md_admin_ioctl(md_dev64_t, int, caddr_t, int, IOLOCK *lockp); 756*0Sstevel@tonic-gate extern void md_get_geom(md_unit_t *, struct dk_geom *); 757*0Sstevel@tonic-gate extern void md_get_vtoc(md_unit_t *, struct vtoc *); 758*0Sstevel@tonic-gate extern int md_set_vtoc(md_unit_t *, struct vtoc *); 759*0Sstevel@tonic-gate extern void md_get_cgapart(md_unit_t *, struct dk_map *); 760*0Sstevel@tonic-gate extern void md_get_efi(md_unit_t *, char *); 761*0Sstevel@tonic-gate extern int md_set_efi(md_unit_t *, char *); 762*0Sstevel@tonic-gate extern int md_dkiocgetefi(minor_t, void *, int); 763*0Sstevel@tonic-gate extern int md_dkiocsetefi(minor_t, void *, int); 764*0Sstevel@tonic-gate extern int md_dkiocpartition(minor_t, void *, int); 765*0Sstevel@tonic-gate 766*0Sstevel@tonic-gate 767*0Sstevel@tonic-gate /* Externals from md_names.c */ 768*0Sstevel@tonic-gate extern mdkey_t md_setdevname(set_t, side_t, mdkey_t, char *, minor_t, char *, 769*0Sstevel@tonic-gate set_t); 770*0Sstevel@tonic-gate extern int md_getdevname(set_t, side_t, mdkey_t, md_dev64_t, char *, 771*0Sstevel@tonic-gate size_t); 772*0Sstevel@tonic-gate extern int md_getkeyfromdev(set_t, side_t, md_dev64_t, mdkey_t *, int *); 773*0Sstevel@tonic-gate extern int md_devid_found(set_t, side_t, mdkey_t); 774*0Sstevel@tonic-gate extern int md_getnment(set_t, side_t, mdkey_t, md_dev64_t, 775*0Sstevel@tonic-gate char *, uint_t, major_t *, minor_t *, mdkey_t *); 776*0Sstevel@tonic-gate extern md_dev64_t md_getdevnum(set_t, side_t, mdkey_t, int); 777*0Sstevel@tonic-gate extern mdkey_t md_getnextkey(set_t, side_t, mdkey_t, uint_t *); 778*0Sstevel@tonic-gate extern int md_remdevname(set_t, side_t, mdkey_t); 779*0Sstevel@tonic-gate extern mdkey_t md_setshared_name(set_t, char *, int); 780*0Sstevel@tonic-gate extern char *md_getshared_name(set_t, mdkey_t); 781*0Sstevel@tonic-gate extern int md_remshared_name(set_t, mdkey_t); 782*0Sstevel@tonic-gate extern mdkey_t md_getshared_key(set_t, char *); 783*0Sstevel@tonic-gate extern int md_setshared_data(set_t, uint_t, caddr_t); 784*0Sstevel@tonic-gate extern caddr_t md_getshared_data(set_t, uint_t); 785*0Sstevel@tonic-gate extern int md_load_namespace(set_t, md_error_t *ep, int); 786*0Sstevel@tonic-gate extern void md_unload_namespace(set_t, int); 787*0Sstevel@tonic-gate extern int md_nm_did_chkspace(set_t); 788*0Sstevel@tonic-gate extern void md_bioinit(); 789*0Sstevel@tonic-gate extern buf_t *md_bioclone(buf_t *, off_t, size_t, dev_t, diskaddr_t, 790*0Sstevel@tonic-gate int (*)(buf_t *), buf_t *, int); 791*0Sstevel@tonic-gate extern int md_getdevid(set_t setno, side_t side, mdkey_t key, 792*0Sstevel@tonic-gate ddi_devid_t devid, ushort_t *did_size); 793*0Sstevel@tonic-gate extern int md_getdevidminor(set_t setno, side_t side, mdkey_t key, 794*0Sstevel@tonic-gate char *minorname, size_t minorname_len); 795*0Sstevel@tonic-gate extern int md_update_namespace(set_t setno, side_t side, mdkey_t key, 796*0Sstevel@tonic-gate caddr_t devname, caddr_t pathname, minor_t mnum); 797*0Sstevel@tonic-gate extern int md_update_locator_namespace(set_t setno, side_t side, 798*0Sstevel@tonic-gate caddr_t devname, caddr_t pathname, md_dev64_t devt); 799*0Sstevel@tonic-gate extern int md_update_namespace_did(set_t setno, side_t side, mdkey_t key, 800*0Sstevel@tonic-gate md_error_t *ep); 801*0Sstevel@tonic-gate extern int md_validate_devid(set_t setno, side_t side, int *maxsz); 802*0Sstevel@tonic-gate extern int md_get_invdid(set_t setno, side_t side, int cnt, int maxsz, 803*0Sstevel@tonic-gate void *didptr); 804*0Sstevel@tonic-gate extern md_dev64_t md_resolve_bydevid(minor_t, md_dev64_t, mdkey_t key); 805*0Sstevel@tonic-gate extern md_dev64_t md_expldev(md_dev64_t); 806*0Sstevel@tonic-gate extern dev32_t md_cmpldev(md_dev64_t); 807*0Sstevel@tonic-gate extern dev_t md_dev64_to_dev(md_dev64_t); 808*0Sstevel@tonic-gate extern md_dev64_t md_makedevice(major_t, minor_t); 809*0Sstevel@tonic-gate extern major_t md_getmajor(md_dev64_t); 810*0Sstevel@tonic-gate extern minor_t md_getminor(md_dev64_t); 811*0Sstevel@tonic-gate extern void md_timeval(md_timeval32_t *); 812*0Sstevel@tonic-gate extern int md_imp_snarf_set(set_t *, int); 813*0Sstevel@tonic-gate 814*0Sstevel@tonic-gate /* externals from md_mddb.c */ 815*0Sstevel@tonic-gate extern int mddb_reread_rr(set_t, mddb_recid_t); 816*0Sstevel@tonic-gate extern int mddb_setowner(mddb_recid_t id, md_mn_nodeid_t owner); 817*0Sstevel@tonic-gate extern int mddb_parse(mddb_parse_parm_t *mpp); 818*0Sstevel@tonic-gate extern int mddb_block(mddb_block_parm_t *mpp); 819*0Sstevel@tonic-gate extern int mddb_optrecfix(mddb_optrec_parm_t *mop); 820*0Sstevel@tonic-gate extern int mddb_check_write_ioctl(mddb_config_t *info); 821*0Sstevel@tonic-gate extern int mddb_setflags_ioctl(mddb_setflags_config_t *info); 822*0Sstevel@tonic-gate extern struct nm_next_hdr *get_first_record(set_t, int, int); 823*0Sstevel@tonic-gate extern void *lookup_entry(struct nm_next_hdr *, set_t, 824*0Sstevel@tonic-gate side_t, mdkey_t, md_dev64_t, int); 825*0Sstevel@tonic-gate extern void *lookup_shared_entry(struct nm_next_hdr *, 826*0Sstevel@tonic-gate mdkey_t key, char *, mddb_recid_t *, int); 827*0Sstevel@tonic-gate extern int remove_shared_entry(struct nm_next_hdr *, mdkey_t key, 828*0Sstevel@tonic-gate char *, int); 829*0Sstevel@tonic-gate extern void *alloc_entry(struct nm_next_hdr *, mddb_recid_t, size_t, int, 830*0Sstevel@tonic-gate mddb_recid_t *); 831*0Sstevel@tonic-gate extern void *getshared_name(set_t, mdkey_t, int); 832*0Sstevel@tonic-gate 833*0Sstevel@tonic-gate #endif /* _KERNEL */ 834*0Sstevel@tonic-gate 835*0Sstevel@tonic-gate #ifdef __cplusplus 836*0Sstevel@tonic-gate } 837*0Sstevel@tonic-gate #endif 838*0Sstevel@tonic-gate 839*0Sstevel@tonic-gate #endif /* _SYS_MDVAR_H */ 840