xref: /onnv-gate/usr/src/uts/common/sys/fs/sdev_impl.h (revision 12633:9f2cda0ed938)
12621Sllai1 /*
22621Sllai1  * CDDL HEADER START
32621Sllai1  *
42621Sllai1  * The contents of this file are subject to the terms of the
52621Sllai1  * Common Development and Distribution License (the "License").
62621Sllai1  * You may not use this file except in compliance with the License.
72621Sllai1  *
82621Sllai1  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
92621Sllai1  * or http://www.opensolaris.org/os/licensing.
102621Sllai1  * See the License for the specific language governing permissions
112621Sllai1  * and limitations under the License.
122621Sllai1  *
132621Sllai1  * When distributing Covered Code, include this CDDL HEADER in each
142621Sllai1  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
152621Sllai1  * If applicable, add the following below this CDDL HEADER, with the
162621Sllai1  * fields enclosed by brackets "[]" replaced with your own identifying
172621Sllai1  * information: Portions Copyright [yyyy] [name of copyright owner]
182621Sllai1  *
192621Sllai1  * CDDL HEADER END
202621Sllai1  */
212621Sllai1 /*
22*12633Sjohn.levon@sun.com  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
232621Sllai1  */
242621Sllai1 
252621Sllai1 #ifndef _SYS_SDEV_IMPL_H
262621Sllai1 #define	_SYS_SDEV_IMPL_H
272621Sllai1 
282621Sllai1 #ifdef __cplusplus
292621Sllai1 extern "C" {
302621Sllai1 #endif
312621Sllai1 
322621Sllai1 #include <rpc/rpc.h>
332621Sllai1 #include <sys/dirent.h>
342621Sllai1 #include <sys/vfs.h>
353898Srsb #include <sys/vfs_opreg.h>
362621Sllai1 #include <sys/list.h>
372621Sllai1 #include <sys/nvpair.h>
382621Sllai1 
392621Sllai1 /*
402621Sllai1  * sdev_nodes are the file-system specific part of the
412621Sllai1  * vnodes for the device filesystem.
422621Sllai1  *
432621Sllai1  * The device filesystem exports two node types:
442621Sllai1  *
452621Sllai1  * VDIR nodes		to represent directories
462621Sllai1  * VCHR & VBLK nodes	to represent devices
472621Sllai1  */
482621Sllai1 
492621Sllai1 /*
502621Sllai1  * /dev mount arguments
512621Sllai1  */
522621Sllai1 struct sdev_mountargs {
532621Sllai1 	uint64_t sdev_attrdir;
542621Sllai1 };
552621Sllai1 
562621Sllai1 
572621Sllai1 /*
582621Sllai1  * Nvpair names of profile information (list of device files available) of
592621Sllai1  * non-global /dev mounts.  These strings must be unique among them.
602621Sllai1  */
612621Sllai1 #define	SDEV_NVNAME_MOUNTPT	"prof_mountpt"
622621Sllai1 #define	SDEV_NVNAME_INCLUDE	"prof_include"
632621Sllai1 #define	SDEV_NVNAME_EXCLUDE	"prof_exclude"
642621Sllai1 #define	SDEV_NVNAME_SYMLINK	"prof_symlink"
652621Sllai1 #define	SDEV_NVNAME_MAP		"prof_map"
662621Sllai1 
672621Sllai1 /*
682621Sllai1  * supported devfsadm_cmd
692621Sllai1  */
702621Sllai1 #define	DEVFSADMD_RUN_ALL	1
712621Sllai1 
722621Sllai1 /*
732621Sllai1  * devfsadm_error codes
742621Sllai1  */
752621Sllai1 #define	DEVFSADM_RUN_INVALID		1
762621Sllai1 #define	DEVFSADM_RUN_EPERM		2
772621Sllai1 #define	DEVFSADM_RUN_NOTSUP		3
782621Sllai1 
792621Sllai1 /*
802621Sllai1  * devfsadm/devname door data structures
812621Sllai1  */
822621Sllai1 typedef struct sdev_door_arg {
832621Sllai1 	uint8_t devfsadm_cmd;	/* what to do for devfsadm[d] */
842621Sllai1 } sdev_door_arg_t;
852621Sllai1 
862621Sllai1 typedef struct sdev_door_res {
872621Sllai1 	int32_t devfsadm_error;
882621Sllai1 } sdev_door_res_t;
892621Sllai1 
902621Sllai1 #ifdef _KERNEL
912621Sllai1 
922621Sllai1 struct sdev_dprof {
932621Sllai1 	int has_glob;
942621Sllai1 	nvlist_t *dev_name;
952621Sllai1 	nvlist_t *dev_map;
962621Sllai1 	nvlist_t *dev_symlink;
972621Sllai1 	nvlist_t *dev_glob_incdir;
982621Sllai1 	nvlist_t *dev_glob_excdir;
992621Sllai1 };
1002621Sllai1 
1012621Sllai1 /*
1022621Sllai1  * devname_handle_t
1032621Sllai1  */
1042621Sllai1 struct devname_handle {
1052621Sllai1 	struct sdev_node *dh_data;	/* the sdev_node */
1062621Sllai1 	void    *dh_args;
1072621Sllai1 };
1082621Sllai1 typedef struct devname_handle devname_handle_t;
1092621Sllai1 
1102621Sllai1 /*
1112621Sllai1  * Per-instance node data for the global zone instance
1122621Sllai1  * Only one mount of /dev in the global zone
1132621Sllai1  */
1142621Sllai1 typedef struct sdev_global_data {
1152621Sllai1 	struct devname_handle sdev_ghandle;
1162621Sllai1 	ulong_t		sdev_dir_ggen;		/* name space generation # */
1172621Sllai1 } sdev_global_data_t;
1182621Sllai1 
1192621Sllai1 /*
1202621Sllai1  * Per-instance node data - profile data per non-global zone mount instance
1212621Sllai1  */
1222621Sllai1 typedef struct sdev_local_data {
1232621Sllai1 	ulong_t sdev_dir_lgen;		/* cached generation # of /dev dir */
1242621Sllai1 	ulong_t sdev_devtree_lgen;	/* cached generation # of devtree */
1252621Sllai1 	struct sdev_node *sdev_lorigin;	/* corresponding global sdev_node */
1262621Sllai1 	struct sdev_dprof sdev_lprof;	/* profile for multi-inst */
1272621Sllai1 } sdev_local_data_t;
1282621Sllai1 
1292621Sllai1 /*
1302621Sllai1  * /dev filesystem sdev_node defines
1312621Sllai1  */
1322621Sllai1 typedef struct sdev_node {
1332621Sllai1 	char		*sdev_name;	/* node name */
1342621Sllai1 	size_t		sdev_namelen;	/* strlen(sdev_name) */
1352621Sllai1 	char		*sdev_path;	/* absolute path */
1362621Sllai1 	char		*sdev_symlink;	/* source for a symlink */
1372621Sllai1 	struct vnode	*sdev_vnode;	/* vnode */
1382621Sllai1 
1392621Sllai1 	krwlock_t	sdev_contents;	/* rw lock for this data structure */
1402621Sllai1 	struct sdev_node *sdev_dotdot;	/* parent */
1416260Sjg 
1426260Sjg 	avl_tree_t	sdev_entries;	/* VDIR: contents as avl tree */
1436260Sjg 	avl_node_t	sdev_avllink;	/* avl node linkage */
1442621Sllai1 
1452621Sllai1 	struct vnode	*sdev_attrvp;	/* backing store vnode if persisted */
1462621Sllai1 	struct vattr	*sdev_attr;	/* memory copy of the vattr */
1472621Sllai1 
1482621Sllai1 	ino64_t		sdev_ino;	/* inode */
1492621Sllai1 	uint_t		sdev_nlink;	/* link count */
1502621Sllai1 	int		sdev_state;	/* state of this node */
1512621Sllai1 	int		sdev_flags;	/* flags bit */
1522621Sllai1 
1532621Sllai1 	kmutex_t	sdev_lookup_lock; /* node creation synch lock */
1542621Sllai1 	kcondvar_t	sdev_lookup_cv;	/* node creation sync cv */
1552621Sllai1 	int		sdev_lookup_flags; /* node creation flags */
1562621Sllai1 
1572621Sllai1 	/* per-instance data, either global or non-global zone */
1582621Sllai1 	union {
1592621Sllai1 		struct sdev_global_data	sdev_globaldata;
1602621Sllai1 		struct sdev_local_data	sdev_localdata;
1612621Sllai1 	} sdev_instance_data;
1625895Syz147064 
1635895Syz147064 	void		*sdev_private;
1642621Sllai1 } sdev_node_t;
1652621Sllai1 
1662621Sllai1 #define	sdev_ldata sdev_instance_data.sdev_localdata
1672621Sllai1 #define	sdev_gdata sdev_instance_data.sdev_globaldata
1682621Sllai1 
1692621Sllai1 #define	sdev_handle		sdev_gdata.sdev_ghandle
1702621Sllai1 #define	sdev_gdir_gen		sdev_gdata.sdev_dir_ggen
1712621Sllai1 
1722621Sllai1 #define	sdev_ldir_gen		sdev_ldata.sdev_dir_lgen
1732621Sllai1 #define	sdev_devtree_gen	sdev_ldata.sdev_devtree_lgen
1742621Sllai1 #define	sdev_origin		sdev_ldata.sdev_lorigin
1752621Sllai1 #define	sdev_prof		sdev_ldata.sdev_lprof
1762621Sllai1 
1772621Sllai1 /*
1786260Sjg  * Directory contents traversal
1796260Sjg  */
1806260Sjg #define	SDEV_FIRST_ENTRY(ddv)		avl_first(&(ddv)->sdev_entries)
1816260Sjg #define	SDEV_NEXT_ENTRY(ddv, dv)	AVL_NEXT(&(ddv)->sdev_entries, (dv))
1826260Sjg 
1836260Sjg /*
1842621Sllai1  * sdev_state
1852621Sllai1  *
1862621Sllai1  * A sdev_node may go through 3 states:
1872621Sllai1  *	SDEV_INIT: When a new /dev file is first looked up, a sdev_node
1882621Sllai1  *		   is allocated, initialized and added to the directory's
1892621Sllai1  *		   sdev_node cache. A node at this state will also
1902621Sllai1  *		   have the SDEV_LOOKUP flag set.
1912621Sllai1  *
1922621Sllai1  *		   Other threads that are trying to look up a node at
1932621Sllai1  *		   this state will be blocked until the SDEV_LOOKUP flag
1942621Sllai1  *		   is cleared.
1952621Sllai1  *
1962621Sllai1  *		   When the SDEV_LOOKUP flag is cleared, the node may
1972621Sllai1  *		   transition into the SDEV_READY state for a successful
1982621Sllai1  *		   lookup or the node is removed from the directory cache
1992621Sllai1  *		   and destroyed if the named node can not be found.
2002621Sllai1  *		   An ENOENT error is returned for the second case.
2012621Sllai1  *
2022621Sllai1  *	SDEV_READY: A /dev file has been successfully looked up and
2032621Sllai1  *		    associated with a vnode. The /dev file is available
2042621Sllai1  *		    for the supported /dev filesystem operations.
2052621Sllai1  *
2062621Sllai1  *	SDEV_ZOMBIE: Deletion of a /dev file has been explicitely issued
2072621Sllai1  *		    to an SDEV_READY node. The node is transitioned into
2082621Sllai1  *		    the SDEV_ZOMBIE state if the vnode reference count
2092621Sllai1  *		    is still held. A SDEV_ZOMBIE node does not support
2102621Sllai1  *		    any of the /dev filesystem operations. A SDEV_ZOMBIE
2112621Sllai1  *		    node is removed from the directory cache and destroyed
2122621Sllai1  *		    once the reference count reaches "zero".
2132621Sllai1  */
2142621Sllai1 typedef enum {
2152621Sllai1 	SDEV_ZOMBIE = -1,
2162621Sllai1 	SDEV_INIT = 0,
2172621Sllai1 	SDEV_READY
2182621Sllai1 } sdev_node_state_t;
2192621Sllai1 
2202621Sllai1 /* sdev_flags */
2215895Syz147064 #define	SDEV_BUILD		0x0001	/* directory cache out-of-date */
2225895Syz147064 #define	SDEV_STALE		0x0002	/* stale sdev nodes */
2235895Syz147064 #define	SDEV_GLOBAL		0x0004	/* global /dev nodes */
2245895Syz147064 #define	SDEV_PERSIST		0x0008	/* backing store persisted node */
2255895Syz147064 #define	SDEV_NO_NCACHE		0x0010	/* do not include in neg. cache */
2265895Syz147064 #define	SDEV_DYNAMIC		0x0020	/* special-purpose vnode ops */
2275895Syz147064 					/* (ex: pts) */
2285895Syz147064 #define	SDEV_VTOR		0x0040	/* validate sdev_nodes during search */
2295895Syz147064 #define	SDEV_ATTR_INVALID	0x0080	/* invalid node attributes, */
2305895Syz147064 					/* need update */
23110588SEric.Taylor@Sun.COM #define	SDEV_SUBDIR		0x0100	/* match all subdirs under here */
232*12633Sjohn.levon@sun.com #define	SDEV_ZONED		0x0200  /* zoned subdir */
2332621Sllai1 
2342621Sllai1 /* sdev_lookup_flags */
2352621Sllai1 #define	SDEV_LOOKUP	0x0001	/* node creation in progress */
2362621Sllai1 #define	SDEV_READDIR	0x0002	/* VDIR readdir in progress */
2372621Sllai1 #define	SDEV_LGWAITING	0x0004	/* waiting for devfsadm completion */
2382621Sllai1 
2392621Sllai1 #define	SDEV_VTOR_INVALID	-1
2402621Sllai1 #define	SDEV_VTOR_SKIP		0
2412621Sllai1 #define	SDEV_VTOR_VALID		1
2428023SPhil.Kirk@Sun.COM #define	SDEV_VTOR_STALE		2
2432621Sllai1 
2442621Sllai1 /* convenient macros */
2452621Sllai1 #define	SDEV_IS_GLOBAL(dv)	\
2462621Sllai1 	(dv->sdev_flags & SDEV_GLOBAL)
2472621Sllai1 #define	SDEV_IS_PERSIST(dv)	\
2482621Sllai1 	(dv->sdev_flags & SDEV_PERSIST)
2492621Sllai1 #define	SDEV_IS_DYNAMIC(dv)	\
2502621Sllai1 	(dv->sdev_flags & SDEV_DYNAMIC)
2512621Sllai1 #define	SDEV_IS_NO_NCACHE(dv)	\
2522621Sllai1 	(dv->sdev_flags & SDEV_NO_NCACHE)
2532621Sllai1 #define	SDEV_IS_LOOKUP(dv)	\
2542621Sllai1 	(dv->sdev_lookup_flags & SDEV_LOOKUP)
2552621Sllai1 #define	SDEV_IS_READDIR(dv)	\
2562621Sllai1 	(dv->sdev_lookup_flags & SDEV_READDIR)
2572621Sllai1 #define	SDEV_IS_LGWAITING(dv)	\
2582621Sllai1 	(dv->sdev_lookup_flags  & SDEV_LGWAITING)
2592621Sllai1 
2602621Sllai1 #define	SDEVTOV(n)	((struct vnode *)(n)->sdev_vnode)
2612621Sllai1 #define	VTOSDEV(vp)	((struct sdev_node *)(vp)->v_data)
2622621Sllai1 #define	VN_HELD(v)	((v)->v_count != 0)
2632621Sllai1 #define	SDEV_HELD(dv)	(VN_HELD(SDEVTOV(dv)))
2642621Sllai1 #define	SDEV_HOLD(dv)	VN_HOLD(SDEVTOV(dv))
2652621Sllai1 #define	SDEV_RELE(dv)	VN_RELE(SDEVTOV(dv))
2662621Sllai1 #define	SDEV_SIMPLE_RELE(dv)	{	\
2672621Sllai1 	mutex_enter(&SDEVTOV(dv)->v_lock);	\
2682621Sllai1 	SDEVTOV(dv)->v_count--;	\
2692621Sllai1 	mutex_exit(&SDEVTOV(dv)->v_lock);	\
2702621Sllai1 }
2712621Sllai1 
2722621Sllai1 #define	SDEV_ACL_FLAVOR(vp)	(VFSTOSDEVFS(vp->v_vfsp)->sdev_acl_flavor)
2732621Sllai1 
2742621Sllai1 /*
2752621Sllai1  * some defaults
2762621Sllai1  */
2772621Sllai1 #define	SDEV_ROOTINO		((ino_t)2)
2782621Sllai1 #define	SDEV_UID_DEFAULT	(0)
2792621Sllai1 #define	SDEV_GID_DEFAULT	(3)
2802621Sllai1 #define	SDEV_DIRMODE_DEFAULT	(S_IFDIR |0755)
2812621Sllai1 #define	SDEV_DEVMODE_DEFAULT	(0600)
2822621Sllai1 #define	SDEV_LNKMODE_DEFAULT	(S_IFLNK | 0777)
2832621Sllai1 
2842621Sllai1 extern struct vattr sdev_vattr_dir;
2852621Sllai1 extern struct vattr sdev_vattr_lnk;
2862621Sllai1 extern struct vattr sdev_vattr_blk;
2872621Sllai1 extern struct vattr sdev_vattr_chr;
2882621Sllai1 
2892621Sllai1 /*
2902621Sllai1  * devname_lookup_func()
2912621Sllai1  */
2922621Sllai1 extern int devname_lookup_func(struct sdev_node *, char *, struct vnode **,
2932621Sllai1     struct cred *, int (*)(struct sdev_node *, char *, void **, struct cred *,
2942621Sllai1     void *, char *), int);
2952621Sllai1 
2962621Sllai1 /*
2972621Sllai1  * flags used by devname_lookup_func callbacks
2982621Sllai1  */
2992621Sllai1 #define	SDEV_VATTR	0x4	/* callback returning node vattr */
3007688SAaron.Zang@Sun.COM #define	SDEV_VLINK	0x8	/* callback returning /dev link */
3012621Sllai1 
3022621Sllai1 /*
3032621Sllai1  * devname_readdir_func()
3042621Sllai1  */
3052621Sllai1 extern int devname_readdir_func(vnode_t *, uio_t *, cred_t *, int *, int);
3062621Sllai1 
3072621Sllai1 /*
3082621Sllai1  * flags for devname_readdir_func
3092621Sllai1  */
3102621Sllai1 #define	SDEV_BROWSE	0x1	/* fetch all entries from backing store */
3112621Sllai1 
3122621Sllai1 /*
3132621Sllai1  * devname_setattr_func()
3142621Sllai1  */
3152621Sllai1 extern int devname_setattr_func(struct vnode *, struct vattr *, int,
3162621Sllai1     struct cred *, int (*)(struct sdev_node *, struct vattr *, int), int);
3172621Sllai1 /*
3185895Syz147064  * devname_inactive_func()
3195895Syz147064  */
32010588SEric.Taylor@Sun.COM extern void devname_inactive_func(struct vnode *, struct cred *,
3215895Syz147064     void (*)(struct vnode *));
3225895Syz147064 
3235895Syz147064 /*
3242621Sllai1  * /dev file system instance defines
3252621Sllai1  */
3262621Sllai1 /*
3272621Sllai1  * /dev version of vfs_data
3282621Sllai1  */
3292621Sllai1 struct sdev_data {
3302621Sllai1 	struct sdev_data	*sdev_prev;
3312621Sllai1 	struct sdev_data	*sdev_next;
3322621Sllai1 	struct sdev_node	*sdev_root;
3332621Sllai1 	struct vfs		*sdev_vfsp;
3342621Sllai1 	struct sdev_mountargs	*sdev_mountargs;
3352621Sllai1 	ulong_t			sdev_acl_flavor;
3362621Sllai1 };
3372621Sllai1 
3382621Sllai1 #define	VFSTOSDEVFS(vfsp)	((struct sdev_data *)((vfsp)->vfs_data))
3392621Sllai1 
3402621Sllai1 /*
3412621Sllai1  * sdev_fid overlays the fid structure (for VFS_VGET)
3422621Sllai1  */
3432621Sllai1 struct sdev_fid {
3442621Sllai1 	uint16_t	sdevfid_len;
3452621Sllai1 	ino32_t		sdevfid_ino;
3462621Sllai1 	int32_t		sdevfid_gen;
3472621Sllai1 };
3482621Sllai1 
3492621Sllai1 /*
3502621Sllai1  * devfsadm and devname communication defines
3512621Sllai1  */
3522621Sllai1 typedef enum {
3532621Sllai1 	DEVNAME_DEVFSADM_STOPPED = 0,	/* devfsadm has never run */
3542621Sllai1 	DEVNAME_DEVFSADM_RUNNING,	/* devfsadm is running */
3552621Sllai1 	DEVNAME_DEVFSADM_RUN		/* devfsadm ran once */
3562621Sllai1 } devname_devfsadm_state_t;
3572621Sllai1 
3582621Sllai1 extern volatile uint_t  devfsadm_state; /* atomic mask for devfsadm status */
3592621Sllai1 
3602621Sllai1 #define	DEVNAME_DEVFSADM_SET_RUNNING(devfsadm_state)	\
3612621Sllai1 	devfsadm_state = DEVNAME_DEVFSADM_RUNNING
3622621Sllai1 #define	DEVNAME_DEVFSADM_SET_STOP(devfsadm_state)	\
3632621Sllai1 	devfsadm_state = DEVNAME_DEVFSADM_STOPPED
3642621Sllai1 #define	DEVNAME_DEVFSADM_SET_RUN(devfsadm_state)	\
3652621Sllai1 	devfsadm_state = DEVNAME_DEVFSADM_RUN
3662621Sllai1 #define	DEVNAME_DEVFSADM_IS_RUNNING(devfsadm_state)	\
3672621Sllai1 	devfsadm_state == DEVNAME_DEVFSADM_RUNNING
3682621Sllai1 #define	DEVNAME_DEVFSADM_HAS_RUN(devfsadm_state)	\
3692621Sllai1 	(devfsadm_state == DEVNAME_DEVFSADM_RUN)
3702621Sllai1 
3712621Sllai1 #define	SDEV_BLOCK_OTHERS(dv, cmd)	{	\
3722621Sllai1 	ASSERT(MUTEX_HELD(&dv->sdev_lookup_lock));	\
3732621Sllai1 	dv->sdev_lookup_flags |= cmd;			\
3742621Sllai1 }
3752621Sllai1 extern void sdev_unblock_others(struct sdev_node *, uint_t);
3762621Sllai1 #define	SDEV_UNBLOCK_OTHERS(dv, cmd)	{	\
3772621Sllai1 	sdev_unblock_others(dv, cmd);		\
3782621Sllai1 }
3792621Sllai1 
3802621Sllai1 #define	SDEV_CLEAR_LOOKUP_FLAGS(dv, cmd)	{	\
3812621Sllai1 	dv->sdev_lookup_flags &= ~cmd;	\
3822621Sllai1 }
3832621Sllai1 
3842621Sllai1 extern int sdev_wait4lookup(struct sdev_node *, int);
38510097SEric.Taylor@Sun.COM extern int devname_filename_register(char *);
3862621Sllai1 extern int devname_nsmaps_register(char *, size_t);
3872621Sllai1 extern void sdev_devfsadm_lockinit(void);
3882621Sllai1 extern void sdev_devfsadm_lockdestroy(void);
3892621Sllai1 extern void devname_add_devfsadm_node(char *);
3902621Sllai1 extern void sdev_devfsadmd_thread(struct sdev_node *, struct sdev_node *,
3912621Sllai1     struct cred *);
3922621Sllai1 extern int devname_profile_update(char *, size_t);
3932621Sllai1 extern struct sdev_data *sdev_find_mntinfo(char *);
3942621Sllai1 void sdev_mntinfo_rele(struct sdev_data *);
3952621Sllai1 extern struct vnodeops *devpts_getvnodeops(void);
3967688SAaron.Zang@Sun.COM extern struct vnodeops *devvt_getvnodeops(void);
3972621Sllai1 
3982621Sllai1 /*
3992621Sllai1  * boot states - warning, the ordering here is significant
4002621Sllai1  *
4012621Sllai1  * the difference between "system available" and "boot complete"
4022621Sllai1  * is a debounce timeout to catch some daemon issuing a readdir
4032621Sllai1  * triggering a nuisance implict reconfig on each boot.
4042621Sllai1  */
4052621Sllai1 #define	SDEV_BOOT_STATE_INITIAL		0
4062621Sllai1 #define	SDEV_BOOT_STATE_RECONFIG	1	/* reconfig */
4072621Sllai1 #define	SDEV_BOOT_STATE_SYSAVAIL	2	/* system available */
4082621Sllai1 #define	SDEV_BOOT_STATE_COMPLETE	3	/* boot complete */
4092621Sllai1 
4102621Sllai1 /*
4112621Sllai1  * Negative cache list and list element
4122621Sllai1  * The mutex protects the flags against multiple accesses and
4132621Sllai1  * must only be acquired when already holding the r/w lock.
4142621Sllai1  */
4152621Sllai1 typedef struct sdev_nc_list {
4162621Sllai1 	list_t		ncl_list;	/* the list itself */
4172621Sllai1 	kmutex_t	ncl_mutex;	/* protects ncl_flags */
4182621Sllai1 	krwlock_t	ncl_lock;	/* protects ncl_list */
4192621Sllai1 	int		ncl_flags;
4202621Sllai1 	int		ncl_nentries;
4212621Sllai1 } sdev_nc_list_t;
4222621Sllai1 
4232621Sllai1 typedef struct sdev_nc_node {
4242621Sllai1 	char		*ncn_name;	/* name of the node */
4252621Sllai1 	int		ncn_flags;	/* state information */
4262621Sllai1 	int		ncn_expirecnt;	/* remove once expired */
4272621Sllai1 	list_node_t	ncn_link;	/* link to next in list */
4282621Sllai1 } sdev_nc_node_t;
4292621Sllai1 
4302621Sllai1 /* ncl_flags */
4312621Sllai1 #define	NCL_LIST_DIRTY		0x01	/* needs to be flushed */
4322621Sllai1 #define	NCL_LIST_WRITING	0x02	/* write in progress */
4332621Sllai1 #define	NCL_LIST_WENABLE	0x04	/* write-enabled post boot */
4342621Sllai1 
4352621Sllai1 /* ncn_flags */
4362621Sllai1 #define	NCN_ACTIVE	0x01	/* a lookup has occurred */
4372621Sllai1 #define	NCN_SRC_STORE	0x02	/* src: persistent store */
4382621Sllai1 #define	NCN_SRC_CURRENT	0x04	/* src: current boot */
4392621Sllai1 
4402621Sllai1 /* sdev_lookup_failed flags */
4412621Sllai1 #define	SLF_NO_NCACHE	0x01	/* node should not be added to ncache */
4422621Sllai1 #define	SLF_REBUILT	0x02	/* reconfig performed during lookup attempt */
4432621Sllai1 
4442621Sllai1 /*
4452797Sjg  * The nvlist name and nvpair identifiers in the
4462797Sjg  * /etc/devices/devname_cache nvlist format
4472797Sjg  */
4482797Sjg #define	DP_DEVNAME_ID			"devname"
4492797Sjg #define	DP_DEVNAME_NCACHE_ID		"ncache"
4502797Sjg #define	DP_DEVNAME_NC_EXPIRECNT_ID	"expire-counts"
4512797Sjg 
4522797Sjg /* devname-cache list element */
4532797Sjg typedef struct nvp_devname {
4542797Sjg 	char			**nvp_paths;
4552797Sjg 	int			*nvp_expirecnts;
4562797Sjg 	int			nvp_npaths;
4572797Sjg 	list_node_t		nvp_link;
4582797Sjg } nvp_devname_t;
4592797Sjg 
4602797Sjg /*
4612621Sllai1  * name service globals and prototypes
4622621Sllai1  */
4632621Sllai1 
4642621Sllai1 /*
4652621Sllai1  * vnodeops and vfsops helpers
4662621Sllai1  */
4672621Sllai1 
4682621Sllai1 typedef enum {
4692621Sllai1 	SDEV_CACHE_ADD = 0,
4702621Sllai1 	SDEV_CACHE_DELETE
4712621Sllai1 } sdev_cache_ops_t;
4722621Sllai1 
4732621Sllai1 extern struct sdev_node *sdev_cache_lookup(struct sdev_node *, char *);
4742621Sllai1 extern int sdev_cache_update(struct sdev_node *, struct sdev_node **, char *,
4752621Sllai1     sdev_cache_ops_t);
4762621Sllai1 extern void sdev_node_cache_init(void);
4772621Sllai1 extern void sdev_node_cache_fini(void);
4782621Sllai1 extern struct sdev_node *sdev_mkroot(struct vfs *, dev_t, struct vnode *,
4792621Sllai1     struct vnode *, struct cred *);
4803843Sjg extern void sdev_filldir_dynamic(struct sdev_node *);
4812621Sllai1 extern int sdev_mknode(struct sdev_node *, char *, struct sdev_node **,
4822621Sllai1     struct vattr *, struct vnode *, void *, struct cred *, sdev_node_state_t);
48310588SEric.Taylor@Sun.COM extern int sdev_getlink(struct vnode *linkvp, char **link);
48410588SEric.Taylor@Sun.COM 
4852621Sllai1 extern int sdev_nodeinit(struct sdev_node *, char *, struct sdev_node **,
4862621Sllai1     vattr_t *);
4872621Sllai1 extern int sdev_nodeready(struct sdev_node *, vattr_t *, vnode_t *, void *,
4882621Sllai1     cred_t *);
4892621Sllai1 extern int sdev_shadow_node(struct sdev_node *, struct cred *);
4902621Sllai1 extern void sdev_nodedestroy(struct sdev_node *, uint_t);
4912621Sllai1 extern void sdev_update_timestamps(struct vnode *, cred_t *, uint_t);
4922621Sllai1 extern void sdev_vattr_merge(struct sdev_node *, struct vattr *);
4932621Sllai1 extern void sdev_devstate_change(void);
4942621Sllai1 extern int sdev_lookup_filter(sdev_node_t *, char *);
4952621Sllai1 extern void sdev_lookup_failed(sdev_node_t *, char *, int);
4962621Sllai1 extern int sdev_unlocked_access(void *, int, struct cred *);
4972621Sllai1 
4982621Sllai1 #define	SDEV_ENFORCE	0x1
4992621Sllai1 extern void sdev_stale(struct sdev_node *);
5002621Sllai1 extern int sdev_cleandir(struct sdev_node *, char *, uint_t);
5012621Sllai1 extern int sdev_rnmnode(struct sdev_node *, struct sdev_node *,
5022621Sllai1     struct sdev_node *, struct sdev_node **, char *, struct cred *);
5032621Sllai1 extern size_t add_dir_entry(dirent64_t *, char *, size_t, ino_t, offset_t);
50410588SEric.Taylor@Sun.COM extern struct vattr *sdev_getdefault_attr(enum vtype type);
5052621Sllai1 extern int sdev_to_vp(struct sdev_node *, struct vnode **);
5062621Sllai1 extern ino_t sdev_mkino(struct sdev_node *);
5072621Sllai1 extern int devname_backstore_lookup(struct sdev_node *, char *,
5082621Sllai1     struct vnode **);
5092621Sllai1 extern int sdev_is_devfs_node(char *);
5102621Sllai1 extern int sdev_copyin_mountargs(struct mounta *, struct sdev_mountargs *);
5112621Sllai1 extern int sdev_reserve_subdirs(struct sdev_node *);
5122621Sllai1 extern int prof_lookup();
5132621Sllai1 extern void prof_filldir(struct sdev_node *);
5142621Sllai1 extern int devpts_validate(struct sdev_node *dv);
5155895Syz147064 extern int devnet_validate(struct sdev_node *dv);
5168023SPhil.Kirk@Sun.COM extern int devipnet_validate(struct sdev_node *dv);
5177688SAaron.Zang@Sun.COM extern int devvt_validate(struct sdev_node *dv);
51810588SEric.Taylor@Sun.COM extern int devzvol_validate(struct sdev_node *dv);
5192621Sllai1 extern void *sdev_get_vtor(struct sdev_node *dv);
5202621Sllai1 
5212621Sllai1 /*
52210588SEric.Taylor@Sun.COM  * devinfo helpers
52310588SEric.Taylor@Sun.COM  */
52410588SEric.Taylor@Sun.COM extern int sdev_modctl_readdir(const char *, char ***, int *, int *, int);
52510588SEric.Taylor@Sun.COM extern void sdev_modctl_readdir_free(char **, int, int);
52610588SEric.Taylor@Sun.COM extern int sdev_modctl_devexists(const char *);
52710588SEric.Taylor@Sun.COM 
52810588SEric.Taylor@Sun.COM /*
5292621Sllai1  * ncache handlers
5302621Sllai1  */
5312621Sllai1 
5322621Sllai1 extern void sdev_ncache_init(void);
5332621Sllai1 extern void sdev_ncache_setup(void);
5342621Sllai1 extern void sdev_ncache_teardown(void);
5352621Sllai1 extern void sdev_nc_addname(sdev_nc_list_t *, sdev_node_t *, char *, int);
5362621Sllai1 extern void sdev_nc_node_exists(sdev_node_t *);
5372621Sllai1 extern void sdev_nc_path_exists(sdev_nc_list_t *, char *);
5382621Sllai1 extern void sdev_modctl_dump_files(void);
5392621Sllai1 
5402621Sllai1 /*
5412621Sllai1  * globals
5422621Sllai1  */
5432729Sllai1 extern kmutex_t sdev_lock;
5442621Sllai1 extern int devtype;
5452621Sllai1 extern kmem_cache_t *sdev_node_cache;
5462621Sllai1 extern struct vnodeops		*sdev_vnodeops;
5472621Sllai1 extern struct vnodeops		*devpts_vnodeops;
5485895Syz147064 extern struct vnodeops		*devnet_vnodeops;
5498023SPhil.Kirk@Sun.COM extern struct vnodeops		*devipnet_vnodeops;
5507688SAaron.Zang@Sun.COM extern struct vnodeops		*devvt_vnodeops;
5512621Sllai1 extern struct sdev_data *sdev_origins; /* mount info for global /dev instance */
55210588SEric.Taylor@Sun.COM extern struct vnodeops		*devzvol_vnodeops;
55310588SEric.Taylor@Sun.COM 
5542621Sllai1 extern const fs_operation_def_t	sdev_vnodeops_tbl[];
5552621Sllai1 extern const fs_operation_def_t	devpts_vnodeops_tbl[];
5565895Syz147064 extern const fs_operation_def_t	devnet_vnodeops_tbl[];
5578023SPhil.Kirk@Sun.COM extern const fs_operation_def_t devipnet_vnodeops_tbl[];
5587688SAaron.Zang@Sun.COM extern const fs_operation_def_t	devvt_vnodeops_tbl[];
5592621Sllai1 extern const fs_operation_def_t	devsys_vnodeops_tbl[];
5602621Sllai1 extern const fs_operation_def_t	devpseudo_vnodeops_tbl[];
56110588SEric.Taylor@Sun.COM extern const fs_operation_def_t	devzvol_vnodeops_tbl[];
5622621Sllai1 
5632621Sllai1 extern sdev_nc_list_t	*sdev_ncache;
5642621Sllai1 extern int		sdev_reconfig_boot;
5652621Sllai1 extern int		sdev_boot_state;
5662621Sllai1 extern int		sdev_reconfig_verbose;
5672621Sllai1 extern int		sdev_reconfig_disable;
5682621Sllai1 extern int		sdev_nc_disable;
5692621Sllai1 extern int		sdev_nc_disable_reset;
5702621Sllai1 extern int		sdev_nc_verbose;
5712621Sllai1 
5722621Sllai1 /*
5732621Sllai1  * misc. defines
5742621Sllai1  */
5752621Sllai1 #ifdef DEBUG
5762621Sllai1 extern int sdev_debug;
5772621Sllai1 #define	SDEV_DEBUG		0x01	/* error messages to console/log */
5782621Sllai1 #define	SDEV_DEBUG_VOPS 	0x02	/* vnode ops errors */
5792621Sllai1 #define	SDEV_DEBUG_DLF		0x04	/* trace devname_lookup_func */
5802621Sllai1 #define	SDEV_DEBUG_DRF		0x08	/* trace devname_readdir_func */
5812621Sllai1 #define	SDEV_DEBUG_NCACHE	0x10	/* negative cache tracing */
5822621Sllai1 #define	SDEV_DEBUG_DEVFSADMD	0x20	/* comm. of devnamefs & devfsadm */
5832621Sllai1 #define	SDEV_DEBUG_PTS		0x40	/* /dev/pts tracing */
5842621Sllai1 #define	SDEV_DEBUG_RECONFIG	0x80	/* events triggering reconfig */
5852621Sllai1 #define	SDEV_DEBUG_SDEV_NODE	0x100	/* trace sdev_node activities */
5862621Sllai1 #define	SDEV_DEBUG_PROFILE	0x200	/* trace sdev_profile */
5872621Sllai1 #define	SDEV_DEBUG_MODCTL	0x400	/* trace modctl activity */
5882621Sllai1 #define	SDEV_DEBUG_FLK		0x800	/* trace failed lookups */
5895895Syz147064 #define	SDEV_DEBUG_NET		0x1000	/* /dev/net tracing */
59010588SEric.Taylor@Sun.COM #define	SDEV_DEBUG_ZVOL		0x2000	/* /dev/zvol/tracing */
5912621Sllai1 
5922621Sllai1 #define	sdcmn_err(args)  if (sdev_debug & SDEV_DEBUG) printf args
5932621Sllai1 #define	sdcmn_err2(args) if (sdev_debug & SDEV_DEBUG_VOPS) printf args
5942621Sllai1 #define	sdcmn_err3(args) if (sdev_debug & SDEV_DEBUG_DLF) printf args
5952621Sllai1 #define	sdcmn_err4(args) if (sdev_debug & SDEV_DEBUG_DRF) printf args
5962621Sllai1 #define	sdcmn_err5(args) if (sdev_debug & SDEV_DEBUG_NCACHE) printf args
5972621Sllai1 #define	sdcmn_err6(args) if (sdev_debug & SDEV_DEBUG_DEVFSADMD) printf args
5982621Sllai1 #define	sdcmn_err7(args) if (sdev_debug & SDEV_DEBUG_PTS) printf args
5992621Sllai1 #define	sdcmn_err8(args) if (sdev_debug & SDEV_DEBUG_RECONFIG) printf args
6002621Sllai1 #define	sdcmn_err9(args) if (sdev_debug & SDEV_DEBUG_SDEV_NODE) printf args
6012621Sllai1 #define	sdcmn_err10(args) if (sdev_debug & SDEV_DEBUG_PROFILE) printf args
6022621Sllai1 #define	sdcmn_err11(args) if (sdev_debug & SDEV_DEBUG_MODCTL) printf args
6035895Syz147064 #define	sdcmn_err12(args) if (sdev_debug & SDEV_DEBUG_NET) printf args
60410588SEric.Taylor@Sun.COM #define	sdcmn_err13(args) if (sdev_debug & SDEV_DEBUG_ZVOL) printf args
6052621Sllai1 #define	impossible(args) printf args
6062621Sllai1 #else
6072621Sllai1 #define	sdcmn_err(args)		/* does nothing */
6082621Sllai1 #define	sdcmn_err2(args)	/* does nothing */
6092621Sllai1 #define	sdcmn_err3(args)	/* does nothing */
6102621Sllai1 #define	sdcmn_err4(args)	/* does nothing */
6112621Sllai1 #define	sdcmn_err5(args)	/* does nothing */
6122621Sllai1 #define	sdcmn_err6(args)	/* does nothing */
6132621Sllai1 #define	sdcmn_err7(args)	/* does nothing */
6142621Sllai1 #define	sdcmn_err8(args)	/* does nothing */
6152621Sllai1 #define	sdcmn_err9(args)	/* does nothing */
6162621Sllai1 #define	sdcmn_err10(args)	/* does nothing */
6172621Sllai1 #define	sdcmn_err11(args)	/* does nothing */
6185895Syz147064 #define	sdcmn_err12(args)	/* does nothing */
61910588SEric.Taylor@Sun.COM #define	sdcmn_err13(args) 	/* does nothing */
6202621Sllai1 #define	impossible(args)	/* does nothing */
6212621Sllai1 #endif
6222621Sllai1 
6232621Sllai1 #ifdef DEBUG
6242621Sllai1 #define	SD_TRACE_FAILED_LOOKUP(ddv, nm, retried)			\
6252621Sllai1 	if ((sdev_debug & SDEV_DEBUG_FLK) ||				\
6262621Sllai1 	    ((retried) && (sdev_debug & SDEV_DEBUG_RECONFIG))) {	\
6272621Sllai1 		printf("lookup of %s/%s by %s failed, line %d\n",	\
6282621Sllai1 		    (ddv)->sdev_name, (nm), curproc->p_user.u_comm,	\
6292621Sllai1 		    __LINE__);						\
6302621Sllai1 	}
6312621Sllai1 #else
6322621Sllai1 #define	SD_TRACE_FAILED_LOOKUP(ddv, nm, retried)
6332621Sllai1 #endif
6342621Sllai1 
6352621Sllai1 #endif	/* _KERNEL */
6362621Sllai1 
6372621Sllai1 #ifdef __cplusplus
6382621Sllai1 }
6392621Sllai1 #endif
6402621Sllai1 
6412621Sllai1 #endif	/* _SYS_SDEV_IMPL_H */
642