xref: /illumos-gate/usr/src/uts/common/fs/autofs/auto_vnops.c (revision 0dee7919e2f2a6479d16b370af93747b9416b242)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/errno.h>
32 #include <sys/proc.h>
33 #include <sys/vnode.h>
34 #include <sys/vfs.h>
35 #include <sys/uio.h>
36 #include <sys/cred.h>
37 #include <sys/pathname.h>
38 #include <sys/dirent.h>
39 #include <sys/debug.h>
40 #include <sys/sysmacros.h>
41 #include <sys/tiuser.h>
42 #include <sys/cmn_err.h>
43 #include <sys/stat.h>
44 #include <sys/mode.h>
45 #include <sys/policy.h>
46 #include <rpc/types.h>
47 #include <rpc/auth.h>
48 #include <rpc/clnt.h>
49 #include <sys/fs/autofs.h>
50 #include <rpcsvc/autofs_prot.h>
51 #include <fs/fs_subr.h>
52 
53 /*
54  *  Vnode ops for autofs
55  */
56 static int auto_open(vnode_t **, int, cred_t *);
57 static int auto_close(vnode_t *, int, int, offset_t, cred_t *);
58 static int auto_getattr(vnode_t *, vattr_t *, int, cred_t *);
59 static int auto_setattr(vnode_t *, vattr_t *, int, cred_t *,
60 	caller_context_t *);
61 static int auto_access(vnode_t *, int, int, cred_t *);
62 static int auto_lookup(vnode_t *, char *, vnode_t **,
63 	pathname_t *, int, vnode_t *, cred_t *);
64 static int auto_create(vnode_t *, char *, vattr_t *, vcexcl_t,
65 	int, vnode_t **, cred_t *, int);
66 static int auto_remove(vnode_t *, char *, cred_t *);
67 static int auto_link(vnode_t *, vnode_t *, char *, cred_t *);
68 static int auto_rename(vnode_t *, char *, vnode_t *, char *, cred_t *);
69 static int auto_mkdir(vnode_t *, char *, vattr_t *, vnode_t **, cred_t *);
70 static int auto_rmdir(vnode_t *, char *, vnode_t *, cred_t *);
71 static int auto_readdir(vnode_t *, uio_t *, cred_t *, int *);
72 static int auto_symlink(vnode_t *, char *, vattr_t *, char *, cred_t *);
73 static int auto_readlink(vnode_t *, struct uio *, cred_t *);
74 static int auto_fsync(vnode_t *, int, cred_t *);
75 static void auto_inactive(vnode_t *, cred_t *);
76 static int auto_rwlock(vnode_t *, int, caller_context_t *);
77 static void auto_rwunlock(vnode_t *vp, int, caller_context_t *);
78 static int auto_seek(vnode_t *vp, offset_t, offset_t *);
79 
80 static int auto_trigger_mount(vnode_t *, cred_t *, vnode_t **);
81 
82 vnodeops_t *auto_vnodeops;
83 
84 const fs_operation_def_t auto_vnodeops_template[] = {
85 	VOPNAME_OPEN, auto_open,
86 	VOPNAME_CLOSE, auto_close,
87 	VOPNAME_GETATTR, auto_getattr,
88 	VOPNAME_SETATTR, auto_setattr,
89 	VOPNAME_ACCESS, auto_access,
90 	VOPNAME_LOOKUP, auto_lookup,
91 	VOPNAME_CREATE, auto_create,
92 	VOPNAME_REMOVE, auto_remove,
93 	VOPNAME_LINK, auto_link,
94 	VOPNAME_RENAME, auto_rename,
95 	VOPNAME_MKDIR, auto_mkdir,
96 	VOPNAME_RMDIR, auto_rmdir,
97 	VOPNAME_READDIR, auto_readdir,
98 	VOPNAME_SYMLINK, auto_symlink,
99 	VOPNAME_READLINK, auto_readlink,
100 	VOPNAME_FSYNC, auto_fsync,
101 	VOPNAME_INACTIVE, (fs_generic_func_p) auto_inactive,
102 	VOPNAME_RWLOCK, auto_rwlock,
103 	VOPNAME_RWUNLOCK, (fs_generic_func_p) auto_rwunlock,
104 	VOPNAME_SEEK, auto_seek,
105 	VOPNAME_FRLOCK, fs_error,
106 	VOPNAME_DISPOSE, fs_error,
107 	VOPNAME_SHRLOCK, fs_error,
108 	NULL, NULL
109 };
110 
111 /* ARGSUSED */
112 static int
113 auto_open(vnode_t **vpp, int flag, cred_t *cred)
114 {
115 	vnode_t *newvp;
116 	int error;
117 
118 	AUTOFS_DPRINT((4, "auto_open: *vpp=%p\n", (void *)*vpp));
119 
120 	error = auto_trigger_mount(*vpp, cred, &newvp);
121 	if (error)
122 		goto done;
123 
124 	if (newvp != NULL) {
125 		/*
126 		 * Node is now mounted on.
127 		 */
128 		VN_RELE(*vpp);
129 		*vpp = newvp;
130 		error = VOP_ACCESS(*vpp, VREAD, 0, cred);
131 		if (!error)
132 			error = VOP_OPEN(vpp, flag, cred);
133 	}
134 
135 done:
136 	AUTOFS_DPRINT((5, "auto_open: *vpp=%p error=%d\n", (void *)*vpp,
137 	    error));
138 	return (error);
139 }
140 
141 /* ARGSUSED */
142 static int
143 auto_close(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cred)
144 {
145 	return (0);
146 }
147 
148 static int
149 auto_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cred)
150 {
151 	fnnode_t *fnp = vntofn(vp);
152 	vnode_t *newvp;
153 	vfs_t *vfsp;
154 	int error;
155 
156 	AUTOFS_DPRINT((4, "auto_getattr vp %p\n", (void *)vp));
157 
158 	/*
159 	 * Recursive auto_getattr/mount; go to the vfsp == NULL
160 	 * case.
161 	 */
162 	if (vn_vfswlock_held(vp))
163 		goto defattr;
164 
165 	if (error = vn_vfswlock_wait(vp))
166 		return (error);
167 
168 	vfsp = vn_mountedvfs(vp);
169 	if (vfsp != NULL) {
170 		/*
171 		 * Node is mounted on.
172 		 */
173 		vfs_lock_wait(vfsp);
174 		vn_vfsunlock(vp);
175 		error = VFS_ROOT(vfsp, &newvp);
176 		vfs_unlock(vfsp);
177 		if (error)
178 			return (error);
179 		mutex_enter(&fnp->fn_lock);
180 		if (fnp->fn_seen == newvp && fnp->fn_thread == curthread) {
181 			/*
182 			 * Recursive auto_getattr(); just release newvp and drop
183 			 * into the vfsp == NULL case.
184 			 */
185 			mutex_exit(&fnp->fn_lock);
186 			VN_RELE(newvp);
187 		} else {
188 			while (fnp->fn_thread && fnp->fn_thread != curthread) {
189 				fnp->fn_flags |= MF_ATTR_WAIT;
190 				cv_wait(&fnp->fn_cv_mount, &fnp->fn_lock);
191 			}
192 			fnp->fn_thread = curthread;
193 			fnp->fn_seen = newvp;
194 			mutex_exit(&fnp->fn_lock);
195 			error = VOP_GETATTR(newvp, vap, flags, cred);
196 			VN_RELE(newvp);
197 			mutex_enter(&fnp->fn_lock);
198 			fnp->fn_seen = 0;
199 			fnp->fn_thread = 0;
200 			if (fnp->fn_flags & MF_ATTR_WAIT) {
201 				fnp->fn_flags &= ~MF_ATTR_WAIT;
202 				cv_broadcast(&fnp->fn_cv_mount);
203 			}
204 			mutex_exit(&fnp->fn_lock);
205 			return (error);
206 		}
207 	} else {
208 		vn_vfsunlock(vp);
209 	}
210 
211 defattr:
212 	ASSERT(vp->v_type == VDIR || vp->v_type == VLNK);
213 	vap->va_uid	= 0;
214 	vap->va_gid	= 0;
215 	vap->va_nlink	= fnp->fn_linkcnt;
216 	vap->va_nodeid	= (u_longlong_t)fnp->fn_nodeid;
217 	vap->va_size	= fnp->fn_size;
218 	vap->va_atime	= fnp->fn_atime;
219 	vap->va_mtime	= fnp->fn_mtime;
220 	vap->va_ctime	= fnp->fn_ctime;
221 	vap->va_type	= vp->v_type;
222 	vap->va_mode	= fnp->fn_mode;
223 	vap->va_fsid	= vp->v_vfsp->vfs_dev;
224 	vap->va_rdev	= 0;
225 	vap->va_blksize	= MAXBSIZE;
226 	vap->va_nblocks	= (fsblkcnt64_t)btod(vap->va_size);
227 	vap->va_seq	= 0;
228 
229 	return (0);
230 }
231 
232 /*ARGSUSED4*/
233 static int
234 auto_setattr(
235 	vnode_t *vp,
236 	struct vattr *vap,
237 	int flags,
238 	cred_t *cred,
239 	caller_context_t *ct)
240 {
241 	vnode_t *newvp;
242 	int error;
243 
244 	AUTOFS_DPRINT((4, "auto_setattr vp %p\n", (void *)vp));
245 
246 	if (error = auto_trigger_mount(vp, cred, &newvp))
247 		goto done;
248 
249 	if (newvp != NULL) {
250 		/*
251 		 * Node is mounted on.
252 		 */
253 		if (vn_is_readonly(newvp))
254 			error = EROFS;
255 		else
256 			error = VOP_SETATTR(newvp, vap, flags, cred, NULL);
257 		VN_RELE(newvp);
258 	} else
259 		error = ENOSYS;
260 
261 done:
262 	AUTOFS_DPRINT((5, "auto_setattr: error=%d\n", error));
263 	return (error);
264 }
265 
266 /* ARGSUSED */
267 static int
268 auto_access(vnode_t *vp, int mode, int flags, cred_t *cred)
269 {
270 	fnnode_t *fnp = vntofn(vp);
271 	vnode_t *newvp;
272 	int error;
273 
274 	AUTOFS_DPRINT((4, "auto_access: vp=%p\n", (void *)vp));
275 
276 	if (error = auto_trigger_mount(vp, cred, &newvp))
277 		goto done;
278 
279 	if (newvp != NULL) {
280 		/*
281 		 * Node is mounted on.
282 		 */
283 		error = VOP_ACCESS(newvp, mode, 0, cred);
284 		VN_RELE(newvp);
285 	} else {
286 		int shift = 0;
287 
288 		/*
289 		 * really interested in the autofs node, check the
290 		 * access on it
291 		 */
292 		ASSERT(error == 0);
293 		if (crgetuid(cred) != fnp->fn_uid) {
294 			shift += 3;
295 			if (groupmember(fnp->fn_gid, cred) == 0)
296 				shift += 3;
297 		}
298 		mode &= ~(fnp->fn_mode << shift);
299 		if (mode != 0)
300 			error = secpolicy_vnode_access(cred, vp, fnp->fn_uid,
301 									mode);
302 	}
303 
304 done:
305 	AUTOFS_DPRINT((5, "auto_access: error=%d\n", error));
306 	return (error);
307 }
308 
309 
310 static int
311 auto_lookup(
312 	vnode_t *dvp,
313 	char *nm,
314 	vnode_t **vpp,
315 	pathname_t *pnp,
316 	int flags,
317 	vnode_t *rdir,
318 	cred_t *cred)
319 {
320 	int error = 0;
321 	vnode_t *newvp = NULL;
322 	vfs_t *vfsp;
323 	fninfo_t *dfnip;
324 	fnnode_t *dfnp = NULL;
325 	fnnode_t *fnp = NULL;
326 	char *searchnm;
327 	int operation;		/* either AUTOFS_LOOKUP or AUTOFS_MOUNT */
328 
329 	dfnip = vfstofni(dvp->v_vfsp);
330 	AUTOFS_DPRINT((3, "auto_lookup: dvp=%p (%s) name=%s\n",
331 	    (void *)dvp, dfnip->fi_map, nm));
332 
333 	if (nm[0] == 0) {
334 		VN_HOLD(dvp);
335 		*vpp = dvp;
336 		return (0);
337 	}
338 
339 	if (error = VOP_ACCESS(dvp, VEXEC, 0, cred))
340 		return (error);
341 
342 	if (nm[0] == '.' && nm[1] == 0) {
343 		VN_HOLD(dvp);
344 		*vpp = dvp;
345 		return (0);
346 	}
347 
348 	if (nm[0] == '.' && nm[1] == '.' && nm[2] == 0) {
349 		fnnode_t *pdfnp;
350 
351 		pdfnp = (vntofn(dvp))->fn_parent;
352 		ASSERT(pdfnp != NULL);
353 
354 		/*
355 		 * Since it is legitimate to have the VROOT flag set for the
356 		 * subdirectories of the indirect map in autofs filesystem,
357 		 * rootfnnodep is checked against fnnode of dvp instead of
358 		 * just checking whether VROOT flag is set in dvp
359 		 */
360 
361 		if (pdfnp == pdfnp->fn_globals->fng_rootfnnodep) {
362 			vnode_t *vp;
363 
364 			vfs_lock_wait(dvp->v_vfsp);
365 			if (dvp->v_vfsp->vfs_flag & VFS_UNMOUNTED) {
366 				vfs_unlock(dvp->v_vfsp);
367 				return (EIO);
368 			}
369 			vp = dvp->v_vfsp->vfs_vnodecovered;
370 			VN_HOLD(vp);
371 			vfs_unlock(dvp->v_vfsp);
372 			error = VOP_LOOKUP(vp, nm, vpp, pnp, flags, rdir, cred);
373 			VN_RELE(vp);
374 			return (error);
375 		} else {
376 			*vpp = fntovn(pdfnp);
377 			VN_HOLD(*vpp);
378 			return (0);
379 		}
380 	}
381 
382 top:
383 	dfnp = vntofn(dvp);
384 	searchnm = nm;
385 	operation = 0;
386 
387 	ASSERT(vn_matchops(dvp, auto_vnodeops));
388 
389 	AUTOFS_DPRINT((3, "auto_lookup: dvp=%p dfnp=%p\n", (void *)dvp,
390 	    (void *)dfnp));
391 
392 	/*
393 	 * If a lookup or mount of this node is in progress, wait for it
394 	 * to finish, and return whatever result it got.
395 	 */
396 	mutex_enter(&dfnp->fn_lock);
397 	if (dfnp->fn_flags & (MF_LOOKUP | MF_INPROG)) {
398 		mutex_exit(&dfnp->fn_lock);
399 		error = auto_wait4mount(dfnp);
400 		if (error == AUTOFS_SHUTDOWN)
401 			error = ENOENT;
402 		if (error == EAGAIN)
403 			goto top;
404 		if (error)
405 			return (error);
406 	} else
407 		mutex_exit(&dfnp->fn_lock);
408 
409 
410 	error = vn_vfswlock_wait(dvp);
411 	if (error)
412 		return (error);
413 	vfsp = vn_mountedvfs(dvp);
414 	if (vfsp != NULL) {
415 		vfs_lock_wait(vfsp);
416 		vn_vfsunlock(dvp);
417 		error = VFS_ROOT(vfsp, &newvp);
418 		vfs_unlock(vfsp);
419 		if (!error) {
420 			error = VOP_LOOKUP(newvp, nm, vpp, pnp,
421 			    flags, rdir, cred);
422 			VN_RELE(newvp);
423 		}
424 		return (error);
425 	}
426 	vn_vfsunlock(dvp);
427 
428 	rw_enter(&dfnp->fn_rwlock, RW_READER);
429 	error = auto_search(dfnp, nm, &fnp, cred);
430 	if (error) {
431 		if (dfnip->fi_flags & MF_DIRECT) {
432 			/*
433 			 * direct map.
434 			 */
435 			if (dfnp->fn_dirents) {
436 				/*
437 				 * Mount previously triggered.
438 				 * 'nm' not found
439 				 */
440 				error = ENOENT;
441 			} else {
442 				/*
443 				 * I need to contact the daemon to trigger
444 				 * the mount. 'dfnp' will be the mountpoint.
445 				 */
446 				operation = AUTOFS_MOUNT;
447 				VN_HOLD(fntovn(dfnp));
448 				fnp = dfnp;
449 				error = 0;
450 			}
451 		} else if (dvp == dfnip->fi_rootvp) {
452 			/*
453 			 * 'dfnp' is the root of the indirect AUTOFS.
454 			 */
455 			if (rw_tryupgrade(&dfnp->fn_rwlock) == 0) {
456 				/*
457 				 * Could not acquire writer lock, release
458 				 * reader, and wait until available. We
459 				 * need to search for 'nm' again, since we
460 				 * had to release the lock before reacquiring
461 				 * it.
462 				 */
463 				rw_exit(&dfnp->fn_rwlock);
464 				rw_enter(&dfnp->fn_rwlock, RW_WRITER);
465 				error = auto_search(dfnp, nm, &fnp, cred);
466 			}
467 
468 			ASSERT(RW_WRITE_HELD(&dfnp->fn_rwlock));
469 			if (error) {
470 				/*
471 				 * create node being looked-up and request
472 				 * mount on it.
473 				 */
474 				error = auto_enter(dfnp, nm, &fnp, kcred);
475 				if (!error)
476 					operation = AUTOFS_LOOKUP;
477 			}
478 		} else if ((dfnp->fn_dirents == NULL) &&
479 		    ((dvp->v_flag & VROOT) == 0) &&
480 		    ((fntovn(dfnp->fn_parent))->v_flag & VROOT)) {
481 			/*
482 			 * dfnp is the actual 'mountpoint' of indirect map,
483 			 * it is the equivalent of a direct mount,
484 			 * ie, /home/'user1'
485 			 */
486 			operation = AUTOFS_MOUNT;
487 			VN_HOLD(fntovn(dfnp));
488 			fnp = dfnp;
489 			error = 0;
490 			searchnm = dfnp->fn_name;
491 		}
492 	}
493 
494 	if (error == EAGAIN) {
495 		rw_exit(&dfnp->fn_rwlock);
496 		goto top;
497 	}
498 	if (error) {
499 		rw_exit(&dfnp->fn_rwlock);
500 		return (error);
501 	}
502 
503 	/*
504 	 * We now have the actual fnnode we're interested in.
505 	 * The 'MF_LOOKUP' indicates another thread is currently
506 	 * performing a daemon lookup of this node, therefore we
507 	 * wait for its completion.
508 	 * The 'MF_INPROG' indicates another thread is currently
509 	 * performing a daemon mount of this node, we wait for it
510 	 * to be done if we are performing a MOUNT. We don't
511 	 * wait for it if we are performing a LOOKUP.
512 	 * We can release the reader/writer lock as soon as we acquire
513 	 * the mutex, since the state of the lock can only change by
514 	 * first acquiring the mutex.
515 	 */
516 	mutex_enter(&fnp->fn_lock);
517 	rw_exit(&dfnp->fn_rwlock);
518 	if ((fnp->fn_flags & MF_LOOKUP) ||
519 	    ((operation == AUTOFS_MOUNT) && (fnp->fn_flags & MF_INPROG))) {
520 		mutex_exit(&fnp->fn_lock);
521 		error = auto_wait4mount(fnp);
522 		VN_RELE(fntovn(fnp));
523 		if (error == AUTOFS_SHUTDOWN)
524 			error = ENOENT;
525 		if (error && error != EAGAIN)
526 			return (error);
527 		goto top;
528 	}
529 
530 	if (operation == 0) {
531 		/*
532 		 * got the fnnode, check for any errors
533 		 * on the previous operation on that node.
534 		 */
535 		error = fnp->fn_error;
536 		if ((error == EINTR) || (error == EAGAIN)) {
537 			/*
538 			 * previous operation on this node was
539 			 * not completed, do a lookup now.
540 			 */
541 			operation = AUTOFS_LOOKUP;
542 		} else {
543 			/*
544 			 * previous operation completed. Return
545 			 * a pointer to the node only if there was
546 			 * no error.
547 			 */
548 			mutex_exit(&fnp->fn_lock);
549 			if (!error)
550 				*vpp = fntovn(fnp);
551 			else
552 				VN_RELE(fntovn(fnp));
553 			return (error);
554 		}
555 	}
556 
557 	/*
558 	 * Since I got to this point, it means I'm the one
559 	 * responsible for triggering the mount/look-up of this node.
560 	 */
561 	switch (operation) {
562 	case AUTOFS_LOOKUP:
563 		AUTOFS_BLOCK_OTHERS(fnp, MF_LOOKUP);
564 		fnp->fn_error = 0;
565 		mutex_exit(&fnp->fn_lock);
566 		error = auto_lookup_aux(fnp, searchnm, cred);
567 		if (!error) {
568 			/*
569 			 * Return this vnode
570 			 */
571 			*vpp = fntovn(fnp);
572 		} else {
573 			/*
574 			 * release our reference to this vnode
575 			 * and return error
576 			 */
577 			VN_RELE(fntovn(fnp));
578 		}
579 		break;
580 	case AUTOFS_MOUNT:
581 		AUTOFS_BLOCK_OTHERS(fnp, MF_INPROG);
582 		fnp->fn_error = 0;
583 		mutex_exit(&fnp->fn_lock);
584 		/*
585 		 * auto_new_mount_thread fires up a new thread which
586 		 * calls automountd finishing up the work
587 		 */
588 		auto_new_mount_thread(fnp, searchnm, cred);
589 
590 		/*
591 		 * At this point, we are simply another thread
592 		 * waiting for the mount to complete
593 		 */
594 		error = auto_wait4mount(fnp);
595 		if (error == AUTOFS_SHUTDOWN)
596 			error = ENOENT;
597 
598 		/*
599 		 * now release our reference to this vnode
600 		 */
601 		VN_RELE(fntovn(fnp));
602 		if (!error)
603 			goto top;
604 		break;
605 	default:
606 		auto_log(dfnp->fn_globals, CE_WARN, "auto_lookup: unknown "
607 		    "operation %d", operation);
608 	}
609 
610 	AUTOFS_DPRINT((5, "auto_lookup: name=%s *vpp=%p return=%d\n",
611 	    nm, (void *)*vpp, error));
612 
613 	return (error);
614 }
615 
616 static int
617 auto_create(
618 	vnode_t *dvp,
619 	char *nm,
620 	vattr_t *va,
621 	vcexcl_t excl,
622 	int mode,
623 	vnode_t **vpp,
624 	cred_t *cred,
625 	int flag)
626 {
627 	vnode_t *newvp;
628 	int error;
629 
630 	AUTOFS_DPRINT((4, "auto_create dvp %p nm %s\n", (void *)dvp, nm));
631 
632 	if (error = auto_trigger_mount(dvp, cred, &newvp))
633 		goto done;
634 
635 	if (newvp != NULL) {
636 		/*
637 		 * Node is now mounted on.
638 		 */
639 		if (vn_is_readonly(newvp))
640 			error = EROFS;
641 		else
642 			error = VOP_CREATE(newvp, nm, va, excl,
643 			    mode, vpp, cred, flag);
644 		VN_RELE(newvp);
645 	} else
646 		error = ENOSYS;
647 
648 done:
649 	AUTOFS_DPRINT((5, "auto_create: error=%d\n", error));
650 	return (error);
651 }
652 
653 static int
654 auto_remove(vnode_t *dvp, char *nm, cred_t *cred)
655 {
656 	vnode_t *newvp;
657 	int error;
658 
659 	AUTOFS_DPRINT((4, "auto_remove dvp %p nm %s\n", (void *)dvp, nm));
660 
661 	if (error = auto_trigger_mount(dvp, cred, &newvp))
662 		goto done;
663 
664 	if (newvp != NULL) {
665 		/*
666 		 * Node is now mounted on.
667 		 */
668 		if (vn_is_readonly(newvp))
669 			error = EROFS;
670 		else
671 			error = VOP_REMOVE(newvp, nm, cred);
672 		VN_RELE(newvp);
673 	} else
674 		error = ENOSYS;
675 
676 done:
677 	AUTOFS_DPRINT((5, "auto_remove: error=%d\n", error));
678 	return (error);
679 }
680 
681 static int
682 auto_link(vnode_t *tdvp, vnode_t *svp, char *nm, cred_t *cred)
683 {
684 	vnode_t *newvp;
685 	int error;
686 
687 	AUTOFS_DPRINT((4, "auto_link tdvp %p svp %p nm %s\n", (void *)tdvp,
688 	    (void *)svp, nm));
689 
690 	if (error = auto_trigger_mount(tdvp, cred, &newvp))
691 		goto done;
692 
693 	if (newvp == NULL) {
694 		/*
695 		 * an autonode can not be a link to another node
696 		 */
697 		error = ENOSYS;
698 		goto done;
699 	}
700 
701 	if (vn_is_readonly(newvp)) {
702 		error = EROFS;
703 		VN_RELE(newvp);
704 		goto done;
705 	}
706 
707 	if (vn_matchops(svp, auto_vnodeops)) {
708 		/*
709 		 * source vp can't be an autonode
710 		 */
711 		error = ENOSYS;
712 		VN_RELE(newvp);
713 		goto done;
714 	}
715 
716 	error = VOP_LINK(newvp, svp, nm, cred);
717 	VN_RELE(newvp);
718 
719 done:
720 	AUTOFS_DPRINT((5, "auto_link error=%d\n", error));
721 	return (error);
722 }
723 
724 static int
725 auto_rename(vnode_t *odvp, char *onm, vnode_t *ndvp, char *nnm, cred_t *cr)
726 {
727 	vnode_t *o_newvp, *n_newvp;
728 	int error;
729 
730 	AUTOFS_DPRINT((4, "auto_rename odvp %p onm %s to ndvp %p nnm %s\n",
731 	    (void *)odvp, onm, (void *)ndvp, nnm));
732 
733 	/*
734 	 * we know odvp is an autonode, otherwise this function
735 	 * could not have ever been called.
736 	 */
737 	ASSERT(vn_matchops(odvp, auto_vnodeops));
738 
739 	if (error = auto_trigger_mount(odvp, cr, &o_newvp))
740 		goto done;
741 
742 	if (o_newvp == NULL) {
743 		/*
744 		 * can't rename an autonode
745 		 */
746 		error = ENOSYS;
747 		goto done;
748 	}
749 
750 	if (vn_matchops(ndvp, auto_vnodeops)) {
751 		/*
752 		 * directory is AUTOFS, need to trigger the
753 		 * mount of the real filesystem.
754 		 */
755 		if (error = auto_trigger_mount(ndvp, cr, &n_newvp)) {
756 			VN_RELE(o_newvp);
757 			goto done;
758 		}
759 
760 		if (n_newvp == NULL) {
761 			/*
762 			 * target can't be an autonode
763 			 */
764 			error = ENOSYS;
765 			VN_RELE(o_newvp);
766 			goto done;
767 		}
768 	} else {
769 		/*
770 		 * destination directory mount had been
771 		 * triggered prior to the call to this function.
772 		 */
773 		n_newvp = ndvp;
774 	}
775 
776 	ASSERT(!vn_matchops(n_newvp, auto_vnodeops));
777 
778 	if (vn_is_readonly(n_newvp)) {
779 		error = EROFS;
780 		VN_RELE(o_newvp);
781 		if (n_newvp != ndvp)
782 			VN_RELE(n_newvp);
783 		goto done;
784 	}
785 
786 	error = VOP_RENAME(o_newvp, onm, n_newvp, nnm, cr);
787 	VN_RELE(o_newvp);
788 	if (n_newvp != ndvp)
789 		VN_RELE(n_newvp);
790 
791 done:
792 	AUTOFS_DPRINT((5, "auto_rename error=%d\n", error));
793 	return (error);
794 }
795 
796 static int
797 auto_mkdir(vnode_t *dvp, char *nm, vattr_t *va, vnode_t **vpp, cred_t *cred)
798 {
799 	vnode_t *newvp;
800 	int error;
801 
802 	AUTOFS_DPRINT((4, "auto_mkdir dvp %p nm %s\n", (void *)dvp, nm));
803 
804 	if (error = auto_trigger_mount(dvp, cred, &newvp))
805 		goto done;
806 
807 	if (newvp != NULL) {
808 		/*
809 		 * Node is now mounted on.
810 		 */
811 		if (vn_is_readonly(newvp))
812 			error = EROFS;
813 		else
814 			error = VOP_MKDIR(newvp, nm, va, vpp, cred);
815 		VN_RELE(newvp);
816 	} else
817 		error = ENOSYS;
818 
819 done:
820 	AUTOFS_DPRINT((5, "auto_mkdir: error=%d\n", error));
821 	return (error);
822 }
823 
824 static int
825 auto_rmdir(vnode_t *dvp, char *nm, vnode_t *cdir, cred_t *cred)
826 {
827 	vnode_t *newvp;
828 	int error;
829 
830 	AUTOFS_DPRINT((4, "auto_rmdir: vp=%p nm=%s\n", (void *)dvp, nm));
831 
832 	if (error = auto_trigger_mount(dvp, cred, &newvp))
833 		goto done;
834 
835 	if (newvp != NULL) {
836 		/*
837 		 * Node is now mounted on.
838 		 */
839 		if (vn_is_readonly(newvp))
840 			error = EROFS;
841 		else
842 			error = VOP_RMDIR(newvp, nm, cdir, cred);
843 		VN_RELE(newvp);
844 	} else
845 		error = ENOSYS;
846 
847 done:
848 	AUTOFS_DPRINT((5, "auto_rmdir: error=%d\n", error));
849 	return (error);
850 }
851 
852 static int autofs_nobrowse = 0;
853 
854 #ifdef nextdp
855 #undef nextdp
856 #endif
857 #define	nextdp(dp)	((struct dirent64 *)((char *)(dp) + (dp)->d_reclen))
858 
859 static int
860 auto_readdir(vnode_t *vp, uio_t *uiop, cred_t *cred, int *eofp)
861 {
862 	struct autofs_rddirargs rda;
863 	struct autofs_rddirres rd;
864 	fnnode_t *fnp = vntofn(vp);
865 	fnnode_t *cfnp, *nfnp;
866 	dirent64_t *dp;
867 	ulong_t offset;
868 	ulong_t outcount = 0, count = 0;
869 	size_t namelen;
870 	ulong_t alloc_count;
871 	void *outbuf;
872 	fninfo_t *fnip = vfstofni(vp->v_vfsp);
873 	struct iovec *iovp;
874 	int error = 0;
875 	int reached_max = 0;
876 	int myeof = 0;
877 	int this_reclen;
878 
879 	AUTOFS_DPRINT((4, "auto_readdir vp=%p offset=%lld\n",
880 	    (void *)vp, uiop->uio_loffset));
881 
882 	if (eofp != NULL)
883 		*eofp = 0;
884 
885 	iovp = uiop->uio_iov;
886 	alloc_count = iovp->iov_len;
887 
888 	if (uiop->uio_iovcnt != 1)
889 		return (EINVAL);
890 
891 	gethrestime(&fnp->fn_atime);
892 	fnp->fn_ref_time = fnp->fn_atime.tv_sec;
893 
894 	dp = outbuf = kmem_alloc(alloc_count, KM_SLEEP);
895 
896 	/*
897 	 * Held when getdents calls VOP_RWLOCK....
898 	 */
899 	ASSERT(RW_READ_HELD(&fnp->fn_rwlock));
900 	if (uiop->uio_offset >= AUTOFS_DAEMONCOOKIE) {
901 again:
902 		/*
903 		 * Do readdir of daemon contents only
904 		 * Drop readers lock and reacquire after reply.
905 		 */
906 		rw_exit(&fnp->fn_rwlock);
907 
908 		count = 0;
909 		rda.rda_map = fnip->fi_map;
910 		rda.rda_offset = (uint_t)uiop->uio_offset;
911 		rd.rd_rddir.rddir_entries = dp;
912 		rda.rda_count = rd.rd_rddir.rddir_size = (uint_t)alloc_count;
913 		error = auto_calldaemon(fnip, AUTOFS_READDIR,
914 		    xdr_autofs_rddirargs, &rda,
915 		    xdr_autofs_rddirres, &rd,
916 		    cred, TRUE);
917 		/*
918 		 * reacquire previously dropped lock
919 		 */
920 		rw_enter(&fnp->fn_rwlock, RW_READER);
921 
922 		if (!error)
923 			error = rd.rd_status;
924 		if (error) {
925 			if (error == AUTOFS_SHUTDOWN) {
926 				/*
927 				 * treat as empty directory
928 				 */
929 				error = 0;
930 				myeof = 1;
931 				if (eofp)
932 					*eofp = 1;
933 			}
934 			goto done;
935 		}
936 
937 		if (rd.rd_rddir.rddir_size) {
938 			dirent64_t *odp = dp;	/* next in output buffer */
939 			dirent64_t *cdp = dp;	/* current examined entry */
940 
941 			/*
942 			 * Check for duplicates here
943 			 */
944 			do {
945 				this_reclen = cdp->d_reclen;
946 				if (auto_search(fnp, cdp->d_name, NULL, cred)) {
947 					/*
948 					 * entry not found in kernel list,
949 					 * include it in readdir output.
950 					 *
951 					 * If we are skipping entries. then
952 					 * we need to copy this entry to the
953 					 * correct position in the buffer
954 					 * to be copied out.
955 					 */
956 					if (cdp != odp)
957 						bcopy(cdp, odp,
958 						    (size_t)this_reclen);
959 					odp = nextdp(odp);
960 					outcount += this_reclen;
961 				} else {
962 					/*
963 					 * Entry was found in the kernel
964 					 * list. If it is the first entry
965 					 * in this buffer, then just skip it
966 					 */
967 					if (odp == dp) {
968 						dp = nextdp(dp);
969 						odp = dp;
970 					}
971 				}
972 				count += this_reclen;
973 				cdp = (struct dirent64 *)
974 				    ((char *)cdp + this_reclen);
975 			} while (count < rd.rd_rddir.rddir_size);
976 
977 			if (outcount)
978 				error = uiomove(dp, outcount, UIO_READ, uiop);
979 			uiop->uio_offset = rd.rd_rddir.rddir_offset;
980 		} else {
981 			if (rd.rd_rddir.rddir_eof == 0) {
982 				/*
983 				 * alloc_count not large enough for one
984 				 * directory entry
985 				 */
986 				error = EINVAL;
987 			}
988 		}
989 		if (rd.rd_rddir.rddir_eof && !error) {
990 			myeof = 1;
991 			if (eofp)
992 				*eofp = 1;
993 		}
994 		if (!error && !myeof && outcount == 0) {
995 			/*
996 			 * call daemon with new cookie, all previous
997 			 * elements happened to be duplicates
998 			 */
999 			dp = outbuf;
1000 			goto again;
1001 		}
1002 		goto done;
1003 	}
1004 
1005 	if (uiop->uio_offset == 0) {
1006 		/*
1007 		 * first time: so fudge the . and ..
1008 		 */
1009 		this_reclen = DIRENT64_RECLEN(1);
1010 		if (alloc_count < this_reclen) {
1011 			error = EINVAL;
1012 			goto done;
1013 		}
1014 		dp->d_ino = (ino64_t)fnp->fn_nodeid;
1015 		dp->d_off = (off64_t)1;
1016 		dp->d_reclen = (ushort_t)this_reclen;
1017 
1018 		/* use strncpy(9f) to zero out uninitialized bytes */
1019 
1020 		(void) strncpy(dp->d_name, ".",
1021 		    DIRENT64_NAMELEN(this_reclen));
1022 		outcount += dp->d_reclen;
1023 		dp = nextdp(dp);
1024 
1025 		this_reclen = DIRENT64_RECLEN(2);
1026 		if (alloc_count < outcount + this_reclen) {
1027 			error = EINVAL;
1028 			goto done;
1029 		}
1030 		dp->d_reclen = (ushort_t)this_reclen;
1031 		dp->d_ino = (ino64_t)fnp->fn_parent->fn_nodeid;
1032 		dp->d_off = (off64_t)2;
1033 
1034 		/* use strncpy(9f) to zero out uninitialized bytes */
1035 
1036 		(void) strncpy(dp->d_name, "..",
1037 		    DIRENT64_NAMELEN(this_reclen));
1038 		outcount += dp->d_reclen;
1039 		dp = nextdp(dp);
1040 	}
1041 
1042 	offset = 2;
1043 	cfnp = fnp->fn_dirents;
1044 	while (cfnp != NULL) {
1045 		nfnp = cfnp->fn_next;
1046 		offset = cfnp->fn_offset;
1047 		if ((offset >= uiop->uio_offset) &&
1048 		    (!(cfnp->fn_flags & MF_LOOKUP))) {
1049 			int reclen;
1050 
1051 			/*
1052 			 * include node only if its offset is greater or
1053 			 * equal to the one required and it is not in
1054 			 * transient state (not being looked-up)
1055 			 */
1056 			namelen = strlen(cfnp->fn_name);
1057 			reclen = (int)DIRENT64_RECLEN(namelen);
1058 			if (outcount + reclen > alloc_count) {
1059 				reached_max = 1;
1060 				break;
1061 			}
1062 			dp->d_reclen = (ushort_t)reclen;
1063 			dp->d_ino = (ino64_t)cfnp->fn_nodeid;
1064 			if (nfnp != NULL) {
1065 				/*
1066 				 * get the offset of the next element
1067 				 */
1068 				dp->d_off = (off64_t)nfnp->fn_offset;
1069 			} else {
1070 				/*
1071 				 * This is the last element, make
1072 				 * offset one plus the current
1073 				 */
1074 				dp->d_off = (off64_t)cfnp->fn_offset + 1;
1075 			}
1076 
1077 			/* use strncpy(9f) to zero out uninitialized bytes */
1078 
1079 			(void) strncpy(dp->d_name, cfnp->fn_name,
1080 			    DIRENT64_NAMELEN(reclen));
1081 			outcount += dp->d_reclen;
1082 			dp = nextdp(dp);
1083 		}
1084 		cfnp = nfnp;
1085 	}
1086 
1087 	if (outcount)
1088 		error = uiomove(outbuf, outcount, UIO_READ, uiop);
1089 	if (!error) {
1090 		if (reached_max) {
1091 			/*
1092 			 * This entry did not get added to the buffer on this,
1093 			 * call. We need to add it on the next call therefore
1094 			 * set uio_offset to this entry's offset.  If there
1095 			 * wasn't enough space for one dirent, return EINVAL.
1096 			 */
1097 			uiop->uio_offset = offset;
1098 			if (outcount == 0)
1099 				error = EINVAL;
1100 		} else if (autofs_nobrowse ||
1101 		    auto_nobrowse_option(fnip->fi_opts) ||
1102 		    (fnip->fi_flags & MF_DIRECT) || (fnp->fn_trigger != NULL) ||
1103 		    (((vp->v_flag & VROOT) == 0) &&
1104 		    ((fntovn(fnp->fn_parent))->v_flag & VROOT) &&
1105 		    (fnp->fn_dirents == NULL))) {
1106 			/*
1107 			 * done reading directory entries
1108 			 */
1109 			uiop->uio_offset = offset + 1;
1110 			if (eofp)
1111 				*eofp = 1;
1112 		} else {
1113 			/*
1114 			 * Need to get the rest of the entries from the daemon.
1115 			 */
1116 			uiop->uio_offset = AUTOFS_DAEMONCOOKIE;
1117 		}
1118 	}
1119 
1120 done:
1121 	kmem_free(outbuf, alloc_count);
1122 	AUTOFS_DPRINT((5, "auto_readdir vp=%p offset=%lld eof=%d\n",
1123 	    (void *)vp, uiop->uio_loffset, myeof));
1124 	return (error);
1125 }
1126 
1127 static int
1128 auto_symlink(
1129 	vnode_t *dvp,
1130 	char *lnknm,		/* new entry */
1131 	vattr_t *tva,
1132 	char *tnm,		/* existing entry */
1133 	cred_t *cred)
1134 {
1135 	vnode_t *newvp;
1136 	int error;
1137 
1138 	AUTOFS_DPRINT((4, "auto_symlink: dvp=%p lnknm=%s tnm=%s\n",
1139 	    (void *)dvp, lnknm, tnm));
1140 
1141 	if (error = auto_trigger_mount(dvp, cred, &newvp))
1142 		goto done;
1143 
1144 	if (newvp != NULL) {
1145 		/*
1146 		 * Node is mounted on.
1147 		 */
1148 		if (vn_is_readonly(newvp))
1149 			error = EROFS;
1150 		else
1151 			error = VOP_SYMLINK(newvp, lnknm, tva, tnm, cred);
1152 		VN_RELE(newvp);
1153 	} else
1154 		error = ENOSYS;
1155 
1156 done:
1157 	AUTOFS_DPRINT((5, "auto_symlink: error=%d\n", error));
1158 	return (error);
1159 }
1160 
1161 /* ARGSUSED */
1162 static int
1163 auto_readlink(vnode_t *vp, struct uio *uiop, cred_t *cr)
1164 {
1165 	fnnode_t *fnp = vntofn(vp);
1166 	int error;
1167 	timestruc_t now;
1168 
1169 	AUTOFS_DPRINT((4, "auto_readlink: vp=%p\n", (void *)vp));
1170 
1171 	gethrestime(&now);
1172 	fnp->fn_ref_time = now.tv_sec;
1173 
1174 	if (vp->v_type != VLNK)
1175 		error = EINVAL;
1176 	else {
1177 		ASSERT(!(fnp->fn_flags & (MF_INPROG | MF_LOOKUP)));
1178 		fnp->fn_atime = now;
1179 		error = uiomove(fnp->fn_symlink, MIN(fnp->fn_symlinklen,
1180 		    uiop->uio_resid), UIO_READ, uiop);
1181 	}
1182 
1183 	AUTOFS_DPRINT((5, "auto_readlink: error=%d\n", error));
1184 	return (error);
1185 }
1186 
1187 /* ARGSUSED */
1188 static int
1189 auto_fsync(vnode_t *cp, int syncflag, cred_t *cred)
1190 {
1191 	return (0);
1192 }
1193 
1194 /* ARGSUSED */
1195 static void
1196 auto_inactive(vnode_t *vp, cred_t *cred)
1197 {
1198 	fnnode_t *fnp = vntofn(vp);
1199 	fnnode_t *dfnp = fnp->fn_parent;
1200 	int count;
1201 
1202 	AUTOFS_DPRINT((4, "auto_inactive: vp=%p v_count=%u fn_link=%d\n",
1203 	    (void *)vp, vp->v_count, fnp->fn_linkcnt));
1204 
1205 	/*
1206 	 * The rwlock should not be already held by this thread.
1207 	 * The assert relies on the fact that the owner field is cleared
1208 	 * when the lock is released.
1209 	 */
1210 	ASSERT(dfnp != NULL);
1211 	ASSERT(rw_owner(&dfnp->fn_rwlock) != curthread);
1212 	rw_enter(&dfnp->fn_rwlock, RW_WRITER);
1213 	mutex_enter(&vp->v_lock);
1214 	ASSERT(vp->v_count > 0);
1215 	count = --vp->v_count;
1216 	mutex_exit(&vp->v_lock);
1217 	if (count == 0) {
1218 		/*
1219 		 * Free only if node has no subdirectories.
1220 		 */
1221 		if (fnp->fn_linkcnt == 1) {
1222 			auto_disconnect(dfnp, fnp);
1223 			rw_exit(&dfnp->fn_rwlock);
1224 			auto_freefnnode(fnp);
1225 			AUTOFS_DPRINT((5, "auto_inactive: (exit) vp=%p freed\n",
1226 			    (void *)vp));
1227 			return;
1228 		}
1229 	}
1230 	rw_exit(&dfnp->fn_rwlock);
1231 
1232 	AUTOFS_DPRINT((5, "auto_inactive: (exit) vp=%p v_count=%u fn_link=%d\n",
1233 	    (void *)vp, vp->v_count, fnp->fn_linkcnt));
1234 }
1235 
1236 /* ARGSUSED2 */
1237 static int
1238 auto_rwlock(vnode_t *vp, int write_lock, caller_context_t *ct)
1239 {
1240 	fnnode_t *fnp = vntofn(vp);
1241 	if (write_lock)
1242 		rw_enter(&fnp->fn_rwlock, RW_WRITER);
1243 	else
1244 		rw_enter(&fnp->fn_rwlock, RW_READER);
1245 	return (write_lock);
1246 }
1247 
1248 /* ARGSUSED */
1249 static void
1250 auto_rwunlock(vnode_t *vp, int write_lock, caller_context_t *ct)
1251 {
1252 	fnnode_t *fnp = vntofn(vp);
1253 	rw_exit(&fnp->fn_rwlock);
1254 }
1255 
1256 
1257 /* ARGSUSED */
1258 static int
1259 auto_seek(struct vnode *vp, offset_t ooff, offset_t *noffp)
1260 {
1261 	/*
1262 	 * Return 0 unconditionally, since we expect
1263 	 * a VDIR all the time
1264 	 */
1265 	return (0);
1266 }
1267 
1268 /*
1269  * Triggers the mount if needed. If the mount has been triggered by
1270  * another thread, it will wait for its return status, and return it.
1271  * Whether the mount is triggered by this thread, another thread, or
1272  * if the vnode was already covered, '*newvp' is a
1273  * VN_HELD vnode pointing to the root of the filesystem covering 'vp'.
1274  * If the node is not mounted on, and should not be mounted on, '*newvp'
1275  * will be NULL.
1276  * The calling routine may use '*newvp' to do the filesystem jump.
1277  */
1278 static int
1279 auto_trigger_mount(vnode_t *vp, cred_t *cred, vnode_t **newvp)
1280 {
1281 	fnnode_t *fnp = vntofn(vp);
1282 	fninfo_t *fnip = vfstofni(vp->v_vfsp);
1283 	vnode_t *dvp;
1284 	vfs_t *vfsp;
1285 	int delayed_ind;
1286 	char name[AUTOFS_MAXPATHLEN];
1287 	int error;
1288 
1289 	AUTOFS_DPRINT((4, "auto_trigger_mount: vp=%p\n", (void *)vp));
1290 
1291 	*newvp = NULL;
1292 
1293 	/*
1294 	 * Cross-zone mount triggering is disallowed.
1295 	 */
1296 	if (fnip->fi_zoneid != getzoneid())
1297 		return (EPERM);	/* Not owner of mount */
1298 
1299 retry:
1300 	error = 0;
1301 	delayed_ind = 0;
1302 	mutex_enter(&fnp->fn_lock);
1303 	while (fnp->fn_flags & (MF_LOOKUP | MF_INPROG)) {
1304 		/*
1305 		 * Mount or lookup in progress,
1306 		 * wait for it before proceeding.
1307 		 */
1308 		mutex_exit(&fnp->fn_lock);
1309 		error = auto_wait4mount(fnp);
1310 		if (error == AUTOFS_SHUTDOWN) {
1311 			error = 0;
1312 			goto done;
1313 		}
1314 		if (error && error != EAGAIN)
1315 			goto done;
1316 		error = 0;
1317 		mutex_enter(&fnp->fn_lock);
1318 	}
1319 
1320 	/*
1321 	 * If the vfslock can't be acquired for the first time.
1322 	 * drop the fn_lock and retry next time in blocking mode.
1323 	 */
1324 	if (vn_vfswlock(vp)) {
1325 		/*
1326 		 * Lock held by another thread.
1327 		 * Perform blocking by dropping the
1328 		 * fn_lock.
1329 		 */
1330 		mutex_exit(&fnp->fn_lock);
1331 		error = vn_vfswlock_wait(vp);
1332 		if (error)
1333 			goto done;
1334 		/*
1335 		 * Because fn_lock wasn't held, the state
1336 		 * of the trigger node might have changed.
1337 		 * Need to run through the checks on trigger
1338 		 * node again.
1339 		 */
1340 		vn_vfsunlock(vp);
1341 		goto retry;
1342 	}
1343 
1344 	vfsp = vn_mountedvfs(vp);
1345 	if (vfsp != NULL) {
1346 		mutex_exit(&fnp->fn_lock);
1347 		vfs_lock_wait(vfsp);
1348 		vn_vfsunlock(vp);
1349 		error = VFS_ROOT(vfsp, newvp);
1350 		vfs_unlock(vfsp);
1351 		goto done;
1352 	} else {
1353 		vn_vfsunlock(vp);
1354 		if ((fnp->fn_flags & MF_MOUNTPOINT) &&
1355 		    fnp->fn_trigger != NULL) {
1356 			ASSERT(fnp->fn_dirents == NULL);
1357 			/*
1358 			 * The filesystem that used to sit here has been
1359 			 * forcibly unmounted.
1360 			 */
1361 			mutex_exit(&fnp->fn_lock);
1362 			error = EIO;
1363 			goto done;
1364 		}
1365 	}
1366 
1367 	ASSERT(vp->v_type == VDIR);
1368 	dvp = fntovn(fnp->fn_parent);
1369 
1370 	if ((fnp->fn_dirents == NULL) &&
1371 	    ((fnip->fi_flags & MF_DIRECT) == 0) &&
1372 	    ((vp->v_flag & VROOT) == 0) &&
1373 	    (dvp->v_flag & VROOT)) {
1374 		/*
1375 		 * If the parent of this node is the root of an indirect
1376 		 * AUTOFS filesystem, this node is remountable.
1377 		 */
1378 		delayed_ind = 1;
1379 	}
1380 
1381 	if (delayed_ind ||
1382 	    ((fnip->fi_flags & MF_DIRECT) && (fnp->fn_dirents == NULL))) {
1383 		/*
1384 		 * Trigger mount since:
1385 		 * direct mountpoint with no subdirs or
1386 		 * delayed indirect.
1387 		 */
1388 		AUTOFS_BLOCK_OTHERS(fnp, MF_INPROG);
1389 		fnp->fn_error = 0;
1390 		mutex_exit(&fnp->fn_lock);
1391 		if (delayed_ind)
1392 			(void) strcpy(name, fnp->fn_name);
1393 		else
1394 			(void) strcpy(name, ".");
1395 		fnp->fn_ref_time = gethrestime_sec();
1396 		auto_new_mount_thread(fnp, name, cred);
1397 		/*
1398 		 * At this point we're simply another thread waiting
1399 		 * for the mount to finish.
1400 		 */
1401 		error = auto_wait4mount(fnp);
1402 		if (error == EAGAIN)
1403 			goto retry;
1404 		if (error == AUTOFS_SHUTDOWN) {
1405 			error = 0;
1406 			goto done;
1407 		}
1408 		if (error == 0) {
1409 			if (error = vn_vfswlock_wait(vp))
1410 				goto done;
1411 			/* Reacquire after dropping locks */
1412 			vfsp = vn_mountedvfs(vp);
1413 			if (vfsp != NULL) {
1414 				vfs_lock_wait(vfsp);
1415 				vn_vfsunlock(vp);
1416 				error = VFS_ROOT(vfsp, newvp);
1417 				vfs_unlock(vfsp);
1418 			} else {
1419 				vn_vfsunlock(vp);
1420 				goto retry;
1421 			}
1422 		}
1423 	} else
1424 		mutex_exit(&fnp->fn_lock);
1425 
1426 done:
1427 	AUTOFS_DPRINT((5, "auto_trigger_mount: error=%d\n", error));
1428 	return (error);
1429 }
1430