aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/vfs_init.c
diff options
context:
space:
mode:
authorPoul-Henning Kamp <phk@FreeBSD.org>2004-12-03 16:11:01 +0000
committerPoul-Henning Kamp <phk@FreeBSD.org>2004-12-03 16:11:01 +0000
commit32ba8e9390deffc1ac129850f212ef4cba235d24 (patch)
tree30bd6d7172cef8231afb2c63fa0086cfad3689d3 /sys/kern/vfs_init.c
parentb4c6be32549ed5a82ce065222403d8e0e0727b91 (diff)
downloadsrc-32ba8e9390deffc1ac129850f212ef4cba235d24.tar.gz
src-32ba8e9390deffc1ac129850f212ef4cba235d24.zip
Introduce vfs_byname_kld() which will try to load the filesystem
as a module if possible. Use it so we don't have linker magic in the middle of the already complex mount code.
Notes
Notes: svn path=/head/; revision=138350
Diffstat (limited to 'sys/kern/vfs_init.c')
-rw-r--r--sys/kern/vfs_init.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c
index 343f5f76f54f..1b1e419cb55a 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)