forked from torvalds/linux
Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
fuse: Definitions and ioctl() for passthrough
Introduce the new FUSE passthrough ioctl(), which allows userspace to specify a direct connection between a FUSE file and a lower file system file. Such ioctl() requires userspace to specify: - the file descriptor of one of its opened files, - the unique identifier of the FUSE request associated with a pending open/create operation, both encapsulated into a fuse_passthrough_out data structure. The ioctl() will search for the pending FUSE request matching the unique identifier, and update the passthrough file pointer of the request with the file pointer referenced by the passed file descriptor. When that pending FUSE request is handled, the passthrough file pointer is copied to the fuse_file data structure, so that the link between FUSE and lower file system is consolidated. In order for the passthrough mode to be successfully activated, the lower file system file must implement both read_ and write_iter file operations. This extra check avoids special pseudofiles to be targets for this feature. An additional enforced limitation is that when FUSE passthrough is enabled, no further file system stacking is allowed. Signed-off-by: Alessio Balsini <balsini@android.com>
- Loading branch information
1 parent
f4d51df
commit c8c14de554673fa450ce2cadee8957f5f8c021e3
Showing
8 changed files
with
156 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| // SPDX-License-Identifier: GPL-2.0 | ||
|
|
||
| #include "fuse_i.h" | ||
|
|
||
| int fuse_passthrough_setup(struct fuse_req *req, unsigned int fd) | ||
| { | ||
| int ret; | ||
| int fs_stack_depth; | ||
| struct file *passthrough_filp; | ||
| struct inode *passthrough_inode; | ||
| struct super_block *passthrough_sb; | ||
|
|
||
| /* Passthrough mode can only be enabled at file open/create time */ | ||
| if (req->in.h.opcode != FUSE_OPEN && req->in.h.opcode != FUSE_CREATE) { | ||
| pr_err("FUSE: invalid OPCODE for request.\n"); | ||
| return -EINVAL; | ||
| } | ||
|
|
||
| passthrough_filp = fget(fd); | ||
| if (!passthrough_filp) { | ||
| pr_err("FUSE: invalid file descriptor for passthrough.\n"); | ||
| return -EINVAL; | ||
| } | ||
|
|
||
| ret = -EINVAL; | ||
| if (!passthrough_filp->f_op->read_iter || | ||
| !passthrough_filp->f_op->write_iter) { | ||
| pr_err("FUSE: passthrough file misses file operations.\n"); | ||
| goto out; | ||
| } | ||
|
|
||
| passthrough_inode = file_inode(passthrough_filp); | ||
| passthrough_sb = passthrough_inode->i_sb; | ||
| fs_stack_depth = passthrough_sb->s_stack_depth + 1; | ||
| ret = -EEXIST; | ||
| if (fs_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) { | ||
| pr_err("FUSE: maximum fs stacking depth exceeded for passthrough\n"); | ||
| goto out; | ||
| } | ||
|
|
||
| req->args->passthrough_filp = passthrough_filp; | ||
| return 0; | ||
| out: | ||
| fput(passthrough_filp); | ||
| return ret; | ||
| } | ||
|
|
||
| void fuse_passthrough_release(struct fuse_file *ff) | ||
| { | ||
| if (!ff->passthrough_filp) | ||
| return; | ||
|
|
||
| fput(ff->passthrough_filp); | ||
| ff->passthrough_filp = NULL; | ||
| } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters