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