xref: /titanic_44/usr/src/uts/common/fs/dev/sdev_subr.c (revision 3c112a2b34403220c06c3e2fcac403358cfba168)
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  */
24 
25 /*
26  * utility routines for the /dev fs
27  */
28 
29 #include <sys/types.h>
30 #include <sys/param.h>
31 #include <sys/t_lock.h>
32 #include <sys/systm.h>
33 #include <sys/sysmacros.h>
34 #include <sys/user.h>
35 #include <sys/time.h>
36 #include <sys/vfs.h>
37 #include <sys/vnode.h>
38 #include <sys/file.h>
39 #include <sys/fcntl.h>
40 #include <sys/flock.h>
41 #include <sys/kmem.h>
42 #include <sys/uio.h>
43 #include <sys/errno.h>
44 #include <sys/stat.h>
45 #include <sys/cred.h>
46 #include <sys/dirent.h>
47 #include <sys/pathname.h>
48 #include <sys/cmn_err.h>
49 #include <sys/debug.h>
50 #include <sys/mode.h>
51 #include <sys/policy.h>
52 #include <fs/fs_subr.h>
53 #include <sys/mount.h>
54 #include <sys/fs/snode.h>
55 #include <sys/fs/dv_node.h>
56 #include <sys/fs/sdev_impl.h>
57 #include <sys/sunndi.h>
58 #include <sys/sunmdi.h>
59 #include <sys/conf.h>
60 #include <sys/proc.h>
61 #include <sys/user.h>
62 #include <sys/modctl.h>
63 
64 #ifdef DEBUG
65 int sdev_debug = 0x00000001;
66 int sdev_debug_cache_flags = 0;
67 #endif
68 
69 /*
70  * globals
71  */
72 /* prototype memory vattrs */
73 vattr_t sdev_vattr_dir = {
74 	AT_TYPE|AT_MODE|AT_UID|AT_GID,		/* va_mask */
75 	VDIR,					/* va_type */
76 	SDEV_DIRMODE_DEFAULT,			/* va_mode */
77 	SDEV_UID_DEFAULT,			/* va_uid */
78 	SDEV_GID_DEFAULT,			/* va_gid */
79 	0,					/* va_fsid */
80 	0,					/* va_nodeid */
81 	0,					/* va_nlink */
82 	0,					/* va_size */
83 	0,					/* va_atime */
84 	0,					/* va_mtime */
85 	0,					/* va_ctime */
86 	0,					/* va_rdev */
87 	0,					/* va_blksize */
88 	0,					/* va_nblocks */
89 	0					/* va_vcode */
90 };
91 
92 vattr_t sdev_vattr_lnk = {
93 	AT_TYPE|AT_MODE,			/* va_mask */
94 	VLNK,					/* va_type */
95 	SDEV_LNKMODE_DEFAULT,			/* va_mode */
96 	SDEV_UID_DEFAULT,			/* va_uid */
97 	SDEV_GID_DEFAULT,			/* va_gid */
98 	0,					/* va_fsid */
99 	0,					/* va_nodeid */
100 	0,					/* va_nlink */
101 	0,					/* va_size */
102 	0,					/* va_atime */
103 	0,					/* va_mtime */
104 	0,					/* va_ctime */
105 	0,					/* va_rdev */
106 	0,					/* va_blksize */
107 	0,					/* va_nblocks */
108 	0					/* va_vcode */
109 };
110 
111 vattr_t sdev_vattr_blk = {
112 	AT_TYPE|AT_MODE|AT_UID|AT_GID,		/* va_mask */
113 	VBLK,					/* va_type */
114 	S_IFBLK | SDEV_DEVMODE_DEFAULT,		/* va_mode */
115 	SDEV_UID_DEFAULT,			/* va_uid */
116 	SDEV_GID_DEFAULT,			/* va_gid */
117 	0,					/* va_fsid */
118 	0,					/* va_nodeid */
119 	0,					/* va_nlink */
120 	0,					/* va_size */
121 	0,					/* va_atime */
122 	0,					/* va_mtime */
123 	0,					/* va_ctime */
124 	0,					/* va_rdev */
125 	0,					/* va_blksize */
126 	0,					/* va_nblocks */
127 	0					/* va_vcode */
128 };
129 
130 vattr_t sdev_vattr_chr = {
131 	AT_TYPE|AT_MODE|AT_UID|AT_GID,		/* va_mask */
132 	VCHR,					/* va_type */
133 	S_IFCHR | SDEV_DEVMODE_DEFAULT,		/* va_mode */
134 	SDEV_UID_DEFAULT,			/* va_uid */
135 	SDEV_GID_DEFAULT,			/* va_gid */
136 	0,					/* va_fsid */
137 	0,					/* va_nodeid */
138 	0,					/* va_nlink */
139 	0,					/* va_size */
140 	0,					/* va_atime */
141 	0,					/* va_mtime */
142 	0,					/* va_ctime */
143 	0,					/* va_rdev */
144 	0,					/* va_blksize */
145 	0,					/* va_nblocks */
146 	0					/* va_vcode */
147 };
148 
149 kmem_cache_t	*sdev_node_cache;	/* sdev_node cache */
150 int		devtype;		/* fstype */
151 
152 /* static */
153 static struct vnodeops *sdev_get_vop(struct sdev_node *);
154 static void sdev_set_no_negcache(struct sdev_node *);
155 static fs_operation_def_t *sdev_merge_vtab(const fs_operation_def_t []);
156 static void sdev_free_vtab(fs_operation_def_t *);
157 
158 static void
159 sdev_prof_free(struct sdev_node *dv)
160 {
161 	ASSERT(!SDEV_IS_GLOBAL(dv));
162 	if (dv->sdev_prof.dev_name)
163 		nvlist_free(dv->sdev_prof.dev_name);
164 	if (dv->sdev_prof.dev_map)
165 		nvlist_free(dv->sdev_prof.dev_map);
166 	if (dv->sdev_prof.dev_symlink)
167 		nvlist_free(dv->sdev_prof.dev_symlink);
168 	if (dv->sdev_prof.dev_glob_incdir)
169 		nvlist_free(dv->sdev_prof.dev_glob_incdir);
170 	if (dv->sdev_prof.dev_glob_excdir)
171 		nvlist_free(dv->sdev_prof.dev_glob_excdir);
172 	bzero(&dv->sdev_prof, sizeof (dv->sdev_prof));
173 }
174 
175 /* sdev_node cache constructor */
176 /*ARGSUSED1*/
177 static int
178 i_sdev_node_ctor(void *buf, void *cfarg, int flag)
179 {
180 	struct sdev_node *dv = (struct sdev_node *)buf;
181 	struct vnode *vp;
182 
183 	bzero(buf, sizeof (struct sdev_node));
184 	vp = dv->sdev_vnode = vn_alloc(flag);
185 	if (vp == NULL) {
186 		return (-1);
187 	}
188 	vp->v_data = dv;
189 	rw_init(&dv->sdev_contents, NULL, RW_DEFAULT, NULL);
190 	return (0);
191 }
192 
193 /* sdev_node cache destructor */
194 /*ARGSUSED1*/
195 static void
196 i_sdev_node_dtor(void *buf, void *arg)
197 {
198 	struct sdev_node *dv = (struct sdev_node *)buf;
199 	struct vnode *vp = SDEVTOV(dv);
200 
201 	rw_destroy(&dv->sdev_contents);
202 	vn_free(vp);
203 }
204 
205 /* initialize sdev_node cache */
206 void
207 sdev_node_cache_init()
208 {
209 	int flags = 0;
210 
211 #ifdef	DEBUG
212 	flags = sdev_debug_cache_flags;
213 	if (flags)
214 		sdcmn_err(("cache debug flags 0x%x\n", flags));
215 #endif	/* DEBUG */
216 
217 	ASSERT(sdev_node_cache == NULL);
218 	sdev_node_cache = kmem_cache_create("sdev_node_cache",
219 	    sizeof (struct sdev_node), 0, i_sdev_node_ctor, i_sdev_node_dtor,
220 	    NULL, NULL, NULL, flags);
221 }
222 
223 /* destroy sdev_node cache */
224 void
225 sdev_node_cache_fini()
226 {
227 	ASSERT(sdev_node_cache != NULL);
228 	kmem_cache_destroy(sdev_node_cache);
229 	sdev_node_cache = NULL;
230 }
231 
232 /*
233  * Compare two nodes lexographically to balance avl tree
234  */
235 static int
236 sdev_compare_nodes(const struct sdev_node *dv1, const struct sdev_node *dv2)
237 {
238 	int rv;
239 	if ((rv = strcmp(dv1->sdev_name, dv2->sdev_name)) == 0)
240 		return (0);
241 	return ((rv < 0) ? -1 : 1);
242 }
243 
244 void
245 sdev_set_nodestate(struct sdev_node *dv, sdev_node_state_t state)
246 {
247 	ASSERT(dv);
248 	ASSERT(RW_WRITE_HELD(&dv->sdev_contents));
249 	dv->sdev_state = state;
250 }
251 
252 static void
253 sdev_attr_update(struct sdev_node *dv, vattr_t *vap)
254 {
255 	timestruc_t	now;
256 	struct vattr	*attrp;
257 	uint_t		mask;
258 
259 	ASSERT(dv->sdev_attr);
260 	ASSERT(vap);
261 
262 	attrp = dv->sdev_attr;
263 	mask = vap->va_mask;
264 	if (mask & AT_TYPE)
265 		attrp->va_type = vap->va_type;
266 	if (mask & AT_MODE)
267 		attrp->va_mode = vap->va_mode;
268 	if (mask & AT_UID)
269 		attrp->va_uid = vap->va_uid;
270 	if (mask & AT_GID)
271 		attrp->va_gid = vap->va_gid;
272 	if (mask & AT_RDEV)
273 		attrp->va_rdev = vap->va_rdev;
274 
275 	gethrestime(&now);
276 	attrp->va_atime = (mask & AT_ATIME) ? vap->va_atime : now;
277 	attrp->va_mtime = (mask & AT_MTIME) ? vap->va_mtime : now;
278 	attrp->va_ctime = (mask & AT_CTIME) ? vap->va_ctime : now;
279 }
280 
281 static void
282 sdev_attr_alloc(struct sdev_node *dv, vattr_t *vap)
283 {
284 	ASSERT(dv->sdev_attr == NULL);
285 	ASSERT(vap->va_mask & AT_TYPE);
286 	ASSERT(vap->va_mask & AT_MODE);
287 
288 	dv->sdev_attr = kmem_zalloc(sizeof (struct vattr), KM_SLEEP);
289 	sdev_attr_update(dv, vap);
290 }
291 
292 /* alloc and initialize a sdev_node */
293 int
294 sdev_nodeinit(struct sdev_node *ddv, char *nm, struct sdev_node **newdv,
295     vattr_t *vap)
296 {
297 	struct sdev_node *dv = NULL;
298 	struct vnode *vp;
299 	size_t nmlen, len;
300 	devname_handle_t  *dhl;
301 
302 	nmlen = strlen(nm) + 1;
303 	if (nmlen > MAXNAMELEN) {
304 		sdcmn_err9(("sdev_nodeinit: node name %s"
305 		    " too long\n", nm));
306 		*newdv = NULL;
307 		return (ENAMETOOLONG);
308 	}
309 
310 	dv = kmem_cache_alloc(sdev_node_cache, KM_SLEEP);
311 
312 	dv->sdev_name = kmem_alloc(nmlen, KM_SLEEP);
313 	bcopy(nm, dv->sdev_name, nmlen);
314 	dv->sdev_namelen = nmlen - 1;	/* '\0' not included */
315 	len = strlen(ddv->sdev_path) + strlen(nm) + 2;
316 	dv->sdev_path = kmem_alloc(len, KM_SLEEP);
317 	(void) snprintf(dv->sdev_path, len, "%s/%s", ddv->sdev_path, nm);
318 	/* overwritten for VLNK nodes */
319 	dv->sdev_symlink = NULL;
320 
321 	vp = SDEVTOV(dv);
322 	vn_reinit(vp);
323 	vp->v_vfsp = SDEVTOV(ddv)->v_vfsp;
324 	if (vap)
325 		vp->v_type = vap->va_type;
326 
327 	/*
328 	 * initialized to the parent's vnodeops.
329 	 * maybe overwriten for a VDIR
330 	 */
331 	vn_setops(vp, vn_getops(SDEVTOV(ddv)));
332 	vn_exists(vp);
333 
334 	dv->sdev_dotdot = NULL;
335 	dv->sdev_attrvp = NULL;
336 	if (vap) {
337 		sdev_attr_alloc(dv, vap);
338 	} else {
339 		dv->sdev_attr = NULL;
340 	}
341 
342 	dv->sdev_ino = sdev_mkino(dv);
343 	dv->sdev_nlink = 0;		/* updated on insert */
344 	dv->sdev_flags = ddv->sdev_flags; /* inherit from the parent first */
345 	dv->sdev_flags |= SDEV_BUILD;
346 	mutex_init(&dv->sdev_lookup_lock, NULL, MUTEX_DEFAULT, NULL);
347 	cv_init(&dv->sdev_lookup_cv, NULL, CV_DEFAULT, NULL);
348 	if (SDEV_IS_GLOBAL(ddv)) {
349 		dv->sdev_flags |= SDEV_GLOBAL;
350 		dhl = &(dv->sdev_handle);
351 		dhl->dh_data = dv;
352 		dhl->dh_args = NULL;
353 		sdev_set_no_negcache(dv);
354 		dv->sdev_gdir_gen = 0;
355 	} else {
356 		dv->sdev_flags &= ~SDEV_GLOBAL;
357 		dv->sdev_origin = NULL; /* set later */
358 		bzero(&dv->sdev_prof, sizeof (dv->sdev_prof));
359 		dv->sdev_ldir_gen = 0;
360 		dv->sdev_devtree_gen = 0;
361 	}
362 
363 	rw_enter(&dv->sdev_contents, RW_WRITER);
364 	sdev_set_nodestate(dv, SDEV_INIT);
365 	rw_exit(&dv->sdev_contents);
366 	*newdv = dv;
367 
368 	return (0);
369 }
370 
371 /*
372  * transition a sdev_node into SDEV_READY state
373  */
374 int
375 sdev_nodeready(struct sdev_node *dv, struct vattr *vap, struct vnode *avp,
376     void *args, struct cred *cred)
377 {
378 	int error = 0;
379 	struct vnode *vp = SDEVTOV(dv);
380 	vtype_t type;
381 
382 	ASSERT(dv && (dv->sdev_state != SDEV_READY) && vap);
383 
384 	type = vap->va_type;
385 	vp->v_type = type;
386 	vp->v_rdev = vap->va_rdev;
387 	rw_enter(&dv->sdev_contents, RW_WRITER);
388 	if (type == VDIR) {
389 		dv->sdev_nlink = 2;
390 		dv->sdev_flags &= ~SDEV_PERSIST;
391 		dv->sdev_flags &= ~SDEV_DYNAMIC;
392 		vn_setops(vp, sdev_get_vop(dv)); /* from internal vtab */
393 		ASSERT(dv->sdev_dotdot);
394 		ASSERT(SDEVTOV(dv->sdev_dotdot)->v_type == VDIR);
395 		vp->v_rdev = SDEVTOV(dv->sdev_dotdot)->v_rdev;
396 		avl_create(&dv->sdev_entries,
397 		    (int (*)(const void *, const void *))sdev_compare_nodes,
398 		    sizeof (struct sdev_node),
399 		    offsetof(struct sdev_node, sdev_avllink));
400 	} else if (type == VLNK) {
401 		ASSERT(args);
402 		dv->sdev_nlink = 1;
403 		dv->sdev_symlink = i_ddi_strdup((char *)args, KM_SLEEP);
404 	} else {
405 		dv->sdev_nlink = 1;
406 	}
407 
408 	if (!(SDEV_IS_GLOBAL(dv))) {
409 		dv->sdev_origin = (struct sdev_node *)args;
410 		dv->sdev_flags &= ~SDEV_PERSIST;
411 	}
412 
413 	/*
414 	 * shadow node is created here OR
415 	 * if failed (indicated by dv->sdev_attrvp == NULL),
416 	 * created later in sdev_setattr
417 	 */
418 	if (avp) {
419 		dv->sdev_attrvp = avp;
420 	} else {
421 		if (dv->sdev_attr == NULL) {
422 			sdev_attr_alloc(dv, vap);
423 		} else {
424 			sdev_attr_update(dv, vap);
425 		}
426 
427 		if ((dv->sdev_attrvp == NULL) && SDEV_IS_PERSIST(dv))
428 			error = sdev_shadow_node(dv, cred);
429 	}
430 
431 	if (error == 0) {
432 		/* transition to READY state */
433 		sdev_set_nodestate(dv, SDEV_READY);
434 		sdev_nc_node_exists(dv);
435 	} else {
436 		sdev_set_nodestate(dv, SDEV_ZOMBIE);
437 	}
438 	rw_exit(&dv->sdev_contents);
439 	return (error);
440 }
441 
442 /*
443  * setting ZOMBIE state
444  */
445 static int
446 sdev_nodezombied(struct sdev_node *dv)
447 {
448 	rw_enter(&dv->sdev_contents, RW_WRITER);
449 	sdev_set_nodestate(dv, SDEV_ZOMBIE);
450 	rw_exit(&dv->sdev_contents);
451 	return (0);
452 }
453 
454 /*
455  * Build the VROOT sdev_node.
456  */
457 /*ARGSUSED*/
458 struct sdev_node *
459 sdev_mkroot(struct vfs *vfsp, dev_t devdev, struct vnode *mvp,
460     struct vnode *avp, struct cred *cred)
461 {
462 	struct sdev_node *dv;
463 	struct vnode *vp;
464 	char devdir[] = "/dev";
465 
466 	ASSERT(sdev_node_cache != NULL);
467 	ASSERT(avp);
468 	dv = kmem_cache_alloc(sdev_node_cache, KM_SLEEP);
469 	vp = SDEVTOV(dv);
470 	vn_reinit(vp);
471 	vp->v_flag |= VROOT;
472 	vp->v_vfsp = vfsp;
473 	vp->v_type = VDIR;
474 	vp->v_rdev = devdev;
475 	vn_setops(vp, sdev_vnodeops); /* apply the default vnodeops at /dev */
476 	vn_exists(vp);
477 
478 	if (vfsp->vfs_mntpt)
479 		dv->sdev_name = i_ddi_strdup(
480 		    (char *)refstr_value(vfsp->vfs_mntpt), KM_SLEEP);
481 	else
482 		/* vfs_mountdev1 set mount point later */
483 		dv->sdev_name = i_ddi_strdup("/dev", KM_SLEEP);
484 	dv->sdev_namelen = strlen(dv->sdev_name); /* '\0' not included */
485 	dv->sdev_path = i_ddi_strdup(devdir, KM_SLEEP);
486 	dv->sdev_ino = SDEV_ROOTINO;
487 	dv->sdev_nlink = 2;		/* name + . (no sdev_insert) */
488 	dv->sdev_dotdot = dv;		/* .. == self */
489 	dv->sdev_attrvp = avp;
490 	dv->sdev_attr = NULL;
491 	mutex_init(&dv->sdev_lookup_lock, NULL, MUTEX_DEFAULT, NULL);
492 	cv_init(&dv->sdev_lookup_cv, NULL, CV_DEFAULT, NULL);
493 	if (strcmp(dv->sdev_name, "/dev") == 0) {
494 		dv->sdev_flags = SDEV_BUILD|SDEV_GLOBAL|SDEV_PERSIST;
495 		bzero(&dv->sdev_handle, sizeof (dv->sdev_handle));
496 		dv->sdev_gdir_gen = 0;
497 	} else {
498 		dv->sdev_flags = SDEV_BUILD;
499 		dv->sdev_flags &= ~SDEV_PERSIST;
500 		bzero(&dv->sdev_prof, sizeof (dv->sdev_prof));
501 		dv->sdev_ldir_gen = 0;
502 		dv->sdev_devtree_gen = 0;
503 	}
504 
505 	avl_create(&dv->sdev_entries,
506 	    (int (*)(const void *, const void *))sdev_compare_nodes,
507 	    sizeof (struct sdev_node),
508 	    offsetof(struct sdev_node, sdev_avllink));
509 
510 	rw_enter(&dv->sdev_contents, RW_WRITER);
511 	sdev_set_nodestate(dv, SDEV_READY);
512 	rw_exit(&dv->sdev_contents);
513 	sdev_nc_node_exists(dv);
514 	return (dv);
515 }
516 
517 /* directory dependent vop table */
518 struct sdev_vop_table {
519 	char *vt_name;				/* subdirectory name */
520 	const fs_operation_def_t *vt_service;	/* vnodeops table */
521 	struct vnodeops *vt_vops;		/* constructed vop */
522 	struct vnodeops **vt_global_vops;	/* global container for vop */
523 	int (*vt_vtor)(struct sdev_node *);	/* validate sdev_node */
524 	int vt_flags;
525 };
526 
527 /*
528  * A nice improvement would be to provide a plug-in mechanism
529  * for this table instead of a const table.
530  */
531 static struct sdev_vop_table vtab[] =
532 {
533 	{ "pts", devpts_vnodeops_tbl, NULL, &devpts_vnodeops, devpts_validate,
534 	SDEV_DYNAMIC | SDEV_VTOR },
535 
536 	{ "vt", devvt_vnodeops_tbl, NULL, &devvt_vnodeops, devvt_validate,
537 	SDEV_DYNAMIC | SDEV_VTOR },
538 
539 	{ "zvol", devzvol_vnodeops_tbl, NULL, &devzvol_vnodeops,
540 	devzvol_validate, SDEV_DYNAMIC | SDEV_VTOR | SDEV_SUBDIR },
541 
542 	{ "zcons", NULL, NULL, NULL, NULL, SDEV_NO_NCACHE },
543 
544 	{ "net", devnet_vnodeops_tbl, NULL, &devnet_vnodeops, devnet_validate,
545 	SDEV_DYNAMIC | SDEV_VTOR },
546 
547 	{ "ipnet", devipnet_vnodeops_tbl, NULL, &devipnet_vnodeops,
548 	devipnet_validate, SDEV_DYNAMIC | SDEV_VTOR | SDEV_NO_NCACHE },
549 
550 	{ "lofi", NULL, NULL, NULL, NULL, SDEV_ZONED },
551 	{ "rlofi", NULL, NULL, NULL, NULL, SDEV_ZONED },
552 
553 	{ NULL, NULL, NULL, NULL, NULL, 0}
554 };
555 
556 struct sdev_vop_table *
557 sdev_match(struct sdev_node *dv)
558 {
559 	int vlen;
560 	int i;
561 
562 	for (i = 0; vtab[i].vt_name; i++) {
563 		if (strcmp(vtab[i].vt_name, dv->sdev_name) == 0)
564 			return (&vtab[i]);
565 		if (vtab[i].vt_flags & SDEV_SUBDIR) {
566 			char *ptr;
567 
568 			ASSERT(strlen(dv->sdev_path) > 5);
569 			ptr = dv->sdev_path + 5;
570 			vlen = strlen(vtab[i].vt_name);
571 			if ((strncmp(vtab[i].vt_name, ptr,
572 			    vlen - 1) == 0) && ptr[vlen] == '/')
573 				return (&vtab[i]);
574 		}
575 
576 	}
577 	return (NULL);
578 }
579 
580 /*
581  *  sets a directory's vnodeops if the directory is in the vtab;
582  */
583 static struct vnodeops *
584 sdev_get_vop(struct sdev_node *dv)
585 {
586 	struct sdev_vop_table *vtp;
587 	char *path;
588 
589 	path = dv->sdev_path;
590 	ASSERT(path);
591 
592 	/* gets the relative path to /dev/ */
593 	path += 5;
594 
595 	/* gets the vtab entry it matches */
596 	if ((vtp = sdev_match(dv)) != NULL) {
597 		dv->sdev_flags |= vtp->vt_flags;
598 
599 		if (vtp->vt_vops) {
600 			if (vtp->vt_global_vops)
601 				*(vtp->vt_global_vops) = vtp->vt_vops;
602 			return (vtp->vt_vops);
603 		}
604 
605 		if (vtp->vt_service) {
606 			fs_operation_def_t *templ;
607 			templ = sdev_merge_vtab(vtp->vt_service);
608 			if (vn_make_ops(vtp->vt_name,
609 			    (const fs_operation_def_t *)templ,
610 			    &vtp->vt_vops) != 0) {
611 				cmn_err(CE_PANIC, "%s: malformed vnode ops\n",
612 				    vtp->vt_name);
613 				/*NOTREACHED*/
614 			}
615 			if (vtp->vt_global_vops) {
616 				*(vtp->vt_global_vops) = vtp->vt_vops;
617 			}
618 			sdev_free_vtab(templ);
619 			return (vtp->vt_vops);
620 		}
621 		return (sdev_vnodeops);
622 	}
623 
624 	/* child inherits the persistence of the parent */
625 	if (SDEV_IS_PERSIST(dv->sdev_dotdot))
626 		dv->sdev_flags |= SDEV_PERSIST;
627 
628 	return (sdev_vnodeops);
629 }
630 
631 static void
632 sdev_set_no_negcache(struct sdev_node *dv)
633 {
634 	int i;
635 	char *path;
636 
637 	ASSERT(dv->sdev_path);
638 	path = dv->sdev_path + strlen("/dev/");
639 
640 	for (i = 0; vtab[i].vt_name; i++) {
641 		if (strcmp(vtab[i].vt_name, path) == 0) {
642 			if (vtab[i].vt_flags & SDEV_NO_NCACHE)
643 				dv->sdev_flags |= SDEV_NO_NCACHE;
644 			break;
645 		}
646 	}
647 }
648 
649 void *
650 sdev_get_vtor(struct sdev_node *dv)
651 {
652 	struct sdev_vop_table *vtp;
653 
654 	vtp = sdev_match(dv);
655 	if (vtp)
656 		return ((void *)vtp->vt_vtor);
657 	else
658 		return (NULL);
659 }
660 
661 /*
662  * Build the base root inode
663  */
664 ino_t
665 sdev_mkino(struct sdev_node *dv)
666 {
667 	ino_t	ino;
668 
669 	/*
670 	 * for now, follow the lead of tmpfs here
671 	 * need to someday understand the requirements here
672 	 */
673 	ino = (ino_t)(uint32_t)((uintptr_t)dv >> 3);
674 	ino += SDEV_ROOTINO + 1;
675 
676 	return (ino);
677 }
678 
679 int
680 sdev_getlink(struct vnode *linkvp, char **link)
681 {
682 	int err;
683 	char *buf;
684 	struct uio uio = {0};
685 	struct iovec iov = {0};
686 
687 	if (linkvp == NULL)
688 		return (ENOENT);
689 	ASSERT(linkvp->v_type == VLNK);
690 
691 	buf = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
692 	iov.iov_base = buf;
693 	iov.iov_len = MAXPATHLEN;
694 	uio.uio_iov = &iov;
695 	uio.uio_iovcnt = 1;
696 	uio.uio_resid = MAXPATHLEN;
697 	uio.uio_segflg = UIO_SYSSPACE;
698 	uio.uio_llimit = MAXOFFSET_T;
699 
700 	err = VOP_READLINK(linkvp, &uio, kcred, NULL);
701 	if (err) {
702 		cmn_err(CE_WARN, "readlink %s failed in dev\n", buf);
703 		kmem_free(buf, MAXPATHLEN);
704 		return (ENOENT);
705 	}
706 
707 	/* mission complete */
708 	*link = i_ddi_strdup(buf, KM_SLEEP);
709 	kmem_free(buf, MAXPATHLEN);
710 	return (0);
711 }
712 
713 /*
714  * A convenient wrapper to get the devfs node vnode for a device
715  * minor functionality: readlink() of a /dev symlink
716  * Place the link into dv->sdev_symlink
717  */
718 static int
719 sdev_follow_link(struct sdev_node *dv)
720 {
721 	int err;
722 	struct vnode *linkvp;
723 	char *link = NULL;
724 
725 	linkvp = SDEVTOV(dv);
726 	if (linkvp == NULL)
727 		return (ENOENT);
728 	ASSERT(linkvp->v_type == VLNK);
729 	err = sdev_getlink(linkvp, &link);
730 	if (err) {
731 		(void) sdev_nodezombied(dv);
732 		dv->sdev_symlink = NULL;
733 		return (ENOENT);
734 	}
735 
736 	ASSERT(link != NULL);
737 	dv->sdev_symlink = link;
738 	return (0);
739 }
740 
741 static int
742 sdev_node_check(struct sdev_node *dv, struct vattr *nvap, void *nargs)
743 {
744 	vtype_t otype = SDEVTOV(dv)->v_type;
745 
746 	/*
747 	 * existing sdev_node has a different type.
748 	 */
749 	if (otype != nvap->va_type) {
750 		sdcmn_err9(("sdev_node_check: existing node "
751 		    "  %s type %d does not match new node type %d\n",
752 		    dv->sdev_name, otype, nvap->va_type));
753 		return (EEXIST);
754 	}
755 
756 	/*
757 	 * For a symlink, the target should be the same.
758 	 */
759 	if (otype == VLNK) {
760 		ASSERT(nargs != NULL);
761 		ASSERT(dv->sdev_symlink != NULL);
762 		if (strcmp(dv->sdev_symlink, (char *)nargs) != 0) {
763 			sdcmn_err9(("sdev_node_check: existing node "
764 			    " %s has different symlink %s as new node "
765 			    " %s\n", dv->sdev_name, dv->sdev_symlink,
766 			    (char *)nargs));
767 			return (EEXIST);
768 		}
769 	}
770 
771 	return (0);
772 }
773 
774 /*
775  * sdev_mknode - a wrapper for sdev_nodeinit(), sdev_nodeready()
776  *
777  * arguments:
778  *	- ddv (parent)
779  *	- nm (child name)
780  *	- newdv (sdev_node for nm is returned here)
781  *	- vap (vattr for the node to be created, va_type should be set.
782  *	- avp (attribute vnode)
783  *	  the defaults should be used if unknown)
784  *	- cred
785  *	- args
786  *	    . tnm (for VLNK)
787  *	    . global sdev_node (for !SDEV_GLOBAL)
788  * 	- state: SDEV_INIT, SDEV_READY
789  *
790  * only ddv, nm, newddv, vap, cred are required for sdev_mknode(SDEV_INIT)
791  *
792  * NOTE:  directory contents writers lock needs to be held before
793  *	  calling this routine.
794  */
795 int
796 sdev_mknode(struct sdev_node *ddv, char *nm, struct sdev_node **newdv,
797     struct vattr *vap, struct vnode *avp, void *args, struct cred *cred,
798     sdev_node_state_t state)
799 {
800 	int error = 0;
801 	sdev_node_state_t node_state;
802 	struct sdev_node *dv = NULL;
803 
804 	ASSERT(state != SDEV_ZOMBIE);
805 	ASSERT(RW_WRITE_HELD(&ddv->sdev_contents));
806 
807 	if (*newdv) {
808 		dv = *newdv;
809 	} else {
810 		/* allocate and initialize a sdev_node */
811 		if (ddv->sdev_state == SDEV_ZOMBIE) {
812 			sdcmn_err9(("sdev_mknode: parent %s ZOMBIEd\n",
813 			    ddv->sdev_path));
814 			return (ENOENT);
815 		}
816 
817 		error = sdev_nodeinit(ddv, nm, &dv, vap);
818 		if (error != 0) {
819 			sdcmn_err9(("sdev_mknode: error %d,"
820 			    " name %s can not be initialized\n",
821 			    error, nm));
822 			return (error);
823 		}
824 		ASSERT(dv);
825 
826 		/* insert into the directory cache */
827 		error = sdev_cache_update(ddv, &dv, nm, SDEV_CACHE_ADD);
828 		if (error) {
829 			sdcmn_err9(("sdev_mknode: node %s can not"
830 			    " be added into directory cache\n", nm));
831 			return (ENOENT);
832 		}
833 	}
834 
835 	ASSERT(dv);
836 	node_state = dv->sdev_state;
837 	ASSERT(node_state != SDEV_ZOMBIE);
838 
839 	if (state == SDEV_READY) {
840 		switch (node_state) {
841 		case SDEV_INIT:
842 			error = sdev_nodeready(dv, vap, avp, args, cred);
843 			if (error) {
844 				sdcmn_err9(("sdev_mknode: node %s can NOT"
845 				    " be transitioned into READY state, "
846 				    "error %d\n", nm, error));
847 			}
848 			break;
849 		case SDEV_READY:
850 			/*
851 			 * Do some sanity checking to make sure
852 			 * the existing sdev_node is what has been
853 			 * asked for.
854 			 */
855 			error = sdev_node_check(dv, vap, args);
856 			break;
857 		default:
858 			break;
859 		}
860 	}
861 
862 	if (!error) {
863 		*newdv = dv;
864 		ASSERT((*newdv)->sdev_state != SDEV_ZOMBIE);
865 	} else {
866 		SDEV_SIMPLE_RELE(dv);
867 		*newdv = NULL;
868 	}
869 
870 	return (error);
871 }
872 
873 /*
874  * convenient wrapper to change vp's ATIME, CTIME and MTIME
875  */
876 void
877 sdev_update_timestamps(struct vnode *vp, cred_t *cred, uint_t mask)
878 {
879 	struct vattr attr;
880 	timestruc_t now;
881 	int err;
882 
883 	ASSERT(vp);
884 	gethrestime(&now);
885 	if (mask & AT_CTIME)
886 		attr.va_ctime = now;
887 	if (mask & AT_MTIME)
888 		attr.va_mtime = now;
889 	if (mask & AT_ATIME)
890 		attr.va_atime = now;
891 
892 	attr.va_mask = (mask & AT_TIMES);
893 	err = VOP_SETATTR(vp, &attr, 0, cred, NULL);
894 	if (err && (err != EROFS)) {
895 		sdcmn_err(("update timestamps error %d\n", err));
896 	}
897 }
898 
899 /*
900  * the backing store vnode is released here
901  */
902 /*ARGSUSED1*/
903 void
904 sdev_nodedestroy(struct sdev_node *dv, uint_t flags)
905 {
906 	/* no references */
907 	ASSERT(dv->sdev_nlink == 0);
908 
909 	if (dv->sdev_attrvp != NULLVP) {
910 		VN_RELE(dv->sdev_attrvp);
911 		/*
912 		 * reset the attrvp so that no more
913 		 * references can be made on this already
914 		 * vn_rele() vnode
915 		 */
916 		dv->sdev_attrvp = NULLVP;
917 	}
918 
919 	if (dv->sdev_attr != NULL) {
920 		kmem_free(dv->sdev_attr, sizeof (struct vattr));
921 		dv->sdev_attr = NULL;
922 	}
923 
924 	if (dv->sdev_name != NULL) {
925 		kmem_free(dv->sdev_name, dv->sdev_namelen + 1);
926 		dv->sdev_name = NULL;
927 	}
928 
929 	if (dv->sdev_symlink != NULL) {
930 		kmem_free(dv->sdev_symlink, strlen(dv->sdev_symlink) + 1);
931 		dv->sdev_symlink = NULL;
932 	}
933 
934 	if (dv->sdev_path) {
935 		kmem_free(dv->sdev_path, strlen(dv->sdev_path) + 1);
936 		dv->sdev_path = NULL;
937 	}
938 
939 	if (!SDEV_IS_GLOBAL(dv))
940 		sdev_prof_free(dv);
941 
942 	if (SDEVTOV(dv)->v_type == VDIR) {
943 		ASSERT(SDEV_FIRST_ENTRY(dv) == NULL);
944 		avl_destroy(&dv->sdev_entries);
945 	}
946 
947 	mutex_destroy(&dv->sdev_lookup_lock);
948 	cv_destroy(&dv->sdev_lookup_cv);
949 
950 	/* return node to initial state as per constructor */
951 	(void) memset((void *)&dv->sdev_instance_data, 0,
952 	    sizeof (dv->sdev_instance_data));
953 	vn_invalid(SDEVTOV(dv));
954 	kmem_cache_free(sdev_node_cache, dv);
955 }
956 
957 /*
958  * DIRECTORY CACHE lookup
959  */
960 struct sdev_node *
961 sdev_findbyname(struct sdev_node *ddv, char *nm)
962 {
963 	struct sdev_node *dv;
964 	struct sdev_node dvtmp;
965 	avl_index_t	where;
966 
967 	ASSERT(RW_LOCK_HELD(&ddv->sdev_contents));
968 
969 	dvtmp.sdev_name = nm;
970 	dv = avl_find(&ddv->sdev_entries, &dvtmp, &where);
971 	if (dv) {
972 		ASSERT(dv->sdev_dotdot == ddv);
973 		ASSERT(strcmp(dv->sdev_name, nm) == 0);
974 		SDEV_HOLD(dv);
975 		return (dv);
976 	}
977 	return (NULL);
978 }
979 
980 /*
981  * Inserts a new sdev_node in a parent directory
982  */
983 void
984 sdev_direnter(struct sdev_node *ddv, struct sdev_node *dv)
985 {
986 	avl_index_t where;
987 
988 	ASSERT(RW_WRITE_HELD(&ddv->sdev_contents));
989 	ASSERT(SDEVTOV(ddv)->v_type == VDIR);
990 	ASSERT(ddv->sdev_nlink >= 2);
991 	ASSERT(dv->sdev_nlink == 0);
992 
993 	dv->sdev_dotdot = ddv;
994 	VERIFY(avl_find(&ddv->sdev_entries, dv, &where) == NULL);
995 	avl_insert(&ddv->sdev_entries, dv, where);
996 	ddv->sdev_nlink++;
997 }
998 
999 /*
1000  * The following check is needed because while sdev_nodes are linked
1001  * in SDEV_INIT state, they have their link counts incremented only
1002  * in SDEV_READY state.
1003  */
1004 static void
1005 decr_link(struct sdev_node *dv)
1006 {
1007 	if (dv->sdev_state != SDEV_INIT)
1008 		dv->sdev_nlink--;
1009 	else
1010 		ASSERT(dv->sdev_nlink == 0);
1011 }
1012 
1013 /*
1014  * Delete an existing dv from directory cache
1015  *
1016  * In the case of a node is still held by non-zero reference count,
1017  *     the node is put into ZOMBIE state. Once the reference count
1018  *     reaches "0", the node is unlinked and destroyed,
1019  *     in sdev_inactive().
1020  */
1021 static int
1022 sdev_dirdelete(struct sdev_node *ddv, struct sdev_node *dv)
1023 {
1024 	struct vnode *vp;
1025 
1026 	ASSERT(RW_WRITE_HELD(&ddv->sdev_contents));
1027 
1028 	vp = SDEVTOV(dv);
1029 	mutex_enter(&vp->v_lock);
1030 
1031 	/* dv is held still */
1032 	if (vp->v_count > 1) {
1033 		rw_enter(&dv->sdev_contents, RW_WRITER);
1034 		if (dv->sdev_state == SDEV_READY) {
1035 			sdcmn_err9((
1036 			    "sdev_dirdelete: node %s busy with count %d\n",
1037 			    dv->sdev_name, vp->v_count));
1038 			dv->sdev_state = SDEV_ZOMBIE;
1039 		}
1040 		rw_exit(&dv->sdev_contents);
1041 		--vp->v_count;
1042 		mutex_exit(&vp->v_lock);
1043 		return (EBUSY);
1044 	}
1045 	ASSERT(vp->v_count == 1);
1046 
1047 	/* unlink from the memory cache */
1048 	ddv->sdev_nlink--;	/* .. to above */
1049 	if (vp->v_type == VDIR) {
1050 		decr_link(dv);		/* . to self */
1051 	}
1052 
1053 	avl_remove(&ddv->sdev_entries, dv);
1054 	decr_link(dv);	/* name, back to zero */
1055 	vp->v_count--;
1056 	mutex_exit(&vp->v_lock);
1057 
1058 	/* destroy the node */
1059 	sdev_nodedestroy(dv, 0);
1060 	return (0);
1061 }
1062 
1063 /*
1064  * check if the source is in the path of the target
1065  *
1066  * source and target are different
1067  */
1068 /*ARGSUSED2*/
1069 static int
1070 sdev_checkpath(struct sdev_node *sdv, struct sdev_node *tdv, struct cred *cred)
1071 {
1072 	int error = 0;
1073 	struct sdev_node *dotdot, *dir;
1074 
1075 	dotdot = tdv->sdev_dotdot;
1076 	ASSERT(dotdot);
1077 
1078 	/* fs root */
1079 	if (dotdot == tdv) {
1080 		return (0);
1081 	}
1082 
1083 	for (;;) {
1084 		/*
1085 		 * avoid error cases like
1086 		 *	mv a a/b
1087 		 *	mv a a/b/c
1088 		 *	etc.
1089 		 */
1090 		if (dotdot == sdv) {
1091 			error = EINVAL;
1092 			break;
1093 		}
1094 
1095 		dir = dotdot;
1096 		dotdot = dir->sdev_dotdot;
1097 
1098 		/* done checking because root is reached */
1099 		if (dir == dotdot) {
1100 			break;
1101 		}
1102 	}
1103 	return (error);
1104 }
1105 
1106 int
1107 sdev_rnmnode(struct sdev_node *oddv, struct sdev_node *odv,
1108     struct sdev_node *nddv, struct sdev_node **ndvp, char *nnm,
1109     struct cred *cred)
1110 {
1111 	int error = 0;
1112 	struct vnode *ovp = SDEVTOV(odv);
1113 	struct vnode *nvp;
1114 	struct vattr vattr;
1115 	int doingdir = (ovp->v_type == VDIR);
1116 	char *link = NULL;
1117 	int samedir = (oddv == nddv) ? 1 : 0;
1118 	int bkstore = 0;
1119 	struct sdev_node *idv = NULL;
1120 	struct sdev_node *ndv = NULL;
1121 	timestruc_t now;
1122 
1123 	vattr.va_mask = AT_TYPE|AT_MODE|AT_UID|AT_GID;
1124 	error = VOP_GETATTR(ovp, &vattr, 0, cred, NULL);
1125 	if (error)
1126 		return (error);
1127 
1128 	if (!samedir)
1129 		rw_enter(&oddv->sdev_contents, RW_WRITER);
1130 	rw_enter(&nddv->sdev_contents, RW_WRITER);
1131 
1132 	/*
1133 	 * the source may have been deleted by another thread before
1134 	 * we gets here.
1135 	 */
1136 	if (odv->sdev_state != SDEV_READY) {
1137 		error = ENOENT;
1138 		goto err_out;
1139 	}
1140 
1141 	if (doingdir && (odv == nddv)) {
1142 		error = EINVAL;
1143 		goto err_out;
1144 	}
1145 
1146 	/*
1147 	 * If renaming a directory, and the parents are different (".." must be
1148 	 * changed) then the source dir must not be in the dir hierarchy above
1149 	 * the target since it would orphan everything below the source dir.
1150 	 */
1151 	if (doingdir && (oddv != nddv)) {
1152 		error = sdev_checkpath(odv, nddv, cred);
1153 		if (error)
1154 			goto err_out;
1155 	}
1156 
1157 	/* destination existing */
1158 	if (*ndvp) {
1159 		nvp = SDEVTOV(*ndvp);
1160 		ASSERT(nvp);
1161 
1162 		/* handling renaming to itself */
1163 		if (odv == *ndvp) {
1164 			error = 0;
1165 			goto err_out;
1166 		}
1167 
1168 		if (nvp->v_type == VDIR) {
1169 			if (!doingdir) {
1170 				error = EISDIR;
1171 				goto err_out;
1172 			}
1173 
1174 			if (vn_vfswlock(nvp)) {
1175 				error = EBUSY;
1176 				goto err_out;
1177 			}
1178 
1179 			if (vn_mountedvfs(nvp) != NULL) {
1180 				vn_vfsunlock(nvp);
1181 				error = EBUSY;
1182 				goto err_out;
1183 			}
1184 
1185 			/* in case dir1 exists in dir2 and "mv dir1 dir2" */
1186 			if ((*ndvp)->sdev_nlink > 2) {
1187 				vn_vfsunlock(nvp);
1188 				error = EEXIST;
1189 				goto err_out;
1190 			}
1191 			vn_vfsunlock(nvp);
1192 
1193 			(void) sdev_dirdelete(nddv, *ndvp);
1194 			*ndvp = NULL;
1195 			ASSERT(nddv->sdev_attrvp);
1196 			error = VOP_RMDIR(nddv->sdev_attrvp, nnm,
1197 			    nddv->sdev_attrvp, cred, NULL, 0);
1198 			if (error)
1199 				goto err_out;
1200 		} else {
1201 			if (doingdir) {
1202 				error = ENOTDIR;
1203 				goto err_out;
1204 			}
1205 
1206 			if (SDEV_IS_PERSIST((*ndvp))) {
1207 				bkstore = 1;
1208 			}
1209 
1210 			/*
1211 			 * get rid of the node from the directory cache
1212 			 * note, in case EBUSY is returned, the ZOMBIE
1213 			 * node is taken care in sdev_mknode.
1214 			 */
1215 			(void) sdev_dirdelete(nddv, *ndvp);
1216 			*ndvp = NULL;
1217 			if (bkstore) {
1218 				ASSERT(nddv->sdev_attrvp);
1219 				error = VOP_REMOVE(nddv->sdev_attrvp,
1220 				    nnm, cred, NULL, 0);
1221 				if (error)
1222 					goto err_out;
1223 			}
1224 		}
1225 	}
1226 
1227 	/* fix the source for a symlink */
1228 	if (vattr.va_type == VLNK) {
1229 		if (odv->sdev_symlink == NULL) {
1230 			error = sdev_follow_link(odv);
1231 			if (error) {
1232 				error = ENOENT;
1233 				goto err_out;
1234 			}
1235 		}
1236 		ASSERT(odv->sdev_symlink);
1237 		link = i_ddi_strdup(odv->sdev_symlink, KM_SLEEP);
1238 	}
1239 
1240 	/*
1241 	 * make a fresh node from the source attrs
1242 	 */
1243 	ASSERT(RW_WRITE_HELD(&nddv->sdev_contents));
1244 	error = sdev_mknode(nddv, nnm, ndvp, &vattr,
1245 	    NULL, (void *)link, cred, SDEV_READY);
1246 
1247 	if (link)
1248 		kmem_free(link, strlen(link) + 1);
1249 
1250 	if (error)
1251 		goto err_out;
1252 	ASSERT(*ndvp);
1253 	ASSERT((*ndvp)->sdev_state == SDEV_READY);
1254 
1255 	/* move dir contents */
1256 	if (doingdir) {
1257 		for (idv = SDEV_FIRST_ENTRY(odv); idv;
1258 		    idv = SDEV_NEXT_ENTRY(odv, idv)) {
1259 			error = sdev_rnmnode(odv, idv,
1260 			    (struct sdev_node *)(*ndvp), &ndv,
1261 			    idv->sdev_name, cred);
1262 			if (error)
1263 				goto err_out;
1264 			ndv = NULL;
1265 		}
1266 	}
1267 
1268 	if ((*ndvp)->sdev_attrvp) {
1269 		sdev_update_timestamps((*ndvp)->sdev_attrvp, kcred,
1270 		    AT_CTIME|AT_ATIME);
1271 	} else {
1272 		ASSERT((*ndvp)->sdev_attr);
1273 		gethrestime(&now);
1274 		(*ndvp)->sdev_attr->va_ctime = now;
1275 		(*ndvp)->sdev_attr->va_atime = now;
1276 	}
1277 
1278 	if (nddv->sdev_attrvp) {
1279 		sdev_update_timestamps(nddv->sdev_attrvp, kcred,
1280 		    AT_MTIME|AT_ATIME);
1281 	} else {
1282 		ASSERT(nddv->sdev_attr);
1283 		gethrestime(&now);
1284 		nddv->sdev_attr->va_mtime = now;
1285 		nddv->sdev_attr->va_atime = now;
1286 	}
1287 	rw_exit(&nddv->sdev_contents);
1288 	if (!samedir)
1289 		rw_exit(&oddv->sdev_contents);
1290 
1291 	SDEV_RELE(*ndvp);
1292 	return (error);
1293 
1294 err_out:
1295 	rw_exit(&nddv->sdev_contents);
1296 	if (!samedir)
1297 		rw_exit(&oddv->sdev_contents);
1298 	return (error);
1299 }
1300 
1301 /*
1302  * Merge sdev_node specific information into an attribute structure.
1303  *
1304  * note: sdev_node is not locked here
1305  */
1306 void
1307 sdev_vattr_merge(struct sdev_node *dv, struct vattr *vap)
1308 {
1309 	struct vnode *vp = SDEVTOV(dv);
1310 
1311 	vap->va_nlink = dv->sdev_nlink;
1312 	vap->va_nodeid = dv->sdev_ino;
1313 	vap->va_fsid = SDEVTOV(dv->sdev_dotdot)->v_rdev;
1314 	vap->va_type = vp->v_type;
1315 
1316 	if (vp->v_type == VDIR) {
1317 		vap->va_rdev = 0;
1318 		vap->va_fsid = vp->v_rdev;
1319 	} else if (vp->v_type == VLNK) {
1320 		vap->va_rdev = 0;
1321 		vap->va_mode  &= ~S_IFMT;
1322 		vap->va_mode |= S_IFLNK;
1323 	} else if ((vp->v_type == VCHR) || (vp->v_type == VBLK)) {
1324 		vap->va_rdev = vp->v_rdev;
1325 		vap->va_mode &= ~S_IFMT;
1326 		if (vap->va_type == VCHR)
1327 			vap->va_mode |= S_IFCHR;
1328 		else
1329 			vap->va_mode |= S_IFBLK;
1330 	} else {
1331 		vap->va_rdev = 0;
1332 	}
1333 }
1334 
1335 struct vattr *
1336 sdev_getdefault_attr(enum vtype type)
1337 {
1338 	if (type == VDIR)
1339 		return (&sdev_vattr_dir);
1340 	else if (type == VCHR)
1341 		return (&sdev_vattr_chr);
1342 	else if (type == VBLK)
1343 		return (&sdev_vattr_blk);
1344 	else if (type == VLNK)
1345 		return (&sdev_vattr_lnk);
1346 	else
1347 		return (NULL);
1348 }
1349 int
1350 sdev_to_vp(struct sdev_node *dv, struct vnode **vpp)
1351 {
1352 	int rv = 0;
1353 	struct vnode *vp = SDEVTOV(dv);
1354 
1355 	switch (vp->v_type) {
1356 	case VCHR:
1357 	case VBLK:
1358 		/*
1359 		 * If vnode is a device, return special vnode instead
1360 		 * (though it knows all about -us- via sp->s_realvp)
1361 		 */
1362 		*vpp = specvp(vp, vp->v_rdev, vp->v_type, kcred);
1363 		VN_RELE(vp);
1364 		if (*vpp == NULLVP)
1365 			rv = ENOSYS;
1366 		break;
1367 	default:	/* most types are returned as is */
1368 		*vpp = vp;
1369 		break;
1370 	}
1371 	return (rv);
1372 }
1373 
1374 /*
1375  * junction between devname and root file system, e.g. ufs
1376  */
1377 int
1378 devname_backstore_lookup(struct sdev_node *ddv, char *nm, struct vnode **rvp)
1379 {
1380 	struct vnode *rdvp = ddv->sdev_attrvp;
1381 	int rval = 0;
1382 
1383 	ASSERT(rdvp);
1384 
1385 	rval = VOP_LOOKUP(rdvp, nm, rvp, NULL, 0, NULL, kcred, NULL, NULL,
1386 	    NULL);
1387 	return (rval);
1388 }
1389 
1390 static int
1391 sdev_filldir_from_store(struct sdev_node *ddv, int dlen, struct cred *cred)
1392 {
1393 	struct sdev_node *dv = NULL;
1394 	char	*nm;
1395 	struct vnode *dirvp;
1396 	int	error;
1397 	vnode_t	*vp;
1398 	int eof;
1399 	struct iovec iov;
1400 	struct uio uio;
1401 	struct dirent64 *dp;
1402 	dirent64_t *dbuf;
1403 	size_t dbuflen;
1404 	struct vattr vattr;
1405 	char *link = NULL;
1406 
1407 	if (ddv->sdev_attrvp == NULL)
1408 		return (0);
1409 	if (!(ddv->sdev_flags & SDEV_BUILD))
1410 		return (0);
1411 
1412 	dirvp = ddv->sdev_attrvp;
1413 	VN_HOLD(dirvp);
1414 	dbuf = kmem_zalloc(dlen, KM_SLEEP);
1415 
1416 	uio.uio_iov = &iov;
1417 	uio.uio_iovcnt = 1;
1418 	uio.uio_segflg = UIO_SYSSPACE;
1419 	uio.uio_fmode = 0;
1420 	uio.uio_extflg = UIO_COPY_CACHED;
1421 	uio.uio_loffset = 0;
1422 	uio.uio_llimit = MAXOFFSET_T;
1423 
1424 	eof = 0;
1425 	error = 0;
1426 	while (!error && !eof) {
1427 		uio.uio_resid = dlen;
1428 		iov.iov_base = (char *)dbuf;
1429 		iov.iov_len = dlen;
1430 		(void) VOP_RWLOCK(dirvp, V_WRITELOCK_FALSE, NULL);
1431 		error = VOP_READDIR(dirvp, &uio, kcred, &eof, NULL, 0);
1432 		VOP_RWUNLOCK(dirvp, V_WRITELOCK_FALSE, NULL);
1433 
1434 		dbuflen = dlen - uio.uio_resid;
1435 		if (error || dbuflen == 0)
1436 			break;
1437 
1438 		if (!(ddv->sdev_flags & SDEV_BUILD))
1439 			break;
1440 
1441 		for (dp = dbuf; ((intptr_t)dp <
1442 		    (intptr_t)dbuf + dbuflen);
1443 		    dp = (dirent64_t *)((intptr_t)dp + dp->d_reclen)) {
1444 			nm = dp->d_name;
1445 
1446 			if (strcmp(nm, ".") == 0 ||
1447 			    strcmp(nm, "..") == 0)
1448 				continue;
1449 
1450 			vp = NULLVP;
1451 			dv = sdev_cache_lookup(ddv, nm);
1452 			if (dv) {
1453 				if (dv->sdev_state != SDEV_ZOMBIE) {
1454 					SDEV_SIMPLE_RELE(dv);
1455 				} else {
1456 					/*
1457 					 * A ZOMBIE node may not have been
1458 					 * cleaned up from the backing store,
1459 					 * bypass this entry in this case,
1460 					 * and clean it up from the directory
1461 					 * cache if this is the last call.
1462 					 */
1463 					(void) sdev_dirdelete(ddv, dv);
1464 				}
1465 				continue;
1466 			}
1467 
1468 			/* refill the cache if not already */
1469 			error = devname_backstore_lookup(ddv, nm, &vp);
1470 			if (error)
1471 				continue;
1472 
1473 			vattr.va_mask = AT_TYPE|AT_MODE|AT_UID|AT_GID;
1474 			error = VOP_GETATTR(vp, &vattr, 0, cred, NULL);
1475 			if (error)
1476 				continue;
1477 
1478 			if (vattr.va_type == VLNK) {
1479 				error = sdev_getlink(vp, &link);
1480 				if (error) {
1481 					continue;
1482 				}
1483 				ASSERT(link != NULL);
1484 			}
1485 
1486 			if (!rw_tryupgrade(&ddv->sdev_contents)) {
1487 				rw_exit(&ddv->sdev_contents);
1488 				rw_enter(&ddv->sdev_contents, RW_WRITER);
1489 			}
1490 			error = sdev_mknode(ddv, nm, &dv, &vattr, vp, link,
1491 			    cred, SDEV_READY);
1492 			rw_downgrade(&ddv->sdev_contents);
1493 
1494 			if (link != NULL) {
1495 				kmem_free(link, strlen(link) + 1);
1496 				link = NULL;
1497 			}
1498 
1499 			if (!error) {
1500 				ASSERT(dv);
1501 				ASSERT(dv->sdev_state != SDEV_ZOMBIE);
1502 				SDEV_SIMPLE_RELE(dv);
1503 			}
1504 			vp = NULL;
1505 			dv = NULL;
1506 		}
1507 	}
1508 
1509 done:
1510 	VN_RELE(dirvp);
1511 	kmem_free(dbuf, dlen);
1512 
1513 	return (error);
1514 }
1515 
1516 void
1517 sdev_filldir_dynamic(struct sdev_node *ddv)
1518 {
1519 	int error;
1520 	int i;
1521 	struct vattr vattr;
1522 	struct vattr *vap = &vattr;
1523 	char *nm = NULL;
1524 	struct sdev_node *dv = NULL;
1525 
1526 	ASSERT(RW_WRITE_HELD(&ddv->sdev_contents));
1527 	ASSERT((ddv->sdev_flags & SDEV_BUILD));
1528 
1529 	*vap = *sdev_getdefault_attr(VDIR);	/* note structure copy here */
1530 	gethrestime(&vap->va_atime);
1531 	vap->va_mtime = vap->va_atime;
1532 	vap->va_ctime = vap->va_atime;
1533 	for (i = 0; vtab[i].vt_name != NULL; i++) {
1534 		nm = vtab[i].vt_name;
1535 		ASSERT(RW_WRITE_HELD(&ddv->sdev_contents));
1536 		dv = NULL;
1537 		error = sdev_mknode(ddv, nm, &dv, vap, NULL,
1538 		    NULL, kcred, SDEV_READY);
1539 		if (error) {
1540 			cmn_err(CE_WARN, "%s/%s: error %d\n",
1541 			    ddv->sdev_name, nm, error);
1542 		} else {
1543 			ASSERT(dv);
1544 			ASSERT(dv->sdev_state != SDEV_ZOMBIE);
1545 			SDEV_SIMPLE_RELE(dv);
1546 		}
1547 	}
1548 }
1549 
1550 /*
1551  * Creating a backing store entry based on sdev_attr.
1552  * This is called either as part of node creation in a persistent directory
1553  * or from setattr/setsecattr to persist access attributes across reboot.
1554  */
1555 int
1556 sdev_shadow_node(struct sdev_node *dv, struct cred *cred)
1557 {
1558 	int error = 0;
1559 	struct vnode *dvp = SDEVTOV(dv->sdev_dotdot);
1560 	struct vnode *rdvp = VTOSDEV(dvp)->sdev_attrvp;
1561 	struct vattr *vap = dv->sdev_attr;
1562 	char *nm = dv->sdev_name;
1563 	struct vnode *tmpvp, **rvp = &tmpvp, *rrvp = NULL;
1564 
1565 	ASSERT(dv && dv->sdev_name && rdvp);
1566 	ASSERT(RW_WRITE_HELD(&dv->sdev_contents) && dv->sdev_attrvp == NULL);
1567 
1568 lookup:
1569 	/* try to find it in the backing store */
1570 	error = VOP_LOOKUP(rdvp, nm, rvp, NULL, 0, NULL, cred, NULL, NULL,
1571 	    NULL);
1572 	if (error == 0) {
1573 		if (VOP_REALVP(*rvp, &rrvp, NULL) == 0) {
1574 			VN_HOLD(rrvp);
1575 			VN_RELE(*rvp);
1576 			*rvp = rrvp;
1577 		}
1578 
1579 		kmem_free(dv->sdev_attr, sizeof (vattr_t));
1580 		dv->sdev_attr = NULL;
1581 		dv->sdev_attrvp = *rvp;
1582 		return (0);
1583 	}
1584 
1585 	/* let's try to persist the node */
1586 	gethrestime(&vap->va_atime);
1587 	vap->va_mtime = vap->va_atime;
1588 	vap->va_ctime = vap->va_atime;
1589 	vap->va_mask |= AT_TYPE|AT_MODE;
1590 	switch (vap->va_type) {
1591 	case VDIR:
1592 		error = VOP_MKDIR(rdvp, nm, vap, rvp, cred, NULL, 0, NULL);
1593 		sdcmn_err9(("sdev_shadow_node: mkdir vp %p error %d\n",
1594 		    (void *)(*rvp), error));
1595 		break;
1596 	case VCHR:
1597 	case VBLK:
1598 	case VREG:
1599 	case VDOOR:
1600 		error = VOP_CREATE(rdvp, nm, vap, NONEXCL, VREAD|VWRITE,
1601 		    rvp, cred, 0, NULL, NULL);
1602 		sdcmn_err9(("sdev_shadow_node: create vp %p, error %d\n",
1603 		    (void *)(*rvp), error));
1604 		if (!error)
1605 			VN_RELE(*rvp);
1606 		break;
1607 	case VLNK:
1608 		ASSERT(dv->sdev_symlink);
1609 		error = VOP_SYMLINK(rdvp, nm, vap, dv->sdev_symlink, cred,
1610 		    NULL, 0);
1611 		sdcmn_err9(("sdev_shadow_node: create symlink error %d\n",
1612 		    error));
1613 		break;
1614 	default:
1615 		cmn_err(CE_PANIC, "dev: %s: sdev_shadow_node "
1616 		    "create\n", nm);
1617 		/*NOTREACHED*/
1618 	}
1619 
1620 	/* go back to lookup to factor out spec node and set attrvp */
1621 	if (error == 0)
1622 		goto lookup;
1623 
1624 	sdcmn_err(("cannot persist %s - error %d\n", dv->sdev_path, error));
1625 	return (error);
1626 }
1627 
1628 static int
1629 sdev_cache_add(struct sdev_node *ddv, struct sdev_node **dv, char *nm)
1630 {
1631 	int error = 0;
1632 	struct sdev_node *dup = NULL;
1633 
1634 	ASSERT(RW_WRITE_HELD(&ddv->sdev_contents));
1635 	if ((dup = sdev_findbyname(ddv, nm)) == NULL) {
1636 		sdev_direnter(ddv, *dv);
1637 	} else {
1638 		if (dup->sdev_state == SDEV_ZOMBIE) {
1639 			error = sdev_dirdelete(ddv, dup);
1640 			/*
1641 			 * The ZOMBIE node is still hanging
1642 			 * around with more than one reference counts.
1643 			 * Fail the new node creation so that
1644 			 * the directory cache won't have
1645 			 * duplicate entries for the same named node
1646 			 */
1647 			if (error == EBUSY) {
1648 				SDEV_SIMPLE_RELE(*dv);
1649 				sdev_nodedestroy(*dv, 0);
1650 				*dv = NULL;
1651 				return (error);
1652 			}
1653 			sdev_direnter(ddv, *dv);
1654 		} else {
1655 			ASSERT((*dv)->sdev_state != SDEV_ZOMBIE);
1656 			SDEV_SIMPLE_RELE(*dv);
1657 			sdev_nodedestroy(*dv, 0);
1658 			*dv = dup;
1659 		}
1660 	}
1661 
1662 	return (0);
1663 }
1664 
1665 static int
1666 sdev_cache_delete(struct sdev_node *ddv, struct sdev_node **dv)
1667 {
1668 	ASSERT(RW_WRITE_HELD(&ddv->sdev_contents));
1669 	return (sdev_dirdelete(ddv, *dv));
1670 }
1671 
1672 /*
1673  * update the in-core directory cache
1674  */
1675 int
1676 sdev_cache_update(struct sdev_node *ddv, struct sdev_node **dv, char *nm,
1677     sdev_cache_ops_t ops)
1678 {
1679 	int error = 0;
1680 
1681 	ASSERT((SDEV_HELD(*dv)));
1682 
1683 	ASSERT(RW_WRITE_HELD(&ddv->sdev_contents));
1684 	switch (ops) {
1685 	case SDEV_CACHE_ADD:
1686 		error = sdev_cache_add(ddv, dv, nm);
1687 		break;
1688 	case SDEV_CACHE_DELETE:
1689 		error = sdev_cache_delete(ddv, dv);
1690 		break;
1691 	default:
1692 		break;
1693 	}
1694 
1695 	return (error);
1696 }
1697 
1698 /*
1699  * retrieve the named entry from the directory cache
1700  */
1701 struct sdev_node *
1702 sdev_cache_lookup(struct sdev_node *ddv, char *nm)
1703 {
1704 	struct sdev_node *dv = NULL;
1705 
1706 	ASSERT(RW_LOCK_HELD(&ddv->sdev_contents));
1707 	dv = sdev_findbyname(ddv, nm);
1708 
1709 	return (dv);
1710 }
1711 
1712 /*
1713  * Implicit reconfig for nodes constructed by a link generator
1714  * Start devfsadm if needed, or if devfsadm is in progress,
1715  * prepare to block on devfsadm either completing or
1716  * constructing the desired node.  As devfsadmd is global
1717  * in scope, constructing all necessary nodes, we only
1718  * need to initiate it once.
1719  */
1720 static int
1721 sdev_call_devfsadmd(struct sdev_node *ddv, struct sdev_node *dv, char *nm)
1722 {
1723 	int error = 0;
1724 
1725 	if (DEVNAME_DEVFSADM_IS_RUNNING(devfsadm_state)) {
1726 		sdcmn_err6(("lookup: waiting for %s/%s, 0x%x\n",
1727 		    ddv->sdev_name, nm, devfsadm_state));
1728 		mutex_enter(&dv->sdev_lookup_lock);
1729 		SDEV_BLOCK_OTHERS(dv, (SDEV_LOOKUP | SDEV_LGWAITING));
1730 		mutex_exit(&dv->sdev_lookup_lock);
1731 		error = 0;
1732 	} else if (!DEVNAME_DEVFSADM_HAS_RUN(devfsadm_state)) {
1733 		sdcmn_err6(("lookup %s/%s starting devfsadm, 0x%x\n",
1734 		    ddv->sdev_name, nm, devfsadm_state));
1735 
1736 		sdev_devfsadmd_thread(ddv, dv, kcred);
1737 		mutex_enter(&dv->sdev_lookup_lock);
1738 		SDEV_BLOCK_OTHERS(dv,
1739 		    (SDEV_LOOKUP | SDEV_LGWAITING));
1740 		mutex_exit(&dv->sdev_lookup_lock);
1741 		error = 0;
1742 	} else {
1743 		error = -1;
1744 	}
1745 
1746 	return (error);
1747 }
1748 
1749 /*
1750  *  Support for specialized device naming construction mechanisms
1751  */
1752 static int
1753 sdev_call_dircallback(struct sdev_node *ddv, struct sdev_node **dvp, char *nm,
1754     int (*callback)(struct sdev_node *, char *, void **, struct cred *,
1755     void *, char *), int flags, struct cred *cred)
1756 {
1757 	int rv = 0;
1758 	char *physpath = NULL;
1759 	struct vattr vattr;
1760 	struct vattr *vap = &vattr;
1761 	struct sdev_node *dv = NULL;
1762 
1763 	ASSERT(RW_WRITE_HELD(&ddv->sdev_contents));
1764 	if (flags & SDEV_VLINK) {
1765 		physpath = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
1766 		rv = callback(ddv, nm, (void *)&physpath, kcred, NULL,
1767 		    NULL);
1768 		if (rv) {
1769 			kmem_free(physpath, MAXPATHLEN);
1770 			return (-1);
1771 		}
1772 
1773 		*vap = *sdev_getdefault_attr(VLNK);	/* structure copy */
1774 		vap->va_size = strlen(physpath);
1775 		gethrestime(&vap->va_atime);
1776 		vap->va_mtime = vap->va_atime;
1777 		vap->va_ctime = vap->va_atime;
1778 
1779 		rv = sdev_mknode(ddv, nm, &dv, vap, NULL,
1780 		    (void *)physpath, cred, SDEV_READY);
1781 		kmem_free(physpath, MAXPATHLEN);
1782 		if (rv)
1783 			return (rv);
1784 	} else if (flags & SDEV_VATTR) {
1785 		/*
1786 		 * /dev/pts
1787 		 *
1788 		 * callback is responsible to set the basic attributes,
1789 		 * e.g. va_type/va_uid/va_gid/
1790 		 *    dev_t if VCHR or VBLK/
1791 		 */
1792 		ASSERT(callback);
1793 		rv = callback(ddv, nm, (void *)&vattr, kcred, NULL, NULL);
1794 		if (rv) {
1795 			sdcmn_err3(("devname_lookup_func: SDEV_NONE "
1796 			    "callback failed \n"));
1797 			return (-1);
1798 		}
1799 
1800 		rv = sdev_mknode(ddv, nm, &dv, &vattr, NULL, NULL,
1801 		    cred, SDEV_READY);
1802 
1803 		if (rv)
1804 			return (rv);
1805 
1806 	} else {
1807 		impossible(("lookup: %s/%s by %s not supported (%d)\n",
1808 		    SDEVTOV(ddv)->v_path, nm, curproc->p_user.u_comm,
1809 		    __LINE__));
1810 		rv = -1;
1811 	}
1812 
1813 	*dvp = dv;
1814 	return (rv);
1815 }
1816 
1817 static int
1818 is_devfsadm_thread(char *exec_name)
1819 {
1820 	/*
1821 	 * note: because devfsadmd -> /usr/sbin/devfsadm
1822 	 * it is safe to use "devfsadm" to capture the lookups
1823 	 * from devfsadm and its daemon version.
1824 	 */
1825 	if (strcmp(exec_name, "devfsadm") == 0)
1826 		return (1);
1827 	return (0);
1828 }
1829 
1830 /*
1831  * Lookup Order:
1832  *	sdev_node cache;
1833  *	backing store (SDEV_PERSIST);
1834  *	DBNR: a. dir_ops implemented in the loadable modules;
1835  *	      b. vnode ops in vtab.
1836  */
1837 int
1838 devname_lookup_func(struct sdev_node *ddv, char *nm, struct vnode **vpp,
1839     struct cred *cred, int (*callback)(struct sdev_node *, char *, void **,
1840     struct cred *, void *, char *), int flags)
1841 {
1842 	int rv = 0, nmlen;
1843 	struct vnode *rvp = NULL;
1844 	struct sdev_node *dv = NULL;
1845 	int	retried = 0;
1846 	int	error = 0;
1847 	struct vattr vattr;
1848 	char *lookup_thread = curproc->p_user.u_comm;
1849 	int failed_flags = 0;
1850 	int (*vtor)(struct sdev_node *) = NULL;
1851 	int state;
1852 	int parent_state;
1853 	char *link = NULL;
1854 
1855 	if (SDEVTOV(ddv)->v_type != VDIR)
1856 		return (ENOTDIR);
1857 
1858 	/*
1859 	 * Empty name or ., return node itself.
1860 	 */
1861 	nmlen = strlen(nm);
1862 	if ((nmlen == 0) || ((nmlen == 1) && (nm[0] == '.'))) {
1863 		*vpp = SDEVTOV(ddv);
1864 		VN_HOLD(*vpp);
1865 		return (0);
1866 	}
1867 
1868 	/*
1869 	 * .., return the parent directory
1870 	 */
1871 	if ((nmlen == 2) && (strcmp(nm, "..") == 0)) {
1872 		*vpp = SDEVTOV(ddv->sdev_dotdot);
1873 		VN_HOLD(*vpp);
1874 		return (0);
1875 	}
1876 
1877 	rw_enter(&ddv->sdev_contents, RW_READER);
1878 	if (ddv->sdev_flags & SDEV_VTOR) {
1879 		vtor = (int (*)(struct sdev_node *))sdev_get_vtor(ddv);
1880 		ASSERT(vtor);
1881 	}
1882 
1883 tryagain:
1884 	/*
1885 	 * (a) directory cache lookup:
1886 	 */
1887 	ASSERT(RW_READ_HELD(&ddv->sdev_contents));
1888 	parent_state = ddv->sdev_state;
1889 	dv = sdev_cache_lookup(ddv, nm);
1890 	if (dv) {
1891 		state = dv->sdev_state;
1892 		switch (state) {
1893 		case SDEV_INIT:
1894 			if (is_devfsadm_thread(lookup_thread))
1895 				break;
1896 
1897 			/* ZOMBIED parent won't allow node creation */
1898 			if (parent_state == SDEV_ZOMBIE) {
1899 				SD_TRACE_FAILED_LOOKUP(ddv, nm,
1900 				    retried);
1901 				goto nolock_notfound;
1902 			}
1903 
1904 			mutex_enter(&dv->sdev_lookup_lock);
1905 			/* compensate the threads started after devfsadm */
1906 			if (DEVNAME_DEVFSADM_IS_RUNNING(devfsadm_state) &&
1907 			    !(SDEV_IS_LOOKUP(dv)))
1908 				SDEV_BLOCK_OTHERS(dv,
1909 				    (SDEV_LOOKUP | SDEV_LGWAITING));
1910 
1911 			if (SDEV_IS_LOOKUP(dv)) {
1912 				failed_flags |= SLF_REBUILT;
1913 				rw_exit(&ddv->sdev_contents);
1914 				error = sdev_wait4lookup(dv, SDEV_LOOKUP);
1915 				mutex_exit(&dv->sdev_lookup_lock);
1916 				rw_enter(&ddv->sdev_contents, RW_READER);
1917 
1918 				if (error != 0) {
1919 					SD_TRACE_FAILED_LOOKUP(ddv, nm,
1920 					    retried);
1921 					goto nolock_notfound;
1922 				}
1923 
1924 				state = dv->sdev_state;
1925 				if (state == SDEV_INIT) {
1926 					SD_TRACE_FAILED_LOOKUP(ddv, nm,
1927 					    retried);
1928 					goto nolock_notfound;
1929 				} else if (state == SDEV_READY) {
1930 					goto found;
1931 				} else if (state == SDEV_ZOMBIE) {
1932 					rw_exit(&ddv->sdev_contents);
1933 					SD_TRACE_FAILED_LOOKUP(ddv, nm,
1934 					    retried);
1935 					SDEV_RELE(dv);
1936 					goto lookup_failed;
1937 				}
1938 			} else {
1939 				mutex_exit(&dv->sdev_lookup_lock);
1940 			}
1941 			break;
1942 		case SDEV_READY:
1943 			goto found;
1944 		case SDEV_ZOMBIE:
1945 			rw_exit(&ddv->sdev_contents);
1946 			SD_TRACE_FAILED_LOOKUP(ddv, nm, retried);
1947 			SDEV_RELE(dv);
1948 			goto lookup_failed;
1949 		default:
1950 			rw_exit(&ddv->sdev_contents);
1951 			SD_TRACE_FAILED_LOOKUP(ddv, nm, retried);
1952 			sdev_lookup_failed(ddv, nm, failed_flags);
1953 			*vpp = NULLVP;
1954 			return (ENOENT);
1955 		}
1956 	}
1957 	ASSERT(RW_READ_HELD(&ddv->sdev_contents));
1958 
1959 	/*
1960 	 * ZOMBIED parent does not allow new node creation.
1961 	 * bail out early
1962 	 */
1963 	if (parent_state == SDEV_ZOMBIE) {
1964 		rw_exit(&ddv->sdev_contents);
1965 		*vpp = NULLVP;
1966 		SD_TRACE_FAILED_LOOKUP(ddv, nm, retried);
1967 		return (ENOENT);
1968 	}
1969 
1970 	/*
1971 	 * (b0): backing store lookup
1972 	 *	SDEV_PERSIST is default except:
1973 	 *		1) pts nodes
1974 	 *		2) non-chmod'ed local nodes
1975 	 *		3) zvol nodes
1976 	 */
1977 	if (SDEV_IS_PERSIST(ddv)) {
1978 		error = devname_backstore_lookup(ddv, nm, &rvp);
1979 
1980 		if (!error) {
1981 
1982 			vattr.va_mask = AT_TYPE|AT_MODE|AT_UID|AT_GID;
1983 			error = VOP_GETATTR(rvp, &vattr, 0, cred, NULL);
1984 			if (error) {
1985 				rw_exit(&ddv->sdev_contents);
1986 				if (dv)
1987 					SDEV_RELE(dv);
1988 				SD_TRACE_FAILED_LOOKUP(ddv, nm, retried);
1989 				sdev_lookup_failed(ddv, nm, failed_flags);
1990 				*vpp = NULLVP;
1991 				return (ENOENT);
1992 			}
1993 
1994 			if (vattr.va_type == VLNK) {
1995 				error = sdev_getlink(rvp, &link);
1996 				if (error) {
1997 					rw_exit(&ddv->sdev_contents);
1998 					if (dv)
1999 						SDEV_RELE(dv);
2000 					SD_TRACE_FAILED_LOOKUP(ddv, nm,
2001 					    retried);
2002 					sdev_lookup_failed(ddv, nm,
2003 					    failed_flags);
2004 					*vpp = NULLVP;
2005 					return (ENOENT);
2006 				}
2007 				ASSERT(link != NULL);
2008 			}
2009 
2010 			if (!rw_tryupgrade(&ddv->sdev_contents)) {
2011 				rw_exit(&ddv->sdev_contents);
2012 				rw_enter(&ddv->sdev_contents, RW_WRITER);
2013 			}
2014 			error = sdev_mknode(ddv, nm, &dv, &vattr,
2015 			    rvp, link, cred, SDEV_READY);
2016 			rw_downgrade(&ddv->sdev_contents);
2017 
2018 			if (link != NULL) {
2019 				kmem_free(link, strlen(link) + 1);
2020 				link = NULL;
2021 			}
2022 
2023 			if (error) {
2024 				SD_TRACE_FAILED_LOOKUP(ddv, nm, retried);
2025 				rw_exit(&ddv->sdev_contents);
2026 				if (dv)
2027 					SDEV_RELE(dv);
2028 				goto lookup_failed;
2029 			} else {
2030 				goto found;
2031 			}
2032 		} else if (retried) {
2033 			rw_exit(&ddv->sdev_contents);
2034 			sdcmn_err3(("retry of lookup of %s/%s: failed\n",
2035 			    ddv->sdev_name, nm));
2036 			if (dv)
2037 				SDEV_RELE(dv);
2038 			SD_TRACE_FAILED_LOOKUP(ddv, nm, retried);
2039 			sdev_lookup_failed(ddv, nm, failed_flags);
2040 			*vpp = NULLVP;
2041 			return (ENOENT);
2042 		}
2043 	}
2044 
2045 lookup_create_node:
2046 	/* first thread that is doing the lookup on this node */
2047 	if (callback) {
2048 		ASSERT(dv == NULL);
2049 		if (!rw_tryupgrade(&ddv->sdev_contents)) {
2050 			rw_exit(&ddv->sdev_contents);
2051 			rw_enter(&ddv->sdev_contents, RW_WRITER);
2052 		}
2053 		error = sdev_call_dircallback(ddv, &dv, nm, callback,
2054 		    flags, cred);
2055 		rw_downgrade(&ddv->sdev_contents);
2056 		if (error == 0) {
2057 			goto found;
2058 		} else {
2059 			SD_TRACE_FAILED_LOOKUP(ddv, nm, retried);
2060 			rw_exit(&ddv->sdev_contents);
2061 			goto lookup_failed;
2062 		}
2063 	}
2064 	if (!dv) {
2065 		if (!rw_tryupgrade(&ddv->sdev_contents)) {
2066 			rw_exit(&ddv->sdev_contents);
2067 			rw_enter(&ddv->sdev_contents, RW_WRITER);
2068 		}
2069 		error = sdev_mknode(ddv, nm, &dv, NULL, NULL, NULL,
2070 		    cred, SDEV_INIT);
2071 		if (!dv) {
2072 			rw_exit(&ddv->sdev_contents);
2073 			SD_TRACE_FAILED_LOOKUP(ddv, nm, retried);
2074 			sdev_lookup_failed(ddv, nm, failed_flags);
2075 			*vpp = NULLVP;
2076 			return (ENOENT);
2077 		}
2078 		rw_downgrade(&ddv->sdev_contents);
2079 	}
2080 
2081 	/*
2082 	 * (b1) invoking devfsadm once per life time for devfsadm nodes
2083 	 */
2084 	ASSERT(SDEV_HELD(dv));
2085 
2086 	if (SDEV_IS_NO_NCACHE(dv))
2087 		failed_flags |= SLF_NO_NCACHE;
2088 	if (sdev_reconfig_boot || !i_ddi_io_initialized() ||
2089 	    SDEV_IS_DYNAMIC(ddv) || SDEV_IS_NO_NCACHE(dv) ||
2090 	    ((moddebug & MODDEBUG_FINI_EBUSY) != 0)) {
2091 		ASSERT(SDEV_HELD(dv));
2092 		SD_TRACE_FAILED_LOOKUP(ddv, nm, retried);
2093 		goto nolock_notfound;
2094 	}
2095 
2096 	/*
2097 	 * filter out known non-existent devices recorded
2098 	 * during initial reconfiguration boot for which
2099 	 * reconfig should not be done and lookup may
2100 	 * be short-circuited now.
2101 	 */
2102 	if (sdev_lookup_filter(ddv, nm)) {
2103 		SD_TRACE_FAILED_LOOKUP(ddv, nm, retried);
2104 		goto nolock_notfound;
2105 	}
2106 
2107 	/* bypassing devfsadm internal nodes */
2108 	if (is_devfsadm_thread(lookup_thread)) {
2109 		SD_TRACE_FAILED_LOOKUP(ddv, nm, retried);
2110 		goto nolock_notfound;
2111 	}
2112 
2113 	if (sdev_reconfig_disable) {
2114 		SD_TRACE_FAILED_LOOKUP(ddv, nm, retried);
2115 		goto nolock_notfound;
2116 	}
2117 
2118 	error = sdev_call_devfsadmd(ddv, dv, nm);
2119 	if (error == 0) {
2120 		sdcmn_err8(("lookup of %s/%s by %s: reconfig\n",
2121 		    ddv->sdev_name, nm, curproc->p_user.u_comm));
2122 		if (sdev_reconfig_verbose) {
2123 			cmn_err(CE_CONT,
2124 			    "?lookup of %s/%s by %s: reconfig\n",
2125 			    ddv->sdev_name, nm, curproc->p_user.u_comm);
2126 		}
2127 		retried = 1;
2128 		failed_flags |= SLF_REBUILT;
2129 		ASSERT(dv->sdev_state != SDEV_ZOMBIE);
2130 		SDEV_SIMPLE_RELE(dv);
2131 		goto tryagain;
2132 	} else {
2133 		SD_TRACE_FAILED_LOOKUP(ddv, nm, retried);
2134 		goto nolock_notfound;
2135 	}
2136 
2137 found:
2138 	ASSERT(!(dv->sdev_flags & SDEV_STALE));
2139 	ASSERT(dv->sdev_state == SDEV_READY);
2140 	if (vtor) {
2141 		/*
2142 		 * Check validity of returned node
2143 		 */
2144 		switch (vtor(dv)) {
2145 		case SDEV_VTOR_VALID:
2146 			break;
2147 		case SDEV_VTOR_STALE:
2148 			/*
2149 			 * The name exists, but the cache entry is
2150 			 * stale and needs to be re-created.
2151 			 */
2152 			ASSERT(RW_READ_HELD(&ddv->sdev_contents));
2153 			if (rw_tryupgrade(&ddv->sdev_contents) == 0) {
2154 				rw_exit(&ddv->sdev_contents);
2155 				rw_enter(&ddv->sdev_contents, RW_WRITER);
2156 			}
2157 			error = sdev_cache_update(ddv, &dv, nm,
2158 			    SDEV_CACHE_DELETE);
2159 			rw_downgrade(&ddv->sdev_contents);
2160 			if (error == 0) {
2161 				dv = NULL;
2162 				goto lookup_create_node;
2163 			}
2164 			/* FALLTHRU */
2165 		case SDEV_VTOR_INVALID:
2166 			SD_TRACE_FAILED_LOOKUP(ddv, nm, retried);
2167 			sdcmn_err7(("lookup: destroy invalid "
2168 			    "node: %s(%p)\n", dv->sdev_name, (void *)dv));
2169 			goto nolock_notfound;
2170 		case SDEV_VTOR_SKIP:
2171 			sdcmn_err7(("lookup: node not applicable - "
2172 			    "skipping: %s(%p)\n", dv->sdev_name, (void *)dv));
2173 			rw_exit(&ddv->sdev_contents);
2174 			SD_TRACE_FAILED_LOOKUP(ddv, nm, retried);
2175 			SDEV_RELE(dv);
2176 			goto lookup_failed;
2177 		default:
2178 			cmn_err(CE_PANIC,
2179 			    "dev fs: validator failed: %s(%p)\n",
2180 			    dv->sdev_name, (void *)dv);
2181 			break;
2182 		}
2183 	}
2184 
2185 	rw_exit(&ddv->sdev_contents);
2186 	rv = sdev_to_vp(dv, vpp);
2187 	sdcmn_err3(("devname_lookup_func: returning vp %p v_count %d state %d "
2188 	    "for nm %s, error %d\n", (void *)*vpp, (*vpp)->v_count,
2189 	    dv->sdev_state, nm, rv));
2190 	return (rv);
2191 
2192 nolock_notfound:
2193 	/*
2194 	 * Destroy the node that is created for synchronization purposes.
2195 	 */
2196 	sdcmn_err3(("devname_lookup_func: %s with state %d\n",
2197 	    nm, dv->sdev_state));
2198 	ASSERT(RW_READ_HELD(&ddv->sdev_contents));
2199 	if (dv->sdev_state == SDEV_INIT) {
2200 		if (!rw_tryupgrade(&ddv->sdev_contents)) {
2201 			rw_exit(&ddv->sdev_contents);
2202 			rw_enter(&ddv->sdev_contents, RW_WRITER);
2203 		}
2204 
2205 		/*
2206 		 * Node state may have changed during the lock
2207 		 * changes. Re-check.
2208 		 */
2209 		if (dv->sdev_state == SDEV_INIT) {
2210 			(void) sdev_dirdelete(ddv, dv);
2211 			rw_exit(&ddv->sdev_contents);
2212 			sdev_lookup_failed(ddv, nm, failed_flags);
2213 			*vpp = NULL;
2214 			return (ENOENT);
2215 		}
2216 	}
2217 
2218 	rw_exit(&ddv->sdev_contents);
2219 	SDEV_RELE(dv);
2220 
2221 lookup_failed:
2222 	sdev_lookup_failed(ddv, nm, failed_flags);
2223 	*vpp = NULL;
2224 	return (ENOENT);
2225 }
2226 
2227 /*
2228  * Given a directory node, mark all nodes beneath as
2229  * STALE, i.e. nodes that don't exist as far as new
2230  * consumers are concerned.  Remove them from the
2231  * list of directory entries so that no lookup or
2232  * directory traversal will find them.  The node
2233  * not deallocated so existing holds are not affected.
2234  */
2235 void
2236 sdev_stale(struct sdev_node *ddv)
2237 {
2238 	struct sdev_node *dv;
2239 	struct vnode *vp;
2240 
2241 	ASSERT(SDEVTOV(ddv)->v_type == VDIR);
2242 
2243 	rw_enter(&ddv->sdev_contents, RW_WRITER);
2244 	for (dv = SDEV_FIRST_ENTRY(ddv); dv; dv = SDEV_NEXT_ENTRY(ddv, dv)) {
2245 		vp = SDEVTOV(dv);
2246 		if (vp->v_type == VDIR)
2247 			sdev_stale(dv);
2248 
2249 		sdcmn_err9(("sdev_stale: setting stale %s\n",
2250 		    dv->sdev_path));
2251 		dv->sdev_flags |= SDEV_STALE;
2252 		avl_remove(&ddv->sdev_entries, dv);
2253 	}
2254 	ddv->sdev_flags |= SDEV_BUILD;
2255 	rw_exit(&ddv->sdev_contents);
2256 }
2257 
2258 /*
2259  * Given a directory node, clean out all the nodes beneath.
2260  * If expr is specified, clean node with names matching expr.
2261  * If SDEV_ENFORCE is specified in flags, busy nodes are made stale,
2262  *	so they are excluded from future lookups.
2263  */
2264 int
2265 sdev_cleandir(struct sdev_node *ddv, char *expr, uint_t flags)
2266 {
2267 	int error = 0;
2268 	int busy = 0;
2269 	struct vnode *vp;
2270 	struct sdev_node *dv, *next = NULL;
2271 	int bkstore = 0;
2272 	int len = 0;
2273 	char *bks_name = NULL;
2274 
2275 	ASSERT(SDEVTOV(ddv)->v_type == VDIR);
2276 
2277 	/*
2278 	 * We try our best to destroy all unused sdev_node's
2279 	 */
2280 	rw_enter(&ddv->sdev_contents, RW_WRITER);
2281 	for (dv = SDEV_FIRST_ENTRY(ddv); dv; dv = next) {
2282 		next = SDEV_NEXT_ENTRY(ddv, dv);
2283 		vp = SDEVTOV(dv);
2284 
2285 		if (expr && gmatch(dv->sdev_name, expr) == 0)
2286 			continue;
2287 
2288 		if (vp->v_type == VDIR &&
2289 		    sdev_cleandir(dv, NULL, flags) != 0) {
2290 			sdcmn_err9(("sdev_cleandir: dir %s busy\n",
2291 			    dv->sdev_name));
2292 			busy++;
2293 			continue;
2294 		}
2295 
2296 		if (vp->v_count > 0 && (flags & SDEV_ENFORCE) == 0) {
2297 			sdcmn_err9(("sdev_cleandir: dir %s busy\n",
2298 			    dv->sdev_name));
2299 			busy++;
2300 			continue;
2301 		}
2302 
2303 		/*
2304 		 * at this point, either dv is not held or SDEV_ENFORCE
2305 		 * is specified. In either case, dv needs to be deleted
2306 		 */
2307 		SDEV_HOLD(dv);
2308 
2309 		bkstore = SDEV_IS_PERSIST(dv) ? 1 : 0;
2310 		if (bkstore && (vp->v_type == VDIR))
2311 			bkstore += 1;
2312 
2313 		if (bkstore) {
2314 			len = strlen(dv->sdev_name) + 1;
2315 			bks_name = kmem_alloc(len, KM_SLEEP);
2316 			bcopy(dv->sdev_name, bks_name, len);
2317 		}
2318 
2319 		error = sdev_dirdelete(ddv, dv);
2320 
2321 		if (error == EBUSY) {
2322 			sdcmn_err9(("sdev_cleandir: dir busy\n"));
2323 			busy++;
2324 		}
2325 
2326 		/* take care the backing store clean up */
2327 		if (bkstore && (error == 0)) {
2328 			ASSERT(bks_name);
2329 			ASSERT(ddv->sdev_attrvp);
2330 
2331 			if (bkstore == 1) {
2332 				error = VOP_REMOVE(ddv->sdev_attrvp,
2333 				    bks_name, kcred, NULL, 0);
2334 			} else if (bkstore == 2) {
2335 				error = VOP_RMDIR(ddv->sdev_attrvp,
2336 				    bks_name, ddv->sdev_attrvp, kcred, NULL, 0);
2337 			}
2338 
2339 			/* do not propagate the backing store errors */
2340 			if (error) {
2341 				sdcmn_err9(("sdev_cleandir: backing store"
2342 				    "not cleaned\n"));
2343 				error = 0;
2344 			}
2345 
2346 			bkstore = 0;
2347 			kmem_free(bks_name, len);
2348 			bks_name = NULL;
2349 			len = 0;
2350 		}
2351 	}
2352 
2353 	ddv->sdev_flags |= SDEV_BUILD;
2354 	rw_exit(&ddv->sdev_contents);
2355 
2356 	if (busy) {
2357 		error = EBUSY;
2358 	}
2359 
2360 	return (error);
2361 }
2362 
2363 /*
2364  * a convenient wrapper for readdir() funcs
2365  */
2366 size_t
2367 add_dir_entry(dirent64_t *de, char *nm, size_t size, ino_t ino, offset_t off)
2368 {
2369 	size_t reclen = DIRENT64_RECLEN(strlen(nm));
2370 	if (reclen > size)
2371 		return (0);
2372 
2373 	de->d_ino = (ino64_t)ino;
2374 	de->d_off = (off64_t)off + 1;
2375 	de->d_reclen = (ushort_t)reclen;
2376 	(void) strncpy(de->d_name, nm, DIRENT64_NAMELEN(reclen));
2377 	return (reclen);
2378 }
2379 
2380 /*
2381  * sdev_mount service routines
2382  */
2383 int
2384 sdev_copyin_mountargs(struct mounta *uap, struct sdev_mountargs *args)
2385 {
2386 	int	error;
2387 
2388 	if (uap->datalen != sizeof (*args))
2389 		return (EINVAL);
2390 
2391 	if (error = copyin(uap->dataptr, args, sizeof (*args))) {
2392 		cmn_err(CE_WARN, "sdev_copyin_mountargs: can not"
2393 		    "get user data. error %d\n", error);
2394 		return (EFAULT);
2395 	}
2396 
2397 	return (0);
2398 }
2399 
2400 #ifdef nextdp
2401 #undef nextdp
2402 #endif
2403 #define	nextdp(dp)	((struct dirent64 *) \
2404 			    (intptr_t)((char *)(dp) + (dp)->d_reclen))
2405 
2406 /*
2407  * readdir helper func
2408  */
2409 int
2410 devname_readdir_func(vnode_t *vp, uio_t *uiop, cred_t *cred, int *eofp,
2411     int flags)
2412 {
2413 	struct sdev_node *ddv = VTOSDEV(vp);
2414 	struct sdev_node *dv;
2415 	dirent64_t	*dp;
2416 	ulong_t		outcount = 0;
2417 	size_t		namelen;
2418 	ulong_t		alloc_count;
2419 	void		*outbuf;
2420 	struct iovec	*iovp;
2421 	int		error = 0;
2422 	size_t		reclen;
2423 	offset_t	diroff;
2424 	offset_t	soff;
2425 	int		this_reclen;
2426 	int (*vtor)(struct sdev_node *) = NULL;
2427 	struct vattr attr;
2428 	timestruc_t now;
2429 
2430 	ASSERT(ddv->sdev_attr || ddv->sdev_attrvp);
2431 	ASSERT(RW_READ_HELD(&ddv->sdev_contents));
2432 
2433 	if (uiop->uio_loffset >= MAXOFF_T) {
2434 		if (eofp)
2435 			*eofp = 1;
2436 		return (0);
2437 	}
2438 
2439 	if (uiop->uio_iovcnt != 1)
2440 		return (EINVAL);
2441 
2442 	if (vp->v_type != VDIR)
2443 		return (ENOTDIR);
2444 
2445 	if (ddv->sdev_flags & SDEV_VTOR) {
2446 		vtor = (int (*)(struct sdev_node *))sdev_get_vtor(ddv);
2447 		ASSERT(vtor);
2448 	}
2449 
2450 	if (eofp != NULL)
2451 		*eofp = 0;
2452 
2453 	soff = uiop->uio_loffset;
2454 	iovp = uiop->uio_iov;
2455 	alloc_count = iovp->iov_len;
2456 	dp = outbuf = kmem_alloc(alloc_count, KM_SLEEP);
2457 	outcount = 0;
2458 
2459 	if (ddv->sdev_state == SDEV_ZOMBIE)
2460 		goto get_cache;
2461 
2462 	if (SDEV_IS_GLOBAL(ddv)) {
2463 
2464 		if ((sdev_boot_state == SDEV_BOOT_STATE_COMPLETE) &&
2465 		    !sdev_reconfig_boot && (flags & SDEV_BROWSE) &&
2466 		    !SDEV_IS_DYNAMIC(ddv) && !SDEV_IS_NO_NCACHE(ddv) &&
2467 		    ((moddebug & MODDEBUG_FINI_EBUSY) == 0) &&
2468 		    !DEVNAME_DEVFSADM_HAS_RUN(devfsadm_state) &&
2469 		    !DEVNAME_DEVFSADM_IS_RUNNING(devfsadm_state) &&
2470 		    !sdev_reconfig_disable) {
2471 			/*
2472 			 * invoking "devfsadm" to do system device reconfig
2473 			 */
2474 			mutex_enter(&ddv->sdev_lookup_lock);
2475 			SDEV_BLOCK_OTHERS(ddv,
2476 			    (SDEV_READDIR|SDEV_LGWAITING));
2477 			mutex_exit(&ddv->sdev_lookup_lock);
2478 
2479 			sdcmn_err8(("readdir of %s by %s: reconfig\n",
2480 			    ddv->sdev_path, curproc->p_user.u_comm));
2481 			if (sdev_reconfig_verbose) {
2482 				cmn_err(CE_CONT,
2483 				    "?readdir of %s by %s: reconfig\n",
2484 				    ddv->sdev_path, curproc->p_user.u_comm);
2485 			}
2486 
2487 			sdev_devfsadmd_thread(ddv, NULL, kcred);
2488 		} else if (DEVNAME_DEVFSADM_IS_RUNNING(devfsadm_state)) {
2489 			/*
2490 			 * compensate the "ls" started later than "devfsadm"
2491 			 */
2492 			mutex_enter(&ddv->sdev_lookup_lock);
2493 			SDEV_BLOCK_OTHERS(ddv, (SDEV_READDIR|SDEV_LGWAITING));
2494 			mutex_exit(&ddv->sdev_lookup_lock);
2495 		}
2496 
2497 		/*
2498 		 * release the contents lock so that
2499 		 * the cache may be updated by devfsadmd
2500 		 */
2501 		rw_exit(&ddv->sdev_contents);
2502 		mutex_enter(&ddv->sdev_lookup_lock);
2503 		if (SDEV_IS_READDIR(ddv))
2504 			(void) sdev_wait4lookup(ddv, SDEV_READDIR);
2505 		mutex_exit(&ddv->sdev_lookup_lock);
2506 		rw_enter(&ddv->sdev_contents, RW_READER);
2507 
2508 		sdcmn_err4(("readdir of directory %s by %s\n",
2509 		    ddv->sdev_name, curproc->p_user.u_comm));
2510 		if (ddv->sdev_flags & SDEV_BUILD) {
2511 			if (SDEV_IS_PERSIST(ddv)) {
2512 				error = sdev_filldir_from_store(ddv,
2513 				    alloc_count, cred);
2514 			}
2515 			ddv->sdev_flags &= ~SDEV_BUILD;
2516 		}
2517 	}
2518 
2519 get_cache:
2520 	/* handle "." and ".." */
2521 	diroff = 0;
2522 	if (soff == 0) {
2523 		/* first time */
2524 		this_reclen = DIRENT64_RECLEN(1);
2525 		if (alloc_count < this_reclen) {
2526 			error = EINVAL;
2527 			goto done;
2528 		}
2529 
2530 		dp->d_ino = (ino64_t)ddv->sdev_ino;
2531 		dp->d_off = (off64_t)1;
2532 		dp->d_reclen = (ushort_t)this_reclen;
2533 
2534 		(void) strncpy(dp->d_name, ".",
2535 		    DIRENT64_NAMELEN(this_reclen));
2536 		outcount += dp->d_reclen;
2537 		dp = nextdp(dp);
2538 	}
2539 
2540 	diroff++;
2541 	if (soff <= 1) {
2542 		this_reclen = DIRENT64_RECLEN(2);
2543 		if (alloc_count < outcount + this_reclen) {
2544 			error = EINVAL;
2545 			goto done;
2546 		}
2547 
2548 		dp->d_reclen = (ushort_t)this_reclen;
2549 		dp->d_ino = (ino64_t)ddv->sdev_dotdot->sdev_ino;
2550 		dp->d_off = (off64_t)2;
2551 
2552 		(void) strncpy(dp->d_name, "..",
2553 		    DIRENT64_NAMELEN(this_reclen));
2554 		outcount += dp->d_reclen;
2555 
2556 		dp = nextdp(dp);
2557 	}
2558 
2559 
2560 	/* gets the cache */
2561 	diroff++;
2562 	for (dv = SDEV_FIRST_ENTRY(ddv); dv;
2563 	    dv = SDEV_NEXT_ENTRY(ddv, dv), diroff++) {
2564 		sdcmn_err3(("sdev_readdir: diroff %lld soff %lld for '%s' \n",
2565 		    diroff, soff, dv->sdev_name));
2566 
2567 		/* bypassing pre-matured nodes */
2568 		if (diroff < soff || (dv->sdev_state != SDEV_READY)) {
2569 			sdcmn_err3(("sdev_readdir: pre-mature node  "
2570 			    "%s %d\n", dv->sdev_name, dv->sdev_state));
2571 			continue;
2572 		}
2573 
2574 		/*
2575 		 * Check validity of node
2576 		 */
2577 		if (vtor) {
2578 			switch (vtor(dv)) {
2579 			case SDEV_VTOR_VALID:
2580 				break;
2581 			case SDEV_VTOR_INVALID:
2582 			case SDEV_VTOR_SKIP:
2583 				continue;
2584 			default:
2585 				cmn_err(CE_PANIC,
2586 				    "dev fs: validator failed: %s(%p)\n",
2587 				    dv->sdev_name, (void *)dv);
2588 				break;
2589 			/*NOTREACHED*/
2590 			}
2591 		}
2592 
2593 		namelen = strlen(dv->sdev_name);
2594 		reclen = DIRENT64_RECLEN(namelen);
2595 		if (outcount + reclen > alloc_count) {
2596 			goto full;
2597 		}
2598 		dp->d_reclen = (ushort_t)reclen;
2599 		dp->d_ino = (ino64_t)dv->sdev_ino;
2600 		dp->d_off = (off64_t)diroff + 1;
2601 		(void) strncpy(dp->d_name, dv->sdev_name,
2602 		    DIRENT64_NAMELEN(reclen));
2603 		outcount += reclen;
2604 		dp = nextdp(dp);
2605 	}
2606 
2607 full:
2608 	sdcmn_err4(("sdev_readdir: moving %lu bytes: "
2609 	    "diroff %lld, soff %lld, dv %p\n", outcount, diroff, soff,
2610 	    (void *)dv));
2611 
2612 	if (outcount)
2613 		error = uiomove(outbuf, outcount, UIO_READ, uiop);
2614 
2615 	if (!error) {
2616 		uiop->uio_loffset = diroff;
2617 		if (eofp)
2618 			*eofp = dv ? 0 : 1;
2619 	}
2620 
2621 
2622 	if (ddv->sdev_attrvp) {
2623 		gethrestime(&now);
2624 		attr.va_ctime = now;
2625 		attr.va_atime = now;
2626 		attr.va_mask = AT_CTIME|AT_ATIME;
2627 
2628 		(void) VOP_SETATTR(ddv->sdev_attrvp, &attr, 0, kcred, NULL);
2629 	}
2630 done:
2631 	kmem_free(outbuf, alloc_count);
2632 	return (error);
2633 }
2634 
2635 static int
2636 sdev_modctl_lookup(const char *path, vnode_t **r_vp)
2637 {
2638 	vnode_t *vp;
2639 	vnode_t *cvp;
2640 	struct sdev_node *svp;
2641 	char *nm;
2642 	struct pathname pn;
2643 	int error;
2644 	int persisted = 0;
2645 
2646 	ASSERT(INGLOBALZONE(curproc));
2647 
2648 	if (error = pn_get((char *)path, UIO_SYSSPACE, &pn))
2649 		return (error);
2650 	nm = kmem_alloc(MAXNAMELEN, KM_SLEEP);
2651 
2652 	vp = rootdir;
2653 	VN_HOLD(vp);
2654 
2655 	while (pn_pathleft(&pn)) {
2656 		ASSERT(vp->v_type == VDIR || vp->v_type == VLNK);
2657 		(void) pn_getcomponent(&pn, nm);
2658 
2659 		/*
2660 		 * Deal with the .. special case where we may be
2661 		 * traversing up across a mount point, to the
2662 		 * root of this filesystem or global root.
2663 		 */
2664 		if (nm[0] == '.' && nm[1] == '.' && nm[2] == 0) {
2665 checkforroot:
2666 			if (VN_CMP(vp, rootdir)) {
2667 				nm[1] = 0;
2668 			} else if (vp->v_flag & VROOT) {
2669 				vfs_t *vfsp;
2670 				cvp = vp;
2671 				vfsp = cvp->v_vfsp;
2672 				vfs_rlock_wait(vfsp);
2673 				vp = cvp->v_vfsp->vfs_vnodecovered;
2674 				if (vp == NULL ||
2675 				    (cvp->v_vfsp->vfs_flag & VFS_UNMOUNTED)) {
2676 					vfs_unlock(vfsp);
2677 					VN_RELE(cvp);
2678 					error = EIO;
2679 					break;
2680 				}
2681 				VN_HOLD(vp);
2682 				vfs_unlock(vfsp);
2683 				VN_RELE(cvp);
2684 				cvp = NULL;
2685 				goto checkforroot;
2686 			}
2687 		}
2688 
2689 		error = VOP_LOOKUP(vp, nm, &cvp, NULL, 0, NULL, kcred, NULL,
2690 		    NULL, NULL);
2691 		if (error) {
2692 			VN_RELE(vp);
2693 			break;
2694 		}
2695 
2696 		/* traverse mount points encountered on our journey */
2697 		if (vn_ismntpt(cvp) && (error = traverse(&cvp)) != 0) {
2698 			VN_RELE(vp);
2699 			VN_RELE(cvp);
2700 			break;
2701 		}
2702 
2703 		/*
2704 		 * symbolic link, can be either relative and absolute
2705 		 */
2706 		if ((cvp->v_type == VLNK) && pn_pathleft(&pn)) {
2707 			struct pathname linkpath;
2708 			pn_alloc(&linkpath);
2709 			if (error = pn_getsymlink(cvp, &linkpath, kcred)) {
2710 				pn_free(&linkpath);
2711 				break;
2712 			}
2713 			if (pn_pathleft(&linkpath) == 0)
2714 				(void) pn_set(&linkpath, ".");
2715 			error = pn_insert(&pn, &linkpath, strlen(nm));
2716 			pn_free(&linkpath);
2717 			if (pn.pn_pathlen == 0) {
2718 				VN_RELE(vp);
2719 				return (ENOENT);
2720 			}
2721 			if (pn.pn_path[0] == '/') {
2722 				pn_skipslash(&pn);
2723 				VN_RELE(vp);
2724 				VN_RELE(cvp);
2725 				vp = rootdir;
2726 				VN_HOLD(vp);
2727 			} else {
2728 				VN_RELE(cvp);
2729 			}
2730 			continue;
2731 		}
2732 
2733 		VN_RELE(vp);
2734 
2735 		/*
2736 		 * Direct the operation to the persisting filesystem
2737 		 * underlying /dev.  Bail if we encounter a
2738 		 * non-persistent dev entity here.
2739 		 */
2740 		if (cvp->v_vfsp->vfs_fstype == devtype) {
2741 
2742 			if ((VTOSDEV(cvp)->sdev_flags & SDEV_PERSIST) == 0) {
2743 				error = ENOENT;
2744 				VN_RELE(cvp);
2745 				break;
2746 			}
2747 
2748 			if (VTOSDEV(cvp) == NULL) {
2749 				error = ENOENT;
2750 				VN_RELE(cvp);
2751 				break;
2752 			}
2753 			svp = VTOSDEV(cvp);
2754 			if ((vp = svp->sdev_attrvp) == NULL) {
2755 				error = ENOENT;
2756 				VN_RELE(cvp);
2757 				break;
2758 			}
2759 			persisted = 1;
2760 			VN_HOLD(vp);
2761 			VN_RELE(cvp);
2762 			cvp = vp;
2763 		}
2764 
2765 		vp = cvp;
2766 		pn_skipslash(&pn);
2767 	}
2768 
2769 	kmem_free(nm, MAXNAMELEN);
2770 	pn_free(&pn);
2771 
2772 	if (error)
2773 		return (error);
2774 
2775 	/*
2776 	 * Only return persisted nodes in the filesystem underlying /dev.
2777 	 */
2778 	if (!persisted) {
2779 		VN_RELE(vp);
2780 		return (ENOENT);
2781 	}
2782 
2783 	*r_vp = vp;
2784 	return (0);
2785 }
2786 
2787 int
2788 sdev_modctl_readdir(const char *dir, char ***dirlistp,
2789 	int *npathsp, int *npathsp_alloc, int checking_empty)
2790 {
2791 	char	**pathlist = NULL;
2792 	char	**newlist = NULL;
2793 	int	npaths = 0;
2794 	int	npaths_alloc = 0;
2795 	dirent64_t *dbuf = NULL;
2796 	int	n;
2797 	char	*s;
2798 	int error;
2799 	vnode_t *vp;
2800 	int eof;
2801 	struct iovec iov;
2802 	struct uio uio;
2803 	struct dirent64 *dp;
2804 	size_t dlen;
2805 	size_t dbuflen;
2806 	int ndirents = 64;
2807 	char *nm;
2808 
2809 	error = sdev_modctl_lookup(dir, &vp);
2810 	sdcmn_err11(("modctl readdir: %s by %s: %s\n",
2811 	    dir, curproc->p_user.u_comm,
2812 	    (error == 0) ? "ok" : "failed"));
2813 	if (error)
2814 		return (error);
2815 
2816 	dlen = ndirents * (sizeof (*dbuf));
2817 	dbuf = kmem_alloc(dlen, KM_SLEEP);
2818 
2819 	uio.uio_iov = &iov;
2820 	uio.uio_iovcnt = 1;
2821 	uio.uio_segflg = UIO_SYSSPACE;
2822 	uio.uio_fmode = 0;
2823 	uio.uio_extflg = UIO_COPY_CACHED;
2824 	uio.uio_loffset = 0;
2825 	uio.uio_llimit = MAXOFFSET_T;
2826 
2827 	eof = 0;
2828 	error = 0;
2829 	while (!error && !eof) {
2830 		uio.uio_resid = dlen;
2831 		iov.iov_base = (char *)dbuf;
2832 		iov.iov_len = dlen;
2833 
2834 		(void) VOP_RWLOCK(vp, V_WRITELOCK_FALSE, NULL);
2835 		error = VOP_READDIR(vp, &uio, kcred, &eof, NULL, 0);
2836 		VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
2837 
2838 		dbuflen = dlen - uio.uio_resid;
2839 
2840 		if (error || dbuflen == 0)
2841 			break;
2842 
2843 		for (dp = dbuf; ((intptr_t)dp < (intptr_t)dbuf + dbuflen);
2844 		    dp = (dirent64_t *)((intptr_t)dp + dp->d_reclen)) {
2845 
2846 			nm = dp->d_name;
2847 
2848 			if (strcmp(nm, ".") == 0 || strcmp(nm, "..") == 0)
2849 				continue;
2850 			if (npaths == npaths_alloc) {
2851 				npaths_alloc += 64;
2852 				newlist = (char **)
2853 				    kmem_zalloc((npaths_alloc + 1) *
2854 				    sizeof (char *), KM_SLEEP);
2855 				if (pathlist) {
2856 					bcopy(pathlist, newlist,
2857 					    npaths * sizeof (char *));
2858 					kmem_free(pathlist,
2859 					    (npaths + 1) * sizeof (char *));
2860 				}
2861 				pathlist = newlist;
2862 			}
2863 			n = strlen(nm) + 1;
2864 			s = kmem_alloc(n, KM_SLEEP);
2865 			bcopy(nm, s, n);
2866 			pathlist[npaths++] = s;
2867 			sdcmn_err11(("  %s/%s\n", dir, s));
2868 
2869 			/* if checking empty, one entry is as good as many */
2870 			if (checking_empty) {
2871 				eof = 1;
2872 				break;
2873 			}
2874 		}
2875 	}
2876 
2877 exit:
2878 	VN_RELE(vp);
2879 
2880 	if (dbuf)
2881 		kmem_free(dbuf, dlen);
2882 
2883 	if (error)
2884 		return (error);
2885 
2886 	*dirlistp = pathlist;
2887 	*npathsp = npaths;
2888 	*npathsp_alloc = npaths_alloc;
2889 
2890 	return (0);
2891 }
2892 
2893 void
2894 sdev_modctl_readdir_free(char **pathlist, int npaths, int npaths_alloc)
2895 {
2896 	int	i, n;
2897 
2898 	for (i = 0; i < npaths; i++) {
2899 		n = strlen(pathlist[i]) + 1;
2900 		kmem_free(pathlist[i], n);
2901 	}
2902 
2903 	kmem_free(pathlist, (npaths_alloc + 1) * sizeof (char *));
2904 }
2905 
2906 int
2907 sdev_modctl_devexists(const char *path)
2908 {
2909 	vnode_t *vp;
2910 	int error;
2911 
2912 	error = sdev_modctl_lookup(path, &vp);
2913 	sdcmn_err11(("modctl dev exists: %s by %s: %s\n",
2914 	    path, curproc->p_user.u_comm,
2915 	    (error == 0) ? "ok" : "failed"));
2916 	if (error == 0)
2917 		VN_RELE(vp);
2918 
2919 	return (error);
2920 }
2921 
2922 extern int sdev_vnodeops_tbl_size;
2923 
2924 /*
2925  * construct a new template with overrides from vtab
2926  */
2927 static fs_operation_def_t *
2928 sdev_merge_vtab(const fs_operation_def_t tab[])
2929 {
2930 	fs_operation_def_t *new;
2931 	const fs_operation_def_t *tab_entry;
2932 
2933 	/* make a copy of standard vnode ops table */
2934 	new = kmem_alloc(sdev_vnodeops_tbl_size, KM_SLEEP);
2935 	bcopy((void *)sdev_vnodeops_tbl, new, sdev_vnodeops_tbl_size);
2936 
2937 	/* replace the overrides from tab */
2938 	for (tab_entry = tab; tab_entry->name != NULL; tab_entry++) {
2939 		fs_operation_def_t *std_entry = new;
2940 		while (std_entry->name) {
2941 			if (strcmp(tab_entry->name, std_entry->name) == 0) {
2942 				std_entry->func = tab_entry->func;
2943 				break;
2944 			}
2945 			std_entry++;
2946 		}
2947 		if (std_entry->name == NULL)
2948 			cmn_err(CE_NOTE, "sdev_merge_vtab: entry %s unused.",
2949 			    tab_entry->name);
2950 	}
2951 
2952 	return (new);
2953 }
2954 
2955 /* free memory allocated by sdev_merge_vtab */
2956 static void
2957 sdev_free_vtab(fs_operation_def_t *new)
2958 {
2959 	kmem_free(new, sdev_vnodeops_tbl_size);
2960 }
2961 
2962 /*
2963  * a generic setattr() function
2964  *
2965  * note: flags only supports AT_UID and AT_GID.
2966  *	 Future enhancements can be done for other types, e.g. AT_MODE
2967  */
2968 int
2969 devname_setattr_func(struct vnode *vp, struct vattr *vap, int flags,
2970     struct cred *cred, int (*callback)(struct sdev_node *, struct vattr *,
2971     int), int protocol)
2972 {
2973 	struct sdev_node	*dv = VTOSDEV(vp);
2974 	struct sdev_node	*parent = dv->sdev_dotdot;
2975 	struct vattr		*get;
2976 	uint_t			mask = vap->va_mask;
2977 	int 			error;
2978 
2979 	/* some sanity checks */
2980 	if (vap->va_mask & AT_NOSET)
2981 		return (EINVAL);
2982 
2983 	if (vap->va_mask & AT_SIZE) {
2984 		if (vp->v_type == VDIR) {
2985 			return (EISDIR);
2986 		}
2987 	}
2988 
2989 	/* no need to set attribute, but do not fail either */
2990 	ASSERT(parent);
2991 	rw_enter(&parent->sdev_contents, RW_READER);
2992 	if (dv->sdev_state == SDEV_ZOMBIE) {
2993 		rw_exit(&parent->sdev_contents);
2994 		return (0);
2995 	}
2996 
2997 	/* If backing store exists, just set it. */
2998 	if (dv->sdev_attrvp) {
2999 		rw_exit(&parent->sdev_contents);
3000 		return (VOP_SETATTR(dv->sdev_attrvp, vap, flags, cred, NULL));
3001 	}
3002 
3003 	/*
3004 	 * Otherwise, for nodes with the persistence attribute, create it.
3005 	 */
3006 	ASSERT(dv->sdev_attr);
3007 	if (SDEV_IS_PERSIST(dv) ||
3008 	    ((vap->va_mask & ~AT_TIMES) != 0 && !SDEV_IS_DYNAMIC(dv))) {
3009 		sdev_vattr_merge(dv, vap);
3010 		rw_enter(&dv->sdev_contents, RW_WRITER);
3011 		error = sdev_shadow_node(dv, cred);
3012 		rw_exit(&dv->sdev_contents);
3013 		rw_exit(&parent->sdev_contents);
3014 
3015 		if (error)
3016 			return (error);
3017 		return (VOP_SETATTR(dv->sdev_attrvp, vap, flags, cred, NULL));
3018 	}
3019 
3020 
3021 	/*
3022 	 * sdev_attr was allocated in sdev_mknode
3023 	 */
3024 	rw_enter(&dv->sdev_contents, RW_WRITER);
3025 	error = secpolicy_vnode_setattr(cred, vp, vap,
3026 	    dv->sdev_attr, flags, sdev_unlocked_access, dv);
3027 	if (error) {
3028 		rw_exit(&dv->sdev_contents);
3029 		rw_exit(&parent->sdev_contents);
3030 		return (error);
3031 	}
3032 
3033 	get = dv->sdev_attr;
3034 	if (mask & AT_MODE) {
3035 		get->va_mode &= S_IFMT;
3036 		get->va_mode |= vap->va_mode & ~S_IFMT;
3037 	}
3038 
3039 	if ((mask & AT_UID) || (mask & AT_GID)) {
3040 		if (mask & AT_UID)
3041 			get->va_uid = vap->va_uid;
3042 		if (mask & AT_GID)
3043 			get->va_gid = vap->va_gid;
3044 		/*
3045 		 * a callback must be provided if the protocol is set
3046 		 */
3047 		if ((protocol & AT_UID) || (protocol & AT_GID)) {
3048 			ASSERT(callback);
3049 			error = callback(dv, get, protocol);
3050 			if (error) {
3051 				rw_exit(&dv->sdev_contents);
3052 				rw_exit(&parent->sdev_contents);
3053 				return (error);
3054 			}
3055 		}
3056 	}
3057 
3058 	if (mask & AT_ATIME)
3059 		get->va_atime = vap->va_atime;
3060 	if (mask & AT_MTIME)
3061 		get->va_mtime = vap->va_mtime;
3062 	if (mask & (AT_MODE | AT_UID | AT_GID | AT_CTIME)) {
3063 		gethrestime(&get->va_ctime);
3064 	}
3065 
3066 	sdev_vattr_merge(dv, get);
3067 	rw_exit(&dv->sdev_contents);
3068 	rw_exit(&parent->sdev_contents);
3069 	return (0);
3070 }
3071 
3072 /*
3073  * a generic inactive() function
3074  */
3075 /*ARGSUSED*/
3076 void
3077 devname_inactive_func(struct vnode *vp, struct cred *cred,
3078     void (*callback)(struct vnode *))
3079 {
3080 	int clean;
3081 	struct sdev_node *dv = VTOSDEV(vp);
3082 	struct sdev_node *ddv = dv->sdev_dotdot;
3083 	int state;
3084 
3085 	rw_enter(&ddv->sdev_contents, RW_WRITER);
3086 	state = dv->sdev_state;
3087 
3088 	mutex_enter(&vp->v_lock);
3089 	ASSERT(vp->v_count >= 1);
3090 
3091 	if (vp->v_count == 1 && callback != NULL)
3092 		callback(vp);
3093 
3094 	clean = (vp->v_count == 1) && (state == SDEV_ZOMBIE);
3095 
3096 	/*
3097 	 * last ref count on the ZOMBIE node is released.
3098 	 * clean up the sdev_node, and
3099 	 * release the hold on the backing store node so that
3100 	 * the ZOMBIE backing stores also cleaned out.
3101 	 */
3102 	if (clean) {
3103 		ASSERT(ddv);
3104 
3105 		ddv->sdev_nlink--;
3106 		if (vp->v_type == VDIR) {
3107 			dv->sdev_nlink--;
3108 		}
3109 		if ((dv->sdev_flags & SDEV_STALE) == 0)
3110 			avl_remove(&ddv->sdev_entries, dv);
3111 		dv->sdev_nlink--;
3112 		--vp->v_count;
3113 		mutex_exit(&vp->v_lock);
3114 		sdev_nodedestroy(dv, 0);
3115 	} else {
3116 		--vp->v_count;
3117 		mutex_exit(&vp->v_lock);
3118 	}
3119 	rw_exit(&ddv->sdev_contents);
3120 }
3121