FreeBSD/sys/kern/vfs_mount.c
/*
 * vfs_domount(): actually attempt a filesystem mount.
 */
actually attempt a filesystem mount.
actually attempt a filesystem mount .
static int
vfs_domount(
	struct thread *td,		
	const char *fstype,		
	char *fspath,			
	uint64_t fsflags,		
	struct vfsoptlist **optlist	
	)
{
	struct vfsconf *vfsp;
	struct nameidata nd;
	struct vnode *vp;
	char *pathbuf;
	int error;
	if (strlen(fstype) >= MFSNAMELEN || strlen(fspath) >= MNAMELEN)
		return (ENAMETOOLONG);
	if (jailed(td->td_ucred) || usermount == 0) {
		if ((error = priv_check(td, PRIV_VFS_MOUNT)) != 0)
			return (error);
	}
	if (fsflags & MNT_EXPORTED) {
		error = priv_check(td, PRIV_VFS_MOUNT_EXPORTED);
		if (error)
			return (error);
	}
	if (fsflags & MNT_SUIDDIR) {
		error = priv_check(td, PRIV_VFS_MOUNT_SUIDDIR);
		if (error)
			return (error);
	}
	if ((fsflags & (MNT_NOSUID | MNT_USER)) != (MNT_NOSUID | MNT_USER)) {
		if (priv_check(td, PRIV_VFS_MOUNT_NONUSER) != 0)
			fsflags |= MNT_NOSUID | MNT_USER;
	}
	vfsp = NULL;
	if ((fsflags & MNT_UPDATE) == 0) {
		if (fsflags & MNT_ROOTFS)
			vfsp = vfs_byname(fstype);
		else
			vfsp = vfs_byname_kld(fstype, td, &error);
		if (vfsp == NULL)
			return (ENODEV);
		if (jailed(td->td_ucred) && !(vfsp->vfc_flags & VFCF_JAIL))
			return (EPERM);
	}
	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1,
	    UIO_SYSSPACE, fspath, td);
	error = namei(&nd);
	if (error != 0)
		return (error);
	NDFREE(&nd, NDF_ONLY_PNBUF);
	vp = nd.ni_vp;
	if ((fsflags & MNT_UPDATE) == 0) {
		pathbuf = malloc(MNAMELEN, M_TEMP, M_WAITOK);
		strcpy(pathbuf, fspath);
		error = vn_path_to_global_path(td, vp, pathbuf, MNAMELEN);
		if (error == 0 || error == ENODEV) {
			error = vfs_domount_first(td, vfsp, pathbuf, vp,
			    fsflags, optlist);
		}
		free(pathbuf, M_TEMP);
	} else
		error = vfs_domount_update(td, vp, fsflags, optlist);
	return (error);
}
static int vfs_domount ( struct thread * td , const char * fstype , char * fspath , uint64_t fsflags , struct vfsoptlist * * optlist ) { struct vfsconf * vfsp ; struct nameidata nd ; struct vnode * vp ; char * pathbuf ; int error ; if ( strlen ( fstype ) >= MFSNAMELEN || strlen ( fspath ) >= MNAMELEN ) return ( ENAMETOOLONG ) ; if ( jailed ( td -> td_ucred ) || usermount == 0 ) { if ( ( error = priv_check ( td , PRIV_VFS_MOUNT ) ) != 0 ) return ( error ) ; } if ( fsflags & MNT_EXPORTED ) { error = priv_check ( td , PRIV_VFS_MOUNT_EXPORTED ) ; if ( error ) return ( error ) ; } if ( fsflags & MNT_SUIDDIR ) { error = priv_check ( td , PRIV_VFS_MOUNT_SUIDDIR ) ; if ( error ) return ( error ) ; } if ( ( fsflags & ( MNT_NOSUID | MNT_USER ) ) != ( MNT_NOSUID | MNT_USER ) ) { if ( priv_check ( td , PRIV_VFS_MOUNT_NONUSER ) != 0 ) fsflags |= MNT_NOSUID | MNT_USER ; } vfsp = NULL ; if ( ( fsflags & MNT_UPDATE ) == 0 ) { if ( fsflags & MNT_ROOTFS ) vfsp = vfs_byname ( fstype ) ; else vfsp = vfs_byname_kld ( fstype , td , & error ) ; if ( vfsp == NULL ) return ( ENODEV ) ; if ( jailed ( td -> td_ucred ) && ! ( vfsp -> vfc_flags & VFCF_JAIL ) ) return ( EPERM ) ; } NDINIT ( & nd , LOOKUP , FOLLOW | LOCKLEAF | AUDITVNODE1 , UIO_SYSSPACE , fspath , td ) ; error = namei ( & nd ) ; if ( error != 0 ) return ( error ) ; NDFREE ( & nd , NDF_ONLY_PNBUF ) ; vp = nd . ni_vp ; if ( ( fsflags & MNT_UPDATE ) == 0 ) { pathbuf = malloc ( MNAMELEN , M_TEMP , M_WAITOK ) ; strcpy ( pathbuf , fspath ) ; error = vn_path_to_global_path ( td , vp , pathbuf , MNAMELEN ) ; if ( error == 0 || error == ENODEV ) { error = vfs_domount_first ( td , vfsp , pathbuf , vp , fsflags , optlist ) ; } free ( pathbuf , M_TEMP ) ; } else error = vfs_domount_update ( td , vp , fsflags , optlist ) ; return ( error ) ; }
vfs_domount(): actually attempt a filesystem mount.
vfs_domount () : actually attempt a filesystem mount .
/* Calling thread. */ /* Filesystem type. */ /* Mount path. */ /* Flags common to all filesystems. */ /* Options local to the filesystem. */ /*
	 * Be ultra-paranoid about making sure the type and fspath
	 * variables will fit in our mp buffers, including the
	 * terminating NUL.
	 */ /*
	 * Do not allow NFS export or MNT_SUIDDIR by unprivileged users.
	 */ /*
	 * Silently enforce MNT_NOSUID and MNT_USER for unprivileged users.
	 */ /* Load KLDs before we lock the covered vnode to avoid reversals. */ /* Don't try to load KLDs if we're mounting the root. */ /*
	 * Get vnode to be covered or mount point's vnode in case of MNT_UPDATE.
	 */ /* debug.disablefullpath == 1 results in ENODEV */