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