diff options
author | Amir Goldstein <amir73il@gmail.com> | 2024-02-09 17:14:50 +0200 |
---|---|---|
committer | Miklos Szeredi <mszeredi@redhat.com> | 2024-03-05 13:40:42 +0100 |
commit | 4a90451bbc7f7fde94041fbb9ca96dd915069943 (patch) | |
tree | cc15dfbe11bae5fade8742be0732ca0a3e8bf7fa /fs/fuse/file.c | |
parent | fc8ff397b2a91590031ae08534de627f957005cb (diff) |
fuse: implement open in passthrough mode
After getting a backing file id with FUSE_DEV_IOC_BACKING_OPEN ioctl,
a FUSE server can reply to an OPEN request with flag FOPEN_PASSTHROUGH
and the backing file id.
The FUSE server should reuse the same backing file id for all the open
replies of the same FUSE inode and open will fail (with -EIO) if a the
server attempts to open the same inode with conflicting io modes or to
setup passthrough to two different backing files for the same FUSE inode.
Using the same backing file id for several different inodes is allowed.
Opening a new file with FOPEN_DIRECT_IO for an inode that is already
open for passthrough is allowed, but only if the FOPEN_PASSTHROUGH flag
and correct backing file id are specified as well.
The read/write IO of such files will not use passthrough operations to
the backing file, but mmap, which does not support direct_io, will use
the backing file insead of using the page cache as it always did.
Even though all FUSE passthrough files of the same inode use the same
backing file as a backing inode reference, each FUSE file opens a unique
instance of a backing_file object to store the FUSE path that was used
to open the inode and the open flags of the specific open file.
The per-file, backing_file object is released along with the FUSE file.
The inode associated fuse_backing object is released when the last FUSE
passthrough file of that inode is released AND when the backing file id
is closed by the server using the FUSE_DEV_IOC_BACKING_CLOSE ioctl.
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/fuse/file.c')
-rw-r--r-- | fs/fuse/file.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 47c1ecab7b5c..6fad381f3beb 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -295,6 +295,9 @@ 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)) + fuse_passthrough_release(ff, fuse_inode_backing(fi)); + /* Inode is NULL on error path of fuse_create_open() */ if (likely(fi)) { spin_lock(&fi->lock); @@ -1374,7 +1377,7 @@ static void fuse_dio_lock(struct kiocb *iocb, struct iov_iter *from, * have raced, so check it again. */ if (fuse_io_past_eof(iocb, from) || - fuse_file_uncached_io_start(inode, ff) != 0) { + fuse_file_uncached_io_start(inode, ff, NULL) != 0) { inode_unlock_shared(inode); inode_lock(inode); *exclusive = true; @@ -2527,6 +2530,10 @@ static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma) if (FUSE_IS_DAX(file_inode(file))) return fuse_dax_mmap(file, vma); + /* TODO: implement mmap to backing file */ + if (fuse_file_passthrough(ff)) + return -ENODEV; + /* * FOPEN_DIRECT_IO handling is special compared to O_DIRECT, * as does not allow MAP_SHARED mmap without FUSE_DIRECT_IO_ALLOW_MMAP. |