summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/vfs_init.c37
-rw-r--r--sys/kern/vfs_mount.c32
-rw-r--r--sys/sys/mount.h1
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);
OpenPOWER on IntegriCloud