From bbe2d73a8231d20f3671d30f8c0045d6c0022b9d Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Mon, 21 Sep 2026 14:05:45 +0200 Subject: [PATCH] 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 Signed-off-by: Miklos Szeredi --- fs/fuse/file.c | 12 ++++++------ fs/fuse/fuse_i.h | 8 ++------ fs/fuse/passthrough.c | 15 ++++++++++++--- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index eeda31cd8afd..6d707f2b3bff 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -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; diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 5a2e31b8a7b6..6af2603b522a 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -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); diff --git a/fs/fuse/passthrough.c b/fs/fuse/passthrough.c index f2d08ac2459b..b43d3e0f7081 100644 --- a/fs/fuse/passthrough.c +++ b/fs/fuse/passthrough.c @@ -11,6 +11,10 @@ #include #include +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;