diff options
author | phk <phk@FreeBSD.org> | 2004-12-03 16:11:01 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2004-12-03 16:11:01 +0000 |
commit | 0381adc1dfeae50004ddf3f91f8e2f29d1c8f805 (patch) | |
tree | 30bd6d7172cef8231afb2c63fa0086cfad3689d3 /sys/kern/vfs_init.c | |
parent | 181d4dfad71dede70194d972dd42b816372b0fe6 (diff) | |
download | FreeBSD-src-0381adc1dfeae50004ddf3f91f8e2f29d1c8f805.zip FreeBSD-src-0381adc1dfeae50004ddf3f91f8e2f29d1c8f805.tar.gz |
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.
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 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) |