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  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2015 Joyent, Inc.  All rights reserved.
  24  */
  25 
  26 #ifndef _SYS_SDEV_IMPL_H
  27 #define _SYS_SDEV_IMPL_H
  28 
  29 #ifdef __cplusplus
  30 extern "C" {
  31 #endif
  32 
  33 #include <rpc/rpc.h>
  34 #include <sys/dirent.h>
  35 #include <sys/vfs.h>
  36 #include <sys/vfs_opreg.h>
  37 #include <sys/list.h>
  38 #include <sys/nvpair.h>
  39 #include <sys/sunddi.h>
  40 
  41 /*
  42  * sdev_nodes are the file-system specific part of the
  43  * vnodes for the device filesystem.
  44  *
  45  * The device filesystem exports two node types:
  46  *
  47  * VDIR nodes           to represent directories
  48  * VCHR & VBLK nodes        to represent devices
  49  */
  50 
  51 /*
  52  * /dev mount arguments
  53  */
  54 struct sdev_mountargs {
  55         uint64_t sdev_attrdir;
  56 };
  57 
  58 
  59 /*
  60  * Nvpair names of profile information (list of device files available) of
  61  * non-global /dev mounts.  These strings must be unique among them.
  62  */
  63 #define SDEV_NVNAME_MOUNTPT     "prof_mountpt"
  64 #define SDEV_NVNAME_INCLUDE     "prof_include"
  65 #define SDEV_NVNAME_EXCLUDE     "prof_exclude"
  66 #define SDEV_NVNAME_SYMLINK     "prof_symlink"
  67 #define SDEV_NVNAME_MAP         "prof_map"
  68 
  69 /*
  70  * supported devfsadm_cmd
  71  */
  72 #define DEVFSADMD_RUN_ALL       1
  73 
  74 /*
  75  * devfsadm_error codes
  76  */
  77 #define DEVFSADM_RUN_INVALID            1
  78 #define DEVFSADM_RUN_EPERM              2
  79 #define DEVFSADM_RUN_NOTSUP             3
  80 
  81 /*
  82  * devfsadm/devname door data structures
  83  */
  84 typedef struct sdev_door_arg {
  85         uint8_t devfsadm_cmd;   /* what to do for devfsadm[d] */
  86 } sdev_door_arg_t;
  87 
  88 typedef struct sdev_door_res {
  89         int32_t devfsadm_error;
  90 } sdev_door_res_t;
  91 
  92 #ifdef _KERNEL
  93 
  94 struct sdev_dprof {
  95         int has_glob;
  96         nvlist_t *dev_name;
  97         nvlist_t *dev_map;
  98         nvlist_t *dev_symlink;
  99         nvlist_t *dev_glob_incdir;
 100         nvlist_t *dev_glob_excdir;
 101 };
 102 
 103 /*
 104  * devname_handle_t
 105  */
 106 struct devname_handle {
 107         struct sdev_node *dh_data;      /* the sdev_node */
 108         void    *dh_args;
 109 };
 110 typedef struct devname_handle devname_handle_t;
 111 
 112 /*
 113  * Per-instance node data for the global zone instance
 114  * Only one mount of /dev in the global zone
 115  */
 116 typedef struct sdev_global_data {
 117         struct devname_handle sdev_ghandle;
 118         ulong_t         sdev_dir_ggen;          /* name space generation # */
 119 } sdev_global_data_t;
 120 
 121 /*
 122  * Per-instance node data - profile data per non-global zone mount instance
 123  */
 124 typedef struct sdev_local_data {
 125         ulong_t sdev_dir_lgen;          /* cached generation # of /dev dir */
 126         ulong_t sdev_devtree_lgen;      /* cached generation # of devtree */
 127         struct sdev_node *sdev_lorigin; /* corresponding global sdev_node */
 128         struct sdev_dprof sdev_lprof;   /* profile for multi-inst */
 129 } sdev_local_data_t;
 130 
 131 /*
 132  * /dev filesystem sdev_node defines
 133  */
 134 typedef struct sdev_node {
 135         char            *sdev_name;     /* node name */
 136         size_t          sdev_namelen;   /* strlen(sdev_name) */
 137         char            *sdev_path;     /* absolute path */
 138         char            *sdev_symlink;  /* source for a symlink */
 139         struct vnode    *sdev_vnode;    /* vnode */
 140 
 141         krwlock_t       sdev_contents;  /* rw lock for this data structure */
 142         struct sdev_node *sdev_dotdot;  /* parent */
 143 
 144         avl_tree_t      sdev_entries;   /* VDIR: contents as avl tree */
 145         avl_node_t      sdev_avllink;   /* avl node linkage */
 146 
 147         struct vnode    *sdev_attrvp;   /* backing store vnode if persisted */
 148         struct vattr    *sdev_attr;     /* memory copy of the vattr */
 149 
 150         ino64_t         sdev_ino;       /* inode */
 151         uint_t          sdev_nlink;     /* link count */
 152         int             sdev_state;     /* state of this node */
 153         int             sdev_flags;     /* flags bit */
 154 
 155         kmutex_t        sdev_lookup_lock; /* node creation synch lock */
 156         kcondvar_t      sdev_lookup_cv; /* node creation sync cv */
 157         int             sdev_lookup_flags; /* node creation flags */
 158 
 159         /* per-instance data, either global or non-global zone */
 160         union {
 161                 struct sdev_global_data sdev_globaldata;
 162                 struct sdev_local_data  sdev_localdata;
 163         } sdev_instance_data;
 164 
 165         void            *sdev_private;
 166 } sdev_node_t;
 167 
 168 #define sdev_ldata sdev_instance_data.sdev_localdata
 169 #define sdev_gdata sdev_instance_data.sdev_globaldata
 170 
 171 #define sdev_handle             sdev_gdata.sdev_ghandle
 172 #define sdev_gdir_gen           sdev_gdata.sdev_dir_ggen
 173 
 174 #define sdev_ldir_gen           sdev_ldata.sdev_dir_lgen
 175 #define sdev_devtree_gen        sdev_ldata.sdev_devtree_lgen
 176 #define sdev_origin             sdev_ldata.sdev_lorigin
 177 #define sdev_prof               sdev_ldata.sdev_lprof
 178 
 179 /*
 180  * Directory contents traversal
 181  */
 182 #define SDEV_FIRST_ENTRY(ddv)           avl_first(&(ddv)->sdev_entries)
 183 #define SDEV_NEXT_ENTRY(ddv, dv)        AVL_NEXT(&(ddv)->sdev_entries, (dv))
 184 
 185 /*
 186  * See the big theory statement in sdev_vnops.c for an explanation of these
 187  * states.
 188  */
 189 typedef enum {
 190         SDEV_ZOMBIE = -1,
 191         SDEV_INIT = 0,
 192         SDEV_READY
 193 } sdev_node_state_t;
 194 
 195 /* sdev_flags */
 196 #define SDEV_BUILD              0x0001  /* directory cache out-of-date */
 197 #define SDEV_GLOBAL             0x0002  /* global /dev nodes */
 198 #define SDEV_PERSIST            0x0004  /* backing store persisted node */
 199 #define SDEV_NO_NCACHE          0x0008  /* do not include in neg. cache */
 200 #define SDEV_DYNAMIC            0x0010  /* special-purpose vnode ops */
 201                                         /* (ex: pts) */
 202 #define SDEV_VTOR               0x0020  /* validate sdev_nodes during search */
 203 #define SDEV_ATTR_INVALID       0x0040  /* invalid node attributes, */
 204                                         /* need update */
 205 #define SDEV_SUBDIR             0x0080  /* match all subdirs under here */
 206 #define SDEV_ZONED              0x0100  /* zoned subdir */
 207 
 208 /* sdev_lookup_flags */
 209 #define SDEV_LOOKUP     0x0001  /* node creation in progress */
 210 #define SDEV_READDIR    0x0002  /* VDIR readdir in progress */
 211 #define SDEV_LGWAITING  0x0004  /* waiting for devfsadm completion */
 212 
 213 #define SDEV_VTOR_INVALID       -1
 214 #define SDEV_VTOR_SKIP          0
 215 #define SDEV_VTOR_VALID         1
 216 #define SDEV_VTOR_STALE         2
 217 
 218 /* convenient macros */
 219 #define SDEV_IS_GLOBAL(dv)      \
 220         (dv->sdev_flags & SDEV_GLOBAL)
 221 #define SDEV_IS_PERSIST(dv)     \
 222         (dv->sdev_flags & SDEV_PERSIST)
 223 #define SDEV_IS_DYNAMIC(dv)     \
 224         (dv->sdev_flags & SDEV_DYNAMIC)
 225 #define SDEV_IS_NO_NCACHE(dv)   \
 226         (dv->sdev_flags & SDEV_NO_NCACHE)
 227 #define SDEV_IS_LOOKUP(dv)      \
 228         (dv->sdev_lookup_flags & SDEV_LOOKUP)
 229 #define SDEV_IS_READDIR(dv)     \
 230         (dv->sdev_lookup_flags & SDEV_READDIR)
 231 #define SDEV_IS_LGWAITING(dv)   \
 232         (dv->sdev_lookup_flags  & SDEV_LGWAITING)
 233 
 234 #define SDEVTOV(n)      ((struct vnode *)(n)->sdev_vnode)
 235 #define VTOSDEV(vp)     ((struct sdev_node *)(vp)->v_data)
 236 #define VN_HELD(v)      ((v)->v_count != 0)
 237 #define SDEV_HELD(dv)   (VN_HELD(SDEVTOV(dv)))
 238 #define SDEV_HOLD(dv)   VN_HOLD(SDEVTOV(dv))
 239 #define SDEV_RELE(dv)   VN_RELE(SDEVTOV(dv))
 240 #define SDEV_SIMPLE_RELE(dv)    {       \
 241         mutex_enter(&SDEVTOV(dv)->v_lock);       \
 242         SDEVTOV(dv)->v_count--;      \
 243         mutex_exit(&SDEVTOV(dv)->v_lock);        \
 244 }
 245 
 246 #define SDEV_ACL_FLAVOR(vp)     (VFSTOSDEVFS(vp->v_vfsp)->sdev_acl_flavor)
 247 
 248 /*
 249  * some defaults
 250  */
 251 #define SDEV_ROOTINO            ((ino_t)2)
 252 #define SDEV_UID_DEFAULT        (0)
 253 #define SDEV_GID_DEFAULT        (3)
 254 #define SDEV_DIRMODE_DEFAULT    (S_IFDIR |0755)
 255 #define SDEV_DEVMODE_DEFAULT    (0600)
 256 #define SDEV_LNKMODE_DEFAULT    (S_IFLNK | 0777)
 257 
 258 extern struct vattr sdev_vattr_dir;
 259 extern struct vattr sdev_vattr_lnk;
 260 extern struct vattr sdev_vattr_blk;
 261 extern struct vattr sdev_vattr_chr;
 262 
 263 /*
 264  * devname_lookup_func()
 265  */
 266 extern int devname_lookup_func(struct sdev_node *, char *, struct vnode **,
 267     struct cred *, int (*)(struct sdev_node *, char *, void **, struct cred *,
 268     void *, char *), int);
 269 
 270 /*
 271  * flags used by devname_lookup_func callbacks
 272  */
 273 #define SDEV_VATTR      0x4     /* callback returning node vattr */
 274 #define SDEV_VLINK      0x8     /* callback returning /dev link */
 275 
 276 /*
 277  * devname_readdir_func()
 278  */
 279 extern int devname_readdir_func(vnode_t *, uio_t *, cred_t *, int *, int);
 280 
 281 /*
 282  * flags for devname_readdir_func
 283  */
 284 #define SDEV_BROWSE     0x1     /* fetch all entries from backing store */
 285 
 286 /*
 287  * devname_setattr_func()
 288  */
 289 extern int devname_setattr_func(struct vnode *, struct vattr *, int,
 290     struct cred *, int (*)(struct sdev_node *, struct vattr *, int), int);
 291 /*
 292  * devname_inactive_func()
 293  */
 294 extern void devname_inactive_func(struct vnode *, struct cred *,
 295     void (*)(struct vnode *));
 296 
 297 /*
 298  * /dev file system instance defines
 299  */
 300 /*
 301  * /dev version of vfs_data
 302  */
 303 struct sdev_data {
 304         struct sdev_data        *sdev_prev;
 305         struct sdev_data        *sdev_next;
 306         struct sdev_node        *sdev_root;
 307         struct vfs              *sdev_vfsp;
 308         struct sdev_mountargs   *sdev_mountargs;
 309         ulong_t                 sdev_acl_flavor;
 310 };
 311 
 312 #define VFSTOSDEVFS(vfsp)       ((struct sdev_data *)((vfsp)->vfs_data))
 313 
 314 /*
 315  * sdev_fid overlays the fid structure (for VFS_VGET)
 316  */
 317 struct sdev_fid {
 318         uint16_t        sdevfid_len;
 319         ino32_t         sdevfid_ino;
 320         int32_t         sdevfid_gen;
 321 };
 322 
 323 /*
 324  * devfsadm and devname communication defines
 325  */
 326 typedef enum {
 327         DEVNAME_DEVFSADM_STOPPED = 0,   /* devfsadm has never run */
 328         DEVNAME_DEVFSADM_RUNNING,       /* devfsadm is running */
 329         DEVNAME_DEVFSADM_RUN            /* devfsadm ran once */
 330 } devname_devfsadm_state_t;
 331 
 332 extern volatile uint_t  devfsadm_state; /* atomic mask for devfsadm status */
 333 
 334 #define DEVNAME_DEVFSADM_SET_RUNNING(devfsadm_state)    \
 335         (devfsadm_state = DEVNAME_DEVFSADM_RUNNING)
 336 #define DEVNAME_DEVFSADM_SET_STOP(devfsadm_state)       \
 337         (devfsadm_state = DEVNAME_DEVFSADM_STOPPED)
 338 #define DEVNAME_DEVFSADM_SET_RUN(devfsadm_state)        \
 339         (devfsadm_state = DEVNAME_DEVFSADM_RUN)
 340 #define DEVNAME_DEVFSADM_IS_RUNNING(devfsadm_state)     \
 341         (devfsadm_state == DEVNAME_DEVFSADM_RUNNING)
 342 #define DEVNAME_DEVFSADM_HAS_RUN(devfsadm_state)        \
 343         (devfsadm_state == DEVNAME_DEVFSADM_RUN)
 344 
 345 #define SDEV_BLOCK_OTHERS(dv, cmd)      {       \
 346         ASSERT(MUTEX_HELD(&dv->sdev_lookup_lock));       \
 347         dv->sdev_lookup_flags |= cmd;                        \
 348 }
 349 extern void sdev_unblock_others(struct sdev_node *, uint_t);
 350 #define SDEV_UNBLOCK_OTHERS(dv, cmd)    {       \
 351         sdev_unblock_others(dv, cmd);           \
 352 }
 353 
 354 #define SDEV_CLEAR_LOOKUP_FLAGS(dv, cmd)        {       \
 355         dv->sdev_lookup_flags &= ~cmd;   \
 356 }
 357 
 358 extern int sdev_wait4lookup(struct sdev_node *, int);
 359 extern int devname_filename_register(char *);
 360 extern int devname_nsmaps_register(char *, size_t);
 361 extern void sdev_devfsadm_lockinit(void);
 362 extern void sdev_devfsadm_lockdestroy(void);
 363 extern void devname_add_devfsadm_node(char *);
 364 extern void sdev_devfsadmd_thread(struct sdev_node *, struct sdev_node *,
 365     struct cred *);
 366 extern int devname_profile_update(char *, size_t);
 367 extern struct sdev_data *sdev_find_mntinfo(char *);
 368 void sdev_mntinfo_rele(struct sdev_data *);
 369 extern struct vnodeops *devpts_getvnodeops(void);
 370 extern struct vnodeops *devvt_getvnodeops(void);
 371 
 372 /*
 373  * boot states - warning, the ordering here is significant
 374  *
 375  * the difference between "system available" and "boot complete"
 376  * is a debounce timeout to catch some daemon issuing a readdir
 377  * triggering a nuisance implict reconfig on each boot.
 378  */
 379 #define SDEV_BOOT_STATE_INITIAL         0
 380 #define SDEV_BOOT_STATE_RECONFIG        1       /* reconfig */
 381 #define SDEV_BOOT_STATE_SYSAVAIL        2       /* system available */
 382 #define SDEV_BOOT_STATE_COMPLETE        3       /* boot complete */
 383 
 384 /*
 385  * Negative cache list and list element
 386  * The mutex protects the flags against multiple accesses and
 387  * must only be acquired when already holding the r/w lock.
 388  */
 389 typedef struct sdev_nc_list {
 390         list_t          ncl_list;       /* the list itself */
 391         kmutex_t        ncl_mutex;      /* protects ncl_flags */
 392         krwlock_t       ncl_lock;       /* protects ncl_list */
 393         int             ncl_flags;
 394         int             ncl_nentries;
 395 } sdev_nc_list_t;
 396 
 397 typedef struct sdev_nc_node {
 398         char            *ncn_name;      /* name of the node */
 399         int             ncn_flags;      /* state information */
 400         int             ncn_expirecnt;  /* remove once expired */
 401         list_node_t     ncn_link;       /* link to next in list */
 402 } sdev_nc_node_t;
 403 
 404 /* ncl_flags */
 405 #define NCL_LIST_DIRTY          0x01    /* needs to be flushed */
 406 #define NCL_LIST_WRITING        0x02    /* write in progress */
 407 #define NCL_LIST_WENABLE        0x04    /* write-enabled post boot */
 408 
 409 /* ncn_flags */
 410 #define NCN_ACTIVE      0x01    /* a lookup has occurred */
 411 #define NCN_SRC_STORE   0x02    /* src: persistent store */
 412 #define NCN_SRC_CURRENT 0x04    /* src: current boot */
 413 
 414 /* sdev_lookup_failed flags */
 415 #define SLF_NO_NCACHE   0x01    /* node should not be added to ncache */
 416 #define SLF_REBUILT     0x02    /* reconfig performed during lookup attempt */
 417 
 418 /*
 419  * The nvlist name and nvpair identifiers in the
 420  * /etc/devices/devname_cache nvlist format
 421  */
 422 #define DP_DEVNAME_ID                   "devname"
 423 #define DP_DEVNAME_NCACHE_ID            "ncache"
 424 #define DP_DEVNAME_NC_EXPIRECNT_ID      "expire-counts"
 425 
 426 /* devname-cache list element */
 427 typedef struct nvp_devname {
 428         char                    **nvp_paths;
 429         int                     *nvp_expirecnts;
 430         int                     nvp_npaths;
 431         list_node_t             nvp_link;
 432 } nvp_devname_t;
 433 
 434 /*
 435  * name service globals and prototypes
 436  */
 437 
 438 /*
 439  * vnodeops and vfsops helpers
 440  */
 441 
 442 typedef enum {
 443         SDEV_CACHE_ADD = 0,
 444         SDEV_CACHE_DELETE
 445 } sdev_cache_ops_t;
 446 
 447 extern struct sdev_node *sdev_cache_lookup(struct sdev_node *, char *);
 448 extern void sdev_cache_update(struct sdev_node *, struct sdev_node **, char *,
 449     sdev_cache_ops_t);
 450 extern void sdev_node_cache_init(void);
 451 extern void sdev_node_cache_fini(void);
 452 extern struct sdev_node *sdev_mkroot(struct vfs *, dev_t, struct vnode *,
 453     struct vnode *, struct cred *);
 454 extern void sdev_filldir_dynamic(struct sdev_node *);
 455 extern int sdev_mknode(struct sdev_node *, char *, struct sdev_node **,
 456     struct vattr *, struct vnode *, void *, struct cred *, sdev_node_state_t);
 457 extern int sdev_getlink(struct vnode *linkvp, char **link);
 458 
 459 extern int sdev_nodeinit(struct sdev_node *, char *, struct sdev_node **,
 460     vattr_t *);
 461 extern int sdev_nodeready(struct sdev_node *, vattr_t *, vnode_t *, void *,
 462     cred_t *);
 463 extern int sdev_shadow_node(struct sdev_node *, struct cred *);
 464 extern void sdev_nodedestroy(struct sdev_node *, uint_t);
 465 extern void sdev_update_timestamps(struct vnode *, cred_t *, uint_t);
 466 extern void sdev_vattr_merge(struct sdev_node *, struct vattr *);
 467 extern void sdev_devstate_change(void);
 468 extern int sdev_lookup_filter(sdev_node_t *, char *);
 469 extern void sdev_lookup_failed(sdev_node_t *, char *, int);
 470 extern int sdev_unlocked_access(void *, int, struct cred *);
 471 
 472 #define SDEV_ENFORCE    0x1
 473 extern void sdev_stale(struct sdev_node *);
 474 extern int sdev_cleandir(struct sdev_node *, char *, uint_t);
 475 extern int sdev_rnmnode(struct sdev_node *, struct sdev_node *,
 476     struct sdev_node *, struct sdev_node **, char *, struct cred *);
 477 extern size_t add_dir_entry(dirent64_t *, char *, size_t, ino_t, offset_t);
 478 extern struct vattr *sdev_getdefault_attr(enum vtype type);
 479 extern int sdev_to_vp(struct sdev_node *, struct vnode **);
 480 extern ino_t sdev_mkino(struct sdev_node *);
 481 extern int devname_backstore_lookup(struct sdev_node *, char *,
 482     struct vnode **);
 483 extern int sdev_is_devfs_node(char *);
 484 extern int sdev_copyin_mountargs(struct mounta *, struct sdev_mountargs *);
 485 extern int sdev_reserve_subdirs(struct sdev_node *);
 486 extern int prof_lookup();
 487 extern void prof_filldir(struct sdev_node *);
 488 extern int devpts_validate(struct sdev_node *dv);
 489 extern int devnet_validate(struct sdev_node *dv);
 490 extern int devipnet_validate(struct sdev_node *dv);
 491 extern int devvt_validate(struct sdev_node *dv);
 492 extern int devzvol_validate(struct sdev_node *dv);
 493 extern void *sdev_get_vtor(struct sdev_node *dv);
 494 
 495 /*
 496  * devinfo helpers
 497  */
 498 extern int sdev_modctl_readdir(const char *, char ***, int *, int *, int);
 499 extern void sdev_modctl_readdir_free(char **, int, int);
 500 extern int sdev_modctl_devexists(const char *);
 501 
 502 /*
 503  * ncache handlers
 504  */
 505 
 506 extern void sdev_ncache_init(void);
 507 extern void sdev_ncache_setup(void);
 508 extern void sdev_ncache_teardown(void);
 509 extern void sdev_nc_addname(sdev_nc_list_t *, sdev_node_t *, char *, int);
 510 extern void sdev_nc_node_exists(sdev_node_t *);
 511 extern void sdev_nc_path_exists(sdev_nc_list_t *, char *);
 512 extern void sdev_modctl_dump_files(void);
 513 
 514 /*
 515  * globals
 516  */
 517 extern kmutex_t sdev_lock;
 518 extern int devtype;
 519 extern kmem_cache_t *sdev_node_cache;
 520 extern struct vnodeops          *sdev_vnodeops;
 521 extern struct vnodeops          *devpts_vnodeops;
 522 extern struct vnodeops          *devnet_vnodeops;
 523 extern struct vnodeops          *devipnet_vnodeops;
 524 extern struct vnodeops          *devvt_vnodeops;
 525 extern struct sdev_data *sdev_origins; /* mount info for global /dev instance */
 526 extern struct vnodeops          *devzvol_vnodeops;
 527 
 528 extern const fs_operation_def_t sdev_vnodeops_tbl[];
 529 extern const fs_operation_def_t devpts_vnodeops_tbl[];
 530 extern const fs_operation_def_t devnet_vnodeops_tbl[];
 531 extern const fs_operation_def_t devipnet_vnodeops_tbl[];
 532 extern const fs_operation_def_t devvt_vnodeops_tbl[];
 533 extern const fs_operation_def_t devsys_vnodeops_tbl[];
 534 extern const fs_operation_def_t devpseudo_vnodeops_tbl[];
 535 extern const fs_operation_def_t devzvol_vnodeops_tbl[];
 536 
 537 extern sdev_nc_list_t   *sdev_ncache;
 538 extern int              sdev_reconfig_boot;
 539 extern int              sdev_boot_state;
 540 extern int              sdev_reconfig_verbose;
 541 extern int              sdev_reconfig_disable;
 542 extern int              sdev_nc_disable;
 543 extern int              sdev_nc_disable_reset;
 544 extern int              sdev_nc_verbose;
 545 
 546 extern taskq_t          *sdev_taskq;
 547 
 548 /*
 549  * misc. defines
 550  */
 551 #ifdef DEBUG
 552 extern int sdev_debug;
 553 #define SDEV_DEBUG              0x01    /* error messages to console/log */
 554 #define SDEV_DEBUG_VOPS         0x02    /* vnode ops errors */
 555 #define SDEV_DEBUG_DLF          0x04    /* trace devname_lookup_func */
 556 #define SDEV_DEBUG_DRF          0x08    /* trace devname_readdir_func */
 557 #define SDEV_DEBUG_NCACHE       0x10    /* negative cache tracing */
 558 #define SDEV_DEBUG_DEVFSADMD    0x20    /* comm. of devnamefs & devfsadm */
 559 #define SDEV_DEBUG_PTS          0x40    /* /dev/pts tracing */
 560 #define SDEV_DEBUG_RECONFIG     0x80    /* events triggering reconfig */
 561 #define SDEV_DEBUG_SDEV_NODE    0x100   /* trace sdev_node activities */
 562 #define SDEV_DEBUG_PROFILE      0x200   /* trace sdev_profile */
 563 #define SDEV_DEBUG_MODCTL       0x400   /* trace modctl activity */
 564 #define SDEV_DEBUG_FLK          0x800   /* trace failed lookups */
 565 #define SDEV_DEBUG_NET          0x1000  /* /dev/net tracing */
 566 #define SDEV_DEBUG_ZVOL         0x2000  /* /dev/zvol/tracing */
 567 
 568 #define sdcmn_err(args)  if (sdev_debug & SDEV_DEBUG) printf args
 569 #define sdcmn_err2(args) if (sdev_debug & SDEV_DEBUG_VOPS) printf args
 570 #define sdcmn_err3(args) if (sdev_debug & SDEV_DEBUG_DLF) printf args
 571 #define sdcmn_err4(args) if (sdev_debug & SDEV_DEBUG_DRF) printf args
 572 #define sdcmn_err5(args) if (sdev_debug & SDEV_DEBUG_NCACHE) printf args
 573 #define sdcmn_err6(args) if (sdev_debug & SDEV_DEBUG_DEVFSADMD) printf args
 574 #define sdcmn_err7(args) if (sdev_debug & SDEV_DEBUG_PTS) printf args
 575 #define sdcmn_err8(args) if (sdev_debug & SDEV_DEBUG_RECONFIG) printf args
 576 #define sdcmn_err9(args) if (sdev_debug & SDEV_DEBUG_SDEV_NODE) printf args
 577 #define sdcmn_err10(args) if (sdev_debug & SDEV_DEBUG_PROFILE) printf args
 578 #define sdcmn_err11(args) if (sdev_debug & SDEV_DEBUG_MODCTL) printf args
 579 #define sdcmn_err12(args) if (sdev_debug & SDEV_DEBUG_NET) printf args
 580 #define sdcmn_err13(args) if (sdev_debug & SDEV_DEBUG_ZVOL) printf args
 581 #define impossible(args) printf args
 582 #else
 583 #define sdcmn_err(args)         /* does nothing */
 584 #define sdcmn_err2(args)        /* does nothing */
 585 #define sdcmn_err3(args)        /* does nothing */
 586 #define sdcmn_err4(args)        /* does nothing */
 587 #define sdcmn_err5(args)        /* does nothing */
 588 #define sdcmn_err6(args)        /* does nothing */
 589 #define sdcmn_err7(args)        /* does nothing */
 590 #define sdcmn_err8(args)        /* does nothing */
 591 #define sdcmn_err9(args)        /* does nothing */
 592 #define sdcmn_err10(args)       /* does nothing */
 593 #define sdcmn_err11(args)       /* does nothing */
 594 #define sdcmn_err12(args)       /* does nothing */
 595 #define sdcmn_err13(args)       /* does nothing */
 596 #define impossible(args)        /* does nothing */
 597 #endif
 598 
 599 #ifdef DEBUG
 600 #define SD_TRACE_FAILED_LOOKUP(ddv, nm, retried)                        \
 601         if ((sdev_debug & SDEV_DEBUG_FLK) ||                                \
 602             ((retried) && (sdev_debug & SDEV_DEBUG_RECONFIG))) {    \
 603                 printf("lookup of %s/%s by %s failed, line %d\n",       \
 604                     (ddv)->sdev_name, (nm), curproc->p_user.u_comm,       \
 605                     __LINE__);                                          \
 606         }
 607 #else
 608 #define SD_TRACE_FAILED_LOOKUP(ddv, nm, retried)
 609 #endif
 610 
 611 #endif  /* _KERNEL */
 612 
 613 #ifdef __cplusplus
 614 }
 615 #endif
 616 
 617 #endif  /* _SYS_SDEV_IMPL_H */