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