diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/vfs_init.c | 37 | ||||
-rw-r--r-- | sys/kern/vfs_mount.c | 32 | ||||
-rw-r--r-- | sys/sys/mount.h | 1 |
3 files changed, 41 insertions, 29 deletions
diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c index 343f5f7..1b1e419 100644 --- a/sys/kern/vfs_init.c +++ b/sys/kern/vfs_init.c @@ -40,7 +40,9 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> +#include <sys/linker.h> #include <sys/mount.h> +#include <sys/proc.h> #include <sys/sysctl.h> #include <sys/vnode.h> #include <sys/malloc.h> @@ -124,6 +126,41 @@ vfs_byname(const char *name) return (NULL); } +struct vfsconf * +vfs_byname_kld(const char *fstype, struct thread *td, int *error) +{ + struct vfsconf *vfsp; + linker_file_t lf; + + vfsp = vfs_byname(fstype); + if (vfsp != NULL) + return (vfsp); + + /* Only load modules for root (very important!). */ + *error = suser(td); + if (*error) + return (NULL); + *error = securelevel_gt(td->td_ucred, 0); + if (*error) + return (NULL); + *error = linker_load_module(NULL, fstype, NULL, NULL, &lf); + if (lf == NULL) + *error = ENODEV; + if (*error) + return (NULL); + lf->userrefs++; + /* Look up again to see if the VFS was loaded. */ + vfsp = vfs_byname(fstype); + if (vfsp == NULL) { + lf->userrefs--; + linker_file_unload(lf, LINKER_UNLOAD_FORCE); + *error = ENODEV; + return (NULL); + } + return (vfsp); +} + + /* Register a new filesystem type in the global table */ int vfs_register(struct vfsconf *vfc) diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 0211de3..e93790f 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -66,7 +66,6 @@ __FBSDID("$FreeBSD$"); #include <sys/cons.h> #include <sys/jail.h> #include <sys/kernel.h> -#include <sys/linker.h> #include <sys/mac.h> #include <sys/malloc.h> #include <sys/mount.h> @@ -669,7 +668,6 @@ vfs_domount( int compat /* Invocation from compat syscall. */ ) { - linker_file_t lf; struct vnode *vp; struct mount *mp; struct vfsconf *vfsp; @@ -786,34 +784,10 @@ vfs_domount( vput(vp); return (ENOTDIR); } - vfsp = vfs_byname(fstype); + vfsp = vfs_byname_kld(fstype, td, &error); if (vfsp == NULL) { - /* Only load modules for root (very important!). */ - if ((error = suser(td)) != 0) { - vput(vp); - return (error); - } - error = securelevel_gt(td->td_ucred, 0); - if (error) { - vput(vp); - return (error); - } - error = linker_load_module(NULL, fstype, NULL, NULL, &lf); - if (error || lf == NULL) { - vput(vp); - if (lf == NULL) - error = ENODEV; - return (error); - } - lf->userrefs++; - /* Look up again to see if the VFS was loaded. */ - vfsp = vfs_byname(fstype); - if (vfsp == NULL) { - lf->userrefs--; - linker_file_unload(lf, LINKER_UNLOAD_FORCE); - vput(vp); - return (ENODEV); - } + vput(vp); + return (error); } VI_LOCK(vp); if ((vp->v_iflag & VI_MOUNT) != 0 || diff --git a/sys/sys/mount.h b/sys/sys/mount.h index 237ba6b..930948c 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -564,6 +564,7 @@ int dounmount(struct mount *, int, struct thread *); int kernel_mount(struct iovec *, u_int, int); int kernel_vmount(int flags, ...); struct vfsconf *vfs_byname(const char *); +struct vfsconf *vfs_byname_kld(const char *, struct thread *td, int *); void vfs_event_signal(fsid_t *, u_int32_t, intptr_t); int vfs_getopt(struct vfsoptlist *, const char *, void **, int *); int vfs_copyopt(struct vfsoptlist *, const char *, void *, int); |