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.
This commit is contained in:
Poul-Henning Kamp 2004-12-03 16:11:01 +00:00
parent b4c6be3254
commit 32ba8e9390
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=138350
3 changed files with 41 additions and 29 deletions

View File

@ -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)

View File

@ -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 ||

View File

@ -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);