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