diff options
author | Poul-Henning Kamp <phk@FreeBSD.org> | 2004-12-03 16:11:01 +0000 |
---|---|---|
committer | Poul-Henning Kamp <phk@FreeBSD.org> | 2004-12-03 16:11:01 +0000 |
commit | 32ba8e9390deffc1ac129850f212ef4cba235d24 (patch) | |
tree | 30bd6d7172cef8231afb2c63fa0086cfad3689d3 /sys/kern/vfs_init.c | |
parent | b4c6be32549ed5a82ce065222403d8e0e0727b91 (diff) | |
download | src-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.c | 37 |
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) |