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:
parent
b4c6be3254
commit
32ba8e9390
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=138350
@ -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)
|
||||
|
@ -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 ||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user