FreeBSD/sys/fs/autofs/autofs_vnops.c
/*
 * Unlock the vnode, request automountd(8) action, and then lock it back.
 * If anything got mounted on top of the vnode, return the new filesystem's
 * root vnode in 'newvp', locked.
 */
Unlock the vnode, request automountd(8) action, and then lock it back.
If anything got mounted on top of the vnode, return the new filesystem's
root vnode in 'newvp', locked.
Unlock the vnode request automountd ( 8 ) action and then lock it back . If anything got mounted on top of the vnode return the new filesystem ' s root vnode in ' newvp ' locked .
static int
autofs_trigger_vn(struct vnode *vp, const char *path, int pathlen,
    struct vnode **newvp)
{
	struct autofs_node *anp;
	struct autofs_mount *amp;
	int error, lock_flags;
	anp = vp->v_data;
	amp = VFSTOAUTOFS(vp->v_mount);
	lock_flags = VOP_ISLOCKED(vp);
	vref(vp);
	VOP_UNLOCK(vp, 0);
	sx_xlock(&autofs_softc->sc_lock);
	if (vp->v_mountedhere != NULL) {
		error = 0;
		goto mounted;
	}
	error = autofs_trigger(anp, path, pathlen);
mounted:
	sx_xunlock(&autofs_softc->sc_lock);
	vn_lock(vp, lock_flags | LK_RETRY);
	vunref(vp);
	if ((vp->v_iflag & VI_DOOMED) != 0) {
		AUTOFS_DEBUG("VI_DOOMED");
		return (ENOENT);
	}
	if (error != 0)
		return (error);
	if (vp->v_mountedhere == NULL) {
		*newvp = NULL;
		return (0);
	} else {
		anp->an_cached = false;
	}
	error = VFS_ROOT(vp->v_mountedhere, lock_flags, newvp);
	if (error != 0) {
		AUTOFS_WARN("VFS_ROOT() failed with error %d", error);
		return (error);
	}
	return (0);
}
static int autofs_trigger_vn ( struct vnode * vp , const char * path , int pathlen , struct vnode * * newvp ) { struct autofs_node * anp ; struct autofs_mount * amp ; int error , lock_flags ; anp = vp -> v_data ; amp = VFSTOAUTOFS ( vp -> v_mount ) ; lock_flags = VOP_ISLOCKED ( vp ) ; vref ( vp ) ; VOP_UNLOCK ( vp , 0 ) ; sx_xlock ( & autofs_softc -> sc_lock ) ; if ( vp -> v_mountedhere != NULL ) { error = 0 ; goto mounted ; } error = autofs_trigger ( anp , path , pathlen ) ; mounted : sx_xunlock ( & autofs_softc -> sc_lock ) ; vn_lock ( vp , lock_flags | LK_RETRY ) ; vunref ( vp ) ; if ( ( vp -> v_iflag & VI_DOOMED ) != 0 ) { AUTOFS_DEBUG ( " " ) ; return ( ENOENT ) ; } if ( error != 0 ) return ( error ) ; if ( vp -> v_mountedhere == NULL ) { * newvp = NULL ; return ( 0 ) ; } else { anp -> an_cached = false ; } error = VFS_ROOT ( vp -> v_mountedhere , lock_flags , newvp ) ; if ( error != 0 ) { AUTOFS_WARN ( " " , error ) ; return ( error ) ; } return ( 0 ) ; }
Unlock the vnode, request automountd(8) action, and then lock it back.
Unlock the vnode request automountd ( 8 ) action and then lock it back .
/*
	 * Release the vnode lock, so that other operations, in partcular
	 * mounting a filesystem on top of it, can proceed.  Increase use
	 * count, to prevent the vnode from being deallocated and to prevent
	 * filesystem from being unmounted.
	 */ /*
	 * XXX: Workaround for mounting the same thing multiple times; revisit.
	 */ /*
		 * If the operation that succeeded was mount, then mark
		 * the node as non-cached.  Otherwise, if someone unmounts
		 * the filesystem before the cache times out, we will fail
		 * to trigger.
		 */