aboutsummaryrefslogtreecommitdiff
path: root/sys/fs/fuse
diff options
context:
space:
mode:
Diffstat (limited to 'sys/fs/fuse')
-rw-r--r--sys/fs/fuse/fuse_device.c9
-rw-r--r--sys/fs/fuse/fuse_internal.c5
-rw-r--r--sys/fs/fuse/fuse_ipc.c6
-rw-r--r--sys/fs/fuse/fuse_ipc.h1
-rw-r--r--sys/fs/fuse/fuse_vfsops.c4
-rw-r--r--sys/fs/fuse/fuse_vnops.c28
6 files changed, 34 insertions, 19 deletions
diff --git a/sys/fs/fuse/fuse_device.c b/sys/fs/fuse/fuse_device.c
index 57b3559731f7..cee477865c42 100644
--- a/sys/fs/fuse/fuse_device.c
+++ b/sys/fs/fuse/fuse_device.c
@@ -126,11 +126,13 @@ static const struct filterops fuse_device_rfiltops = {
.f_isfd = 1,
.f_detach = fuse_device_filt_detach,
.f_event = fuse_device_filt_read,
+ .f_copy = knote_triv_copy,
};
static const struct filterops fuse_device_wfiltops = {
.f_isfd = 1,
.f_event = fuse_device_filt_write,
+ .f_copy = knote_triv_copy,
};
/****************************
@@ -548,6 +550,13 @@ fuse_device_write(struct cdev *dev, struct uio *uio, int ioflag)
} else if (ohead.unique == 0){
/* unique == 0 means asynchronous notification */
SDT_PROBE1(fusefs, , device, fuse_device_write_notify, &ohead);
+ if (data->mp == NULL) {
+ SDT_PROBE2(fusefs, , device, trace, 1,
+ "asynchronous notification before mount"
+ " or after unmount");
+ return (EXTERROR(ENODEV,
+ "This FUSE session is not mounted"));
+ }
mp = data->mp;
vfs_ref(mp);
err = vfs_busy(mp, 0);
diff --git a/sys/fs/fuse/fuse_internal.c b/sys/fs/fuse/fuse_internal.c
index 61fe2ed032f6..eba0a8a79ff3 100644
--- a/sys/fs/fuse/fuse_internal.c
+++ b/sys/fs/fuse/fuse_internal.c
@@ -1063,6 +1063,8 @@ fuse_internal_init_callback(struct fuse_ticket *tick, struct uio *uio)
if (!fuse_libabi_geq(data, 7, 28))
fsess_set_notimpl(data->mp, FUSE_COPY_FILE_RANGE);
+ if (fuse_libabi_geq(data, 7, 33) && (fiio->flags & FUSE_SETXATTR_EXT))
+ data->dataflags |= FSESS_SETXATTR_EXT;
out:
if (err) {
fdata_set_dead(data);
@@ -1115,7 +1117,8 @@ fuse_internal_send_init(struct fuse_data *data, struct thread *td)
*/
fiii->flags = FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_EXPORT_SUPPORT
| FUSE_BIG_WRITES | FUSE_WRITEBACK_CACHE
- | FUSE_NO_OPEN_SUPPORT | FUSE_NO_OPENDIR_SUPPORT;
+ | FUSE_NO_OPEN_SUPPORT | FUSE_NO_OPENDIR_SUPPORT
+ | FUSE_SETXATTR_EXT;
fuse_insert_callback(fdi.tick, fuse_internal_init_callback);
fuse_insert_message(fdi.tick, false);
diff --git a/sys/fs/fuse/fuse_ipc.c b/sys/fs/fuse/fuse_ipc.c
index a751c09159ff..bc36f0070d7d 100644
--- a/sys/fs/fuse/fuse_ipc.c
+++ b/sys/fs/fuse/fuse_ipc.c
@@ -193,7 +193,6 @@ fuse_interrupt_send(struct fuse_ticket *otick, int err)
struct fuse_data *data = otick->tk_data;
struct fuse_ticket *tick, *xtick;
struct ucred reused_creds;
- gid_t reused_groups[1];
if (otick->irq_unique == 0) {
/*
@@ -237,8 +236,7 @@ fuse_interrupt_send(struct fuse_ticket *otick, int err)
*/
ftick_hdr = fticket_in_header(otick);
reused_creds.cr_uid = ftick_hdr->uid;
- reused_groups[0] = ftick_hdr->gid;
- reused_creds.cr_groups = reused_groups;
+ reused_creds.cr_gid = ftick_hdr->gid;
fdisp_init(&fdi, sizeof(*fii));
fdisp_make_pid(&fdi, FUSE_INTERRUPT, data, ftick_hdr->nodeid,
ftick_hdr->pid, &reused_creds);
@@ -696,7 +694,7 @@ fuse_body_audit(struct fuse_ticket *ftick, size_t blen)
break;
case FUSE_FORGET:
- panic("FUSE: a handler has been intalled for FUSE_FORGET");
+ panic("FUSE: a handler has been installed for FUSE_FORGET");
break;
case FUSE_GETATTR:
diff --git a/sys/fs/fuse/fuse_ipc.h b/sys/fs/fuse/fuse_ipc.h
index 3bfc859dbac9..d9d79f38c269 100644
--- a/sys/fs/fuse/fuse_ipc.h
+++ b/sys/fs/fuse/fuse_ipc.h
@@ -243,6 +243,7 @@ struct fuse_data {
#define FSESS_MNTOPTS_MASK ( \
FSESS_DAEMON_CAN_SPY | FSESS_PUSH_SYMLINKS_IN | \
FSESS_DEFAULT_PERMISSIONS | FSESS_INTR)
+#define FSESS_SETXATTR_EXT 0x8000000 /* extended fuse_setxattr_in */
extern int fuse_data_cache_mode;
diff --git a/sys/fs/fuse/fuse_vfsops.c b/sys/fs/fuse/fuse_vfsops.c
index 1b858a988289..b617925c4e5f 100644
--- a/sys/fs/fuse/fuse_vfsops.c
+++ b/sys/fs/fuse/fuse_vfsops.c
@@ -278,13 +278,13 @@ fuse_vfsop_fhtovp(struct mount *mp, struct fid *fhp, int flags,
error = VFS_VGET(mp, ffhp->nid, LK_EXCLUSIVE, &nvp);
if (error) {
- *vpp = NULLVP;
+ *vpp = NULL;
return (error);
}
fvdat = VTOFUD(nvp);
if (fvdat->generation != ffhp->gen ) {
vput(nvp);
- *vpp = NULLVP;
+ *vpp = NULL;
return (ESTALE);
}
*vpp = nvp;
diff --git a/sys/fs/fuse/fuse_vnops.c b/sys/fs/fuse/fuse_vnops.c
index de60a4717dd4..ef5aee5de34c 100644
--- a/sys/fs/fuse/fuse_vnops.c
+++ b/sys/fs/fuse/fuse_vnops.c
@@ -284,7 +284,7 @@ fuse_flush(struct vnode *vp, struct ucred *cred, pid_t pid, int fflag)
struct mount *mp = vnode_mount(vp);
int err;
- if (fsess_not_impl(vnode_mount(vp), FUSE_FLUSH))
+ if (fsess_not_impl(mp, FUSE_FLUSH))
return 0;
err = fuse_filehandle_getrw(vp, fflag, &fufh, cred, pid);
@@ -292,7 +292,7 @@ fuse_flush(struct vnode *vp, struct ucred *cred, pid_t pid, int fflag)
return err;
if (fufh->fuse_open_flags & FOPEN_NOFLUSH &&
- (!fsess_opt_writeback(vnode_mount(vp))))
+ (!fsess_opt_writeback(mp)))
return (0);
fdisp_init(&fdi, sizeof(*ffi));
@@ -625,7 +625,7 @@ fuse_vnop_allocate(struct vop_allocate_args *ap)
return (EROFS);
if (fsess_not_impl(mp, FUSE_FALLOCATE))
- return (EXTERROR(EINVAL, "This server does not implement "
+ return (EXTERROR(EOPNOTSUPP, "This server does not implement "
"FUSE_FALLOCATE"));
io.uio_offset = *offset;
@@ -656,14 +656,14 @@ fuse_vnop_allocate(struct vop_allocate_args *ap)
if (err == ENOSYS) {
fsess_set_notimpl(mp, FUSE_FALLOCATE);
- err = EXTERROR(EINVAL, "This server does not implement "
+ err = EXTERROR(EOPNOTSUPP, "This server does not implement "
"FUSE_ALLOCATE");
} else if (err == EOPNOTSUPP) {
/*
* The file system server does not support FUSE_FALLOCATE with
* the supplied mode for this particular file.
*/
- err = EXTERROR(EINVAL, "This file can't be pre-allocated");
+ err = EXTERROR(EOPNOTSUPP, "This file can't be pre-allocated");
} else if (!err) {
*offset += *len;
*len = 0;
@@ -795,11 +795,15 @@ fuse_vnop_close(struct vop_close_args *ap)
struct mount *mp = vnode_mount(vp);
struct ucred *cred = ap->a_cred;
int fflag = ap->a_fflag;
- struct thread *td = ap->a_td;
- pid_t pid = td->td_proc->p_pid;
+ struct thread *td;
struct fuse_vnode_data *fvdat = VTOFUD(vp);
+ pid_t pid;
int err = 0;
+ /* NB: a_td will be NULL from some async kernel contexts */
+ td = ap->a_td ? ap->a_td : curthread;
+ pid = td->td_proc->p_pid;
+
if (fuse_isdeadfs(vp))
return 0;
if (vnode_isdir(vp))
@@ -838,7 +842,7 @@ fuse_vnop_close(struct vop_close_args *ap)
}
/* TODO: close the file handle, if we're sure it's no longer used */
if ((fvdat->flag & FN_SIZECHANGE) != 0) {
- fuse_vnode_savesize(vp, cred, td->td_proc->p_pid);
+ fuse_vnode_savesize(vp, cred, pid);
}
return err;
}
@@ -953,7 +957,7 @@ fuse_vnop_copy_file_range(struct vop_copy_file_range_args *ap)
*ap->a_outoffp += fwo->size;
fuse_internal_clear_suid_on_write(outvp, outcred, td);
if (*ap->a_outoffp > outfvdat->cached_attrs.va_size) {
- fuse_vnode_setsize(outvp, *ap->a_outoffp, false);
+ fuse_vnode_setsize(outvp, *ap->a_outoffp, false);
getnanouptime(&outfvdat->last_local_modify);
}
fuse_vnode_update(invp, FN_ATIMECHANGE);
@@ -2752,7 +2756,7 @@ fuse_vnop_setextattr(struct vop_setextattr_args *ap)
*/
if (fsess_not_impl(mp, FUSE_REMOVEXATTR))
return (EXTERROR(EOPNOTSUPP, "This server does not "
- "implement removing extended attributess"));
+ "implement removing extended attributes"));
else
return (EXTERROR(EINVAL, "DELETEEXTATTR should be used "
"to remove extattrs"));
@@ -2773,7 +2777,7 @@ fuse_vnop_setextattr(struct vop_setextattr_args *ap)
strlen(ap->a_name) + 1;
/* older FUSE servers use a smaller fuse_setxattr_in struct*/
- if (fuse_libabi_geq(fuse_get_mpdata(mp), 7, 33))
+ if (fuse_get_mpdata(mp)->dataflags & FSESS_SETXATTR_EXT)
struct_size = sizeof(*set_xattr_in);
fdisp_init(&fdi, len + struct_size + uio->uio_resid);
@@ -2782,7 +2786,7 @@ fuse_vnop_setextattr(struct vop_setextattr_args *ap)
set_xattr_in = fdi.indata;
set_xattr_in->size = uio->uio_resid;
- if (fuse_libabi_geq(fuse_get_mpdata(mp), 7, 33)) {
+ if (fuse_get_mpdata(mp)->dataflags & FSESS_SETXATTR_EXT) {
set_xattr_in->setxattr_flags = 0;
set_xattr_in->padding = 0;
}