fuse: don't assume ff->passthrough is set for FOPEN_PASSTHROUGH

Following patch will introduce extent map passthrough mode, where
ff->passthrough is not set.

Check if in passthrough mode via FOPEN_PASSTHROUGH instead.

No functional change.

Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
Miklos Szeredi 2026-09-21 14:05:45 +02:00
parent b6397651e5
commit bbe2d73a82
3 changed files with 20 additions and 15 deletions

View File

@ -311,7 +311,7 @@ static void fuse_prepare_release(struct fuse_inode *fi, struct fuse_file *ff,
struct fuse_conn *fc = ff->fm->fc;
struct fuse_release_args *ra = &ff->args->release_args;
if (fuse_file_passthrough(ff))
if (fuse_is_passthrough(ff))
fuse_passthrough_release(ff, fuse_inode_backing(fi));
/* Inode is NULL on error path of fuse_create_open() */
@ -1862,7 +1862,7 @@ static ssize_t fuse_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
/* FOPEN_DIRECT_IO overrides FOPEN_PASSTHROUGH */
if (ff->open_flags & FOPEN_DIRECT_IO)
return fuse_direct_read_iter(iocb, to);
else if (fuse_file_passthrough(ff))
else if (fuse_is_passthrough(ff))
return fuse_passthrough_read_iter(iocb, to);
else
return fuse_cache_read_iter(iocb, to);
@ -1883,7 +1883,7 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
/* FOPEN_DIRECT_IO overrides FOPEN_PASSTHROUGH */
if (ff->open_flags & FOPEN_DIRECT_IO)
return fuse_direct_write_iter(iocb, from);
else if (fuse_file_passthrough(ff))
else if (fuse_is_passthrough(ff))
return fuse_passthrough_write_iter(iocb, from);
else
return fuse_cache_write_iter(iocb, from);
@ -1899,7 +1899,7 @@ static ssize_t fuse_splice_read(struct file *in, loff_t *ppos,
if (ff->open_flags & FOPEN_DIRECT_IO)
return copy_splice_read(in, ppos, pipe, len, flags);
else if (fuse_file_passthrough(ff))
else if (fuse_is_passthrough(ff))
return fuse_passthrough_splice_read(in, ppos, pipe, len, flags);
else
return filemap_splice_read(in, ppos, pipe, len, flags);
@ -1911,7 +1911,7 @@ static ssize_t fuse_splice_write(struct pipe_inode_info *pipe, struct file *out,
struct fuse_file *ff = out->private_data;
/* FOPEN_DIRECT_IO overrides FOPEN_PASSTHROUGH */
if (fuse_file_passthrough(ff) && !(ff->open_flags & FOPEN_DIRECT_IO))
if (fuse_is_passthrough(ff) && !(ff->open_flags & FOPEN_DIRECT_IO))
return fuse_passthrough_splice_write(pipe, out, ppos, len, flags);
else
return iter_file_splice_write(pipe, out, ppos, len, flags);
@ -2426,7 +2426,7 @@ static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma)
* in passthrough mode, either mmap to backing file or fail mmap,
* because mixing cached mmap and passthrough io mode is not allowed.
*/
if (fuse_file_passthrough(ff))
if (fuse_is_passthrough(ff))
return fuse_passthrough_mmap(file, vma);
else if (fuse_inode_backing(get_fuse_inode(inode)))
return -ENODEV;

View File

@ -1313,13 +1313,9 @@ static inline struct fuse_backing *fuse_inode_backing_set(struct fuse_inode *fi,
struct fuse_backing *fuse_passthrough_open(struct file *file, int backing_id);
void fuse_passthrough_release(struct fuse_file *ff, struct fuse_backing *fb);
static inline struct file *fuse_file_passthrough(struct fuse_file *ff)
static inline bool fuse_is_passthrough(struct fuse_file *ff)
{
#ifdef CONFIG_FUSE_PASSTHROUGH
return ff->passthrough;
#else
return NULL;
#endif
return IS_ENABLED(CONFIG_FUSE_PASSTHROUGH) && (ff->open_flags & FOPEN_PASSTHROUGH);
}
ssize_t fuse_passthrough_read_iter(struct kiocb *iocb, struct iov_iter *iter);

View File

@ -11,6 +11,10 @@
#include <linux/backing-file.h>
#include <linux/splice.h>
static inline struct file *fuse_file_passthrough(struct fuse_file *ff)
{
return ff->passthrough;
}
static void fuse_file_accessed(struct file *file)
{
struct inode *inode = file_inode(file);
@ -187,10 +191,15 @@ struct fuse_backing *fuse_passthrough_open(struct file *file, int backing_id)
void fuse_passthrough_release(struct fuse_file *ff, struct fuse_backing *fb)
{
pr_debug("%s: fb=0x%p, backing_file=0x%p\n", __func__,
fb, ff->passthrough);
struct file *backing_file = fuse_file_passthrough(ff);
fput(ff->passthrough);
pr_debug("%s: fb=0x%p, backing_file=0x%p\n", __func__,
fb, backing_file);
if (!backing_file)
return;
fput(backing_file);
ff->passthrough = NULL;
put_cred(ff->cred);
ff->cred = NULL;