Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/fuse/fuse_vfsops.c
Show First 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | |||||
#include <sys/sx.h> | #include <sys/sx.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/vnode.h> | #include <sys/vnode.h> | ||||
#include <sys/namei.h> | #include <sys/namei.h> | ||||
#include <sys/mount.h> | #include <sys/mount.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/fcntl.h> | #include <sys/fcntl.h> | ||||
#include <sys/sglist.h> | |||||
#include "fuse.h" | #include "fuse.h" | ||||
#include "fuse_node.h" | #include "fuse_node.h" | ||||
#include "fuse_ipc.h" | #include "fuse_ipc.h" | ||||
#include "fuse_internal.h" | #include "fuse_internal.h" | ||||
#include "fuse_vfsops.h" | |||||
#include <sys/priv.h> | #include <sys/priv.h> | ||||
#include <security/mac/mac_framework.h> | #include <security/mac/mac_framework.h> | ||||
#include <dev/virtio/fs/virtio_fs.h> | |||||
SDT_PROVIDER_DECLARE(fusefs); | SDT_PROVIDER_DECLARE(fusefs); | ||||
/* | /* | ||||
* Fuse trace probe: | * Fuse trace probe: | ||||
* arg0: verbosity. Higher numbers give more verbose messages | * arg0: verbosity. Higher numbers give more verbose messages | ||||
* arg1: Textual message | * arg1: Textual message | ||||
*/ | */ | ||||
SDT_PROBE_DEFINE2(fusefs, , vfsops, trace, "int", "char*"); | SDT_PROBE_DEFINE2(fusefs, , vfsops, trace, "int", "char*"); | ||||
/* This will do for privilege types for now */ | /* This will do for privilege types for now */ | ||||
#ifndef PRIV_VFS_FUSE_ALLOWOTHER | #ifndef PRIV_VFS_FUSE_ALLOWOTHER | ||||
#define PRIV_VFS_FUSE_ALLOWOTHER PRIV_VFS_MOUNT_NONUSER | #define PRIV_VFS_FUSE_ALLOWOTHER PRIV_VFS_MOUNT_NONUSER | ||||
#endif | #endif | ||||
#ifndef PRIV_VFS_FUSE_MOUNT_NONUSER | #ifndef PRIV_VFS_FUSE_MOUNT_NONUSER | ||||
#define PRIV_VFS_FUSE_MOUNT_NONUSER PRIV_VFS_MOUNT_NONUSER | #define PRIV_VFS_FUSE_MOUNT_NONUSER PRIV_VFS_MOUNT_NONUSER | ||||
#endif | #endif | ||||
#ifndef PRIV_VFS_FUSE_SYNC_UNMOUNT | #ifndef PRIV_VFS_FUSE_SYNC_UNMOUNT | ||||
#define PRIV_VFS_FUSE_SYNC_UNMOUNT PRIV_VFS_MOUNT_NONUSER | #define PRIV_VFS_FUSE_SYNC_UNMOUNT PRIV_VFS_MOUNT_NONUSER | ||||
#endif | #endif | ||||
static vfs_fhtovp_t fuse_vfsop_fhtovp; | |||||
static vfs_mount_t fuse_vfsop_mount; | |||||
static vfs_unmount_t fuse_vfsop_unmount; | |||||
static vfs_root_t fuse_vfsop_root; | |||||
static vfs_statfs_t fuse_vfsop_statfs; | |||||
static vfs_vget_t fuse_vfsop_vget; | |||||
struct vfsops fuse_vfsops = { | struct vfsops fuse_vfsops = { | ||||
.vfs_fhtovp = fuse_vfsop_fhtovp, | .vfs_fhtovp = fuse_vfsop_fhtovp, | ||||
.vfs_mount = fuse_vfsop_mount, | .vfs_mount = fuse_vfsop_mount, | ||||
.vfs_unmount = fuse_vfsop_unmount, | .vfs_unmount = fuse_vfsop_unmount, | ||||
.vfs_root = fuse_vfsop_root, | .vfs_root = fuse_vfsop_root, | ||||
.vfs_statfs = fuse_vfsop_statfs, | .vfs_statfs = fuse_vfsop_statfs, | ||||
.vfs_vget = fuse_vfsop_vget, | .vfs_vget = fuse_vfsop_vget, | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 130 Lines • ▼ Show 20 Lines | if (err == 0 && td->td_ucred->cr_uid != data->daemoncred->cr_uid) | ||||
/* are we allowed to do the first mount? */ | /* are we allowed to do the first mount? */ | ||||
err = priv_check(td, PRIV_VFS_FUSE_MOUNT_NONUSER); | err = priv_check(td, PRIV_VFS_FUSE_MOUNT_NONUSER); | ||||
out: | out: | ||||
FUSE_UNLOCK(); | FUSE_UNLOCK(); | ||||
return err; | return err; | ||||
} | } | ||||
static int | int | ||||
fuse_vfsop_fhtovp(struct mount *mp, struct fid *fhp, int flags, | fuse_vfsop_fhtovp(struct mount *mp, struct fid *fhp, int flags, | ||||
struct vnode **vpp) | struct vnode **vpp) | ||||
{ | { | ||||
struct fuse_fid *ffhp = (struct fuse_fid *)fhp; | struct fuse_fid *ffhp = (struct fuse_fid *)fhp; | ||||
struct fuse_vnode_data *fvdat; | struct fuse_vnode_data *fvdat; | ||||
struct vnode *nvp; | struct vnode *nvp; | ||||
int error; | int error; | ||||
Show All 11 Lines | if (fvdat->generation != ffhp->gen ) { | ||||
*vpp = NULLVP; | *vpp = NULLVP; | ||||
return (ESTALE); | return (ESTALE); | ||||
} | } | ||||
*vpp = nvp; | *vpp = nvp; | ||||
vnode_create_vobject(*vpp, VNODE_NO_SIZE, curthread); | vnode_create_vobject(*vpp, VNODE_NO_SIZE, curthread); | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | int | ||||
fuse_vfsop_mount(struct mount *mp) | fuse_vfsop_mount(struct mount *mp) | ||||
{ | { | ||||
int err; | int err; | ||||
uint64_t mntopts, __mntopts; | uint64_t mntopts, __mntopts; | ||||
uint32_t max_read; | uint32_t max_read; | ||||
int linux_errnos; | int linux_errnos; | ||||
int daemon_timeout; | int daemon_timeout; | ||||
▲ Show 20 Lines • Show All 159 Lines • ▼ Show 20 Lines | if (data != NULL && data->mp == mp) { | ||||
fdata_trydestroy(data); | fdata_trydestroy(data); | ||||
} | } | ||||
FUSE_UNLOCK(); | FUSE_UNLOCK(); | ||||
dev_rel(fdev); | dev_rel(fdev); | ||||
} | } | ||||
return err; | return err; | ||||
} | } | ||||
static int | int | ||||
fuse_vfsop_unmount(struct mount *mp, int mntflags) | fuse_vfsop_unmount(struct mount *mp, int mntflags) | ||||
{ | { | ||||
int err = 0; | int err = 0; | ||||
int flags = 0; | int flags = 0; | ||||
struct cdev *fdev; | struct cdev *fdev; | ||||
struct fuse_data *data; | struct fuse_data *data; | ||||
struct fuse_dispatcher fdi; | struct fuse_dispatcher fdi; | ||||
Show All 26 Lines | fuse_vfsop_unmount(struct mount *mp, int mntflags) | ||||
if (fsess_maybe_impl(mp, FUSE_DESTROY)) { | if (fsess_maybe_impl(mp, FUSE_DESTROY)) { | ||||
fdisp_init(&fdi, 0); | fdisp_init(&fdi, 0); | ||||
fdisp_make(&fdi, FUSE_DESTROY, mp, 0, td, NULL); | fdisp_make(&fdi, FUSE_DESTROY, mp, 0, td, NULL); | ||||
(void)fdisp_wait_answ(&fdi); | (void)fdisp_wait_answ(&fdi); | ||||
fdisp_destroy(&fdi); | fdisp_destroy(&fdi); | ||||
} | } | ||||
if (fsess_get_virtiofs(data)) | |||||
data->virtiofs_unmount_cb((void *)data); | |||||
else | |||||
fdata_set_dead(data); | fdata_set_dead(data); | ||||
alreadydead: | alreadydead: | ||||
FUSE_LOCK(); | FUSE_LOCK(); | ||||
data->mp = NULL; | data->mp = NULL; | ||||
fdev = data->fdev; | fdev = data->fdev; | ||||
fdata_trydestroy(data); | fdata_trydestroy(data); | ||||
FUSE_UNLOCK(); | FUSE_UNLOCK(); | ||||
MNT_ILOCK(mp); | MNT_ILOCK(mp); | ||||
mp->mnt_data = NULL; | mp->mnt_data = NULL; | ||||
MNT_IUNLOCK(mp); | MNT_IUNLOCK(mp); | ||||
if (fdev != NULL) | |||||
dev_rel(fdev); | dev_rel(fdev); | ||||
return 0; | return 0; | ||||
} | } | ||||
SDT_PROBE_DEFINE1(fusefs, , vfsops, invalidate_without_export, | SDT_PROBE_DEFINE1(fusefs, , vfsops, invalidate_without_export, | ||||
"struct mount*"); | "struct mount*"); | ||||
static int | int | ||||
fuse_vfsop_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp) | fuse_vfsop_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp) | ||||
{ | { | ||||
struct fuse_data *data = fuse_get_mpdata(mp); | struct fuse_data *data = fuse_get_mpdata(mp); | ||||
uint64_t nodeid = ino; | uint64_t nodeid = ino; | ||||
struct thread *td = curthread; | struct thread *td = curthread; | ||||
struct fuse_dispatcher fdi; | struct fuse_dispatcher fdi; | ||||
struct fuse_entry_out *feo; | struct fuse_entry_out *feo; | ||||
struct fuse_vnode_data *fvdat; | struct fuse_vnode_data *fvdat; | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | fuse_vfsop_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp) | ||||
} | } | ||||
fuse_validity_2_bintime(feo->entry_valid, feo->entry_valid_nsec, | fuse_validity_2_bintime(feo->entry_valid, feo->entry_valid_nsec, | ||||
&fvdat->entry_cache_timeout); | &fvdat->entry_cache_timeout); | ||||
out: | out: | ||||
fdisp_destroy(&fdi); | fdisp_destroy(&fdi); | ||||
return error; | return error; | ||||
} | } | ||||
static int | int | ||||
fuse_vfsop_root(struct mount *mp, int lkflags, struct vnode **vpp) | fuse_vfsop_root(struct mount *mp, int lkflags, struct vnode **vpp) | ||||
{ | { | ||||
struct fuse_data *data = fuse_get_mpdata(mp); | struct fuse_data *data = fuse_get_mpdata(mp); | ||||
int err = 0; | int err = 0; | ||||
if (data->vroot != NULL) { | if (data->vroot != NULL) { | ||||
err = vget(data->vroot, lkflags); | err = vget(data->vroot, lkflags); | ||||
if (err == 0) | if (err == 0) | ||||
Show All 19 Lines | if (err == 0) { | ||||
*vpp = data->vroot; | *vpp = data->vroot; | ||||
} else | } else | ||||
FUSE_UNLOCK(); | FUSE_UNLOCK(); | ||||
} | } | ||||
} | } | ||||
return err; | return err; | ||||
} | } | ||||
static int | int | ||||
fuse_vfsop_statfs(struct mount *mp, struct statfs *sbp) | fuse_vfsop_statfs(struct mount *mp, struct statfs *sbp) | ||||
{ | { | ||||
struct fuse_dispatcher fdi; | struct fuse_dispatcher fdi; | ||||
int err = 0; | int err = 0; | ||||
struct fuse_statfs_out *fsfo; | struct fuse_statfs_out *fsfo; | ||||
struct fuse_data *data; | struct fuse_data *data; | ||||
▲ Show 20 Lines • Show All 44 Lines • Show Last 20 Lines |