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