diff options
author | Amir Goldstein <amir73il@gmail.com> | 2024-02-09 17:03:55 +0200 |
---|---|---|
committer | Miklos Szeredi <mszeredi@redhat.com> | 2024-03-05 13:40:42 +0100 |
commit | fc8ff397b2a91590031ae08534de627f957005cb (patch) | |
tree | 75eccaa695f54d036602532bf38b1b9911434394 /fs/fuse/dir.c | |
parent | 44350256ab943d424d70aa60a34f45060b3a36e8 (diff) | |
download | linux-fc8ff397b2a91590031ae08534de627f957005cb.tar.gz linux-fc8ff397b2a91590031ae08534de627f957005cb.tar.bz2 linux-fc8ff397b2a91590031ae08534de627f957005cb.zip |
fuse: prepare for opening file in passthrough mode
In preparation for opening file in passthrough mode, store the
fuse_open_out argument in ff->args to be passed into fuse_file_io_open()
with the optional backing_id member.
This will be used for setting up passthrough to backing file on open
reply with FOPEN_PASSTHROUGH flag and a valid backing_id.
Opening a file in passthrough mode may fail for several reasons, such as
missing capability, conflicting open flags or inode in caching mode.
Return EIO from fuse_file_io_open() in those cases.
The combination of FOPEN_PASSTHROUGH and FOPEN_DIRECT_IO is allowed -
it mean that read/write operations will go directly to the server,
but mmap will be done to the backing file.
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/fuse/dir.c')
-rw-r--r-- | fs/fuse/dir.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 1225df59d9b7..25c7c97f774b 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -615,7 +615,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, FUSE_ARGS(args); struct fuse_forget_link *forget; struct fuse_create_in inarg; - struct fuse_open_out outopen; + struct fuse_open_out *outopenp; struct fuse_entry_out outentry; struct fuse_inode *fi; struct fuse_file *ff; @@ -659,8 +659,10 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, args.out_numargs = 2; args.out_args[0].size = sizeof(outentry); args.out_args[0].value = &outentry; - args.out_args[1].size = sizeof(outopen); - args.out_args[1].value = &outopen; + /* Store outarg for fuse_finish_open() */ + outopenp = &ff->args->open_outarg; + args.out_args[1].size = sizeof(*outopenp); + args.out_args[1].value = outopenp; err = get_create_ext(&args, dir, entry, mode); if (err) @@ -676,9 +678,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, fuse_invalid_attr(&outentry.attr)) goto out_free_ff; - ff->fh = outopen.fh; + ff->fh = outopenp->fh; ff->nodeid = outentry.nodeid; - ff->open_flags = outopen.open_flags; + ff->open_flags = outopenp->open_flags; inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation, &outentry.attr, ATTR_TIMEOUT(&outentry), 0); if (!inode) { |