From eca63dab456a10c3491c367711ab18cbcb34816e Mon Sep 17 00:00:00 2001 From: Amir Goldstein Date: Mon, 13 May 2024 16:30:25 +0300 Subject: Enable passthrough mode for read/write operations (#919) Add support for filesystem passthrough read/write of files. When the FUSE_PASSTHROUGH capability is enabled, the FUSE server may decide, while handling the "open" or "create" requests, if the given file can be accessed by that process in "passthrough" mode, meaning that all the further read and write operations would be forwarded by the kernel directly to the backing file rather than to the FUSE server. All requests other than read or write are still handled by the server. This allows for an improved performance on reads and writes, especially in the case of reads at random offsets, for which no (readahead) caching mechanism would help, reducing the performance gap between FUSE and native filesystem access. Extend also the passthrough_hp example with the new passthrough feature. This example opens a kernel backing file per FUSE inode on the first FUSE file open of that inode and closes the backing file on the release of the last FUSE file on that inode. All opens of the same inode passthrough to the same backing file. A combination of fi->direct_io and fi->passthrough is allowed. It means that read/write operations go directly to the server, but mmap is done on the backing file. This allows to open some fds of the inode in passthrough mode and some fd of the same inode in direct_io/passthrough_mmap mode. Signed-off-by: Alessio Balsini Signed-off-by: Amir Goldstein --- include/fuse_common.h | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'include/fuse_common.h') diff --git a/include/fuse_common.h b/include/fuse_common.h index a614fb0..ba4b127 100644 --- a/include/fuse_common.h +++ b/include/fuse_common.h @@ -105,6 +105,11 @@ struct fuse_file_info { /** Requested poll events. Available in ->poll. Only set on kernels which support it. If unsupported, this field is set to zero. */ uint32_t poll_events; + + /** Passthrough backing file id. May be filled in by filesystem in + * create and open. It is used to create a passthrough connection + * between FUSE file and backing file. */ + int32_t backing_id; }; @@ -468,6 +473,18 @@ struct fuse_loop_config_v1 { */ #define FUSE_CAP_DIRECT_IO_ALLOW_MMAP (1 << 28) +/** + * Indicates support for passthrough mode access for read/write operations. + * + * If this flag is set in the `capable` field of the `fuse_conn_info` + * structure, then the FUSE kernel module supports redirecting read/write + * operations to the backing file instead of letting them to be handled + * by the FUSE daemon. + * + * This feature is disabled by default. + */ +#define FUSE_CAP_PASSTHROUGH (1 << 29) + /** * Ioctl flags * @@ -597,10 +614,30 @@ struct fuse_conn_info { */ unsigned time_gran; + /** + * When FUSE_CAP_PASSTHROUGH is enabled, this is the maximum allowed + * stacking depth of the backing files. In current kernel, the maximum + * allowed stack depth if FILESYSTEM_MAX_STACK_DEPTH (2), which includes + * the FUSE passthrough layer, so the maximum stacking depth for backing + * files is 1. + * + * The default is FUSE_BACKING_STACKED_UNDER (0), meaning that the + * backing files cannot be on a stacked filesystem, but another stacked + * filesystem can be stacked over this FUSE passthrough filesystem. + * + * Set this to FUSE_BACKING_STACKED_OVER (1) if backing files may be on + * a stacked filesystem, such as overlayfs or another FUSE passthrough. + * In this configuration, another stacked filesystem cannot be stacked + * over this FUSE passthrough filesystem. + */ +#define FUSE_BACKING_STACKED_UNDER (0) +#define FUSE_BACKING_STACKED_OVER (1) + unsigned max_backing_stack_depth; + /** * For future use. */ - unsigned reserved[22]; + unsigned reserved[21]; }; struct fuse_session; -- cgit v1.2.3