Compare commits

...
100 Commits
Author SHA1 Message Date
Antonio SJ Musumeci 9943f0ca2b fuse_open.cpp 2024-04-08 23:25:02 -05:00
Antonio SJ Musumeci d2df77046d fuse_create.cpp 2024-04-08 23:24:35 -05:00
Antonio SJ Musumeci e5b4e49b44 fuse_open.cpp 2024-04-08 22:54:32 -05:00
Antonio SJ Musumeci 524028dc2d fuse_create.cpp 2024-04-08 22:54:25 -05:00
Antonio SJ Musumeci c7c3f398a7 fuse_open.cpp 2024-04-08 22:52:43 -05:00
Antonio SJ Musumeci 23a16ee709 fuse_create.cpp 2024-04-08 22:52:17 -05:00
Antonio SJ Musumeci bfc2400746 fuse_create.cpp 2024-04-08 22:51:56 -05:00
Antonio SJ Musumeci 15e5e23aae fuse_create.cpp 2024-04-08 22:51:40 -05:00
Antonio SJ Musumeci a5a944d0be fuse_create.cpp 2024-04-08 22:51:14 -05:00
Antonio SJ Musumeci d020cfc2a6 fuse_open.cpp 2024-04-08 22:50:15 -05:00
Antonio SJ Musumeci 55a8243a8e fuse_open.cpp 2024-04-08 22:50:02 -05:00
Antonio SJ Musumeci 178b18804e fuse_open.cpp 2024-04-08 19:31:23 -05:00
Antonio SJ Musumeci 265cd454d2 fuse_open.cpp 2024-04-08 19:31:20 -05:00
Antonio SJ Musumeci f652f08910 fuse_open.cpp 2024-04-08 19:15:01 -05:00
Antonio SJ Musumeci 496ca26193 fuse_open.cpp 2024-04-08 19:14:49 -05:00
Antonio SJ Musumeci 6d927bc642 fuse_create.cpp 2024-04-08 19:14:16 -05:00
Antonio SJ Musumeci f4a22895b6 fuse_create.cpp 2024-04-08 19:14:01 -05:00
Antonio SJ Musumeci 712b51e388 fuse_create.cpp 2024-04-08 19:13:43 -05:00
Antonio SJ Musumeci 9497871cae fuse_create.cpp 2024-04-08 19:12:59 -05:00
Antonio SJ Musumeci 82806df54d fuse_create.cpp 2024-04-08 19:12:35 -05:00
Antonio SJ Musumeci ab193701de fuse_create.cpp 2024-04-08 19:12:06 -05:00
Antonio SJ Musumeci 49bec8f981 fuse_create.cpp 2024-04-08 19:10:02 -05:00
Antonio SJ Musumeci 922aac6a71 fuse_create.cpp 2024-04-08 19:09:44 -05:00
Antonio SJ Musumeci 739559fa80 fuse_create.cpp 2024-04-08 19:09:25 -05:00
Antonio SJ Musumeci ee9a0f0735 fuse_create.cpp 2024-04-08 19:09:06 -05:00
Antonio SJ Musumeci 64d0a97a6f fuse_create.cpp 2024-04-08 19:02:52 -05:00
Antonio SJ Musumeci 620f9ac901 fuse_create.cpp 2024-04-08 19:01:32 -05:00
Antonio SJ Musumeci a706d86f94 fuse_create.cpp 2024-04-08 19:00:48 -05:00
Antonio SJ Musumeci 2aeba8988d fuse_create.cpp 2024-04-08 19:00:37 -05:00
Antonio SJ Musumeci d2d80c78a9 fuse_create.cpp 2024-04-08 18:57:06 -05:00
Antonio SJ Musumeci 5d48e92e11 fuse_create.cpp 2024-04-08 18:55:40 -05:00
Antonio SJ Musumeci bb6a0e30d1 fuse_create.cpp 2024-04-08 18:55:16 -05:00
Antonio SJ Musumeci e06c671de8 fuse_create.cpp 2024-04-08 18:51:24 -05:00
Antonio SJ Musumeci 0f92992631 fuse_init.cpp 2024-04-08 18:20:34 -05:00
Antonio SJ Musumeci 61d95e6b7b enum.hpp 2024-04-08 18:19:54 -05:00
Antonio SJ Musumeci ed5fc2a83b enum.hpp 2024-04-08 18:19:44 -05:00
Antonio SJ Musumeci 5f9c7e5470 fuse_create.cpp 2024-04-08 18:18:19 -05:00
Antonio SJ Musumeci 57f86aba8c fuse_create.cpp 2024-04-08 18:18:06 -05:00
Antonio SJ Musumeci 4b397ab5dc config.cpp 2024-04-08 18:17:14 -05:00
Antonio SJ Musumeci eddfad36c3 config.cpp 2024-04-08 18:17:04 -05:00
Antonio SJ Musumeci 48d0b6adf6 config.cpp 2024-04-08 18:16:45 -05:00
Antonio SJ Musumeci 45767881ce config.hpp 2024-04-08 18:16:09 -05:00
Antonio SJ Musumeci 87d9f23102 config.hpp 2024-04-08 18:15:54 -05:00
Antonio SJ Musumeci 2d925d871f config_passthrough.cpp 2024-04-08 17:52:46 -05:00
Antonio SJ Musumeci 016b980199 config_passthrough.cpp 2024-04-08 17:52:40 -05:00
Antonio SJ Musumeci b48509e767 config_passthrough.cpp 2024-04-08 17:50:05 -05:00
Antonio SJ Musumeci 8977800020 config_passthrough.cpp 2024-04-08 17:49:28 -05:00
Antonio SJ Musumeci 8ead297481 config_passthrough.cpp 2024-04-08 17:44:41 -05:00
Antonio SJ Musumeci 86c0d10902 config_passthrough.cpp 2024-04-08 17:44:03 -05:00
Antonio SJ Musumeci 4d64b8c9ad config_passthrough.cpp 2024-04-08 17:43:49 -05:00
Antonio SJ Musumeci 1907168452 config_passthrough.cpp 2024-04-08 17:43:22 -05:00
Antonio SJ Musumeci ceee1f1cbb config_passthrough.cpp 2024-04-08 17:41:57 -05:00
Antonio SJ Musumeci e7536e4bbc config_passthrough.hpp 2024-04-08 17:41:32 -05:00
Antonio SJ Musumeci 70d94339fd config_passthrough.cpp 2024-04-08 17:39:33 -05:00
Antonio SJ Musumeci e539ecaded config_passthrough.cpp 2024-04-08 16:40:09 -05:00
Antonio SJ Musumeci 0686c18fe4 config_passthrough.cpp 2024-04-08 16:37:38 -05:00
Antonio SJ Musumeci 1252062f62 config_passthrough.cpp 2024-04-08 12:59:32 -05:00
Antonio SJ Musumeci 45dbec907b config_passthrough.cpp 2024-04-08 12:59:15 -05:00
Antonio SJ Musumeci e2a640a6ea config_passthrough.cpp 2024-04-08 12:14:32 -05:00
Antonio SJ Musumeci 4dd86c5e43 config_passthrough.cpp 2024-04-08 12:14:22 -05:00
Antonio SJ Musumeci e9185c3610 config_passthrough.cpp 2024-04-08 11:51:55 -05:00
Antonio SJ Musumeci 2136d95e33 config_passthrough.cpp 2024-04-08 11:51:27 -05:00
Antonio SJ Musumeci c581a7d172 config_passthrough.cpp 2024-04-08 10:28:01 -05:00
Antonio SJ Musumeci c173259a73 config_passthrough.cpp 2024-04-08 10:27:43 -05:00
Antonio SJ Musumeci 2cd26acd23 config_passthrough.cpp 2024-04-08 00:28:38 -05:00
Antonio SJ Musumeci bf9c5726bc config_passthrough.cpp 2024-04-08 00:28:29 -05:00
Antonio SJ Musumeci 62e68eb800 config_passthrough.cpp 2024-04-08 00:28:15 -05:00
Antonio SJ Musumeci b9433d2973 config_passthrough.cpp 2024-04-08 00:28:00 -05:00
Antonio SJ Musumeci a22aee9991 config_passthrough.cpp 2024-04-08 00:27:32 -05:00
Antonio SJ Musumeci 7e3769d083 config_passthrough.cpp 2024-04-08 00:26:10 -05:00
Antonio SJ Musumeci a6686a2ed4 config_passthrough.cpp 2024-04-08 00:25:56 -05:00
Antonio SJ Musumeci 5d2b862898 config_passthrough.cpp 2024-04-08 00:24:37 -05:00
Antonio SJ Musumeci 9b5108627e config_passthrough.cpp 2024-04-08 00:24:04 -05:00
Antonio SJ Musumeci c45834af93 config_passthrough.cpp 2024-04-08 00:23:47 -05:00
Antonio SJ Musumeci 04c6b6d4a9 config_passthrough.cpp 2024-04-08 00:23:21 -05:00
Antonio SJ Musumeci 16f71392fd config_passthrough.cpp 2024-04-08 00:23:13 -05:00
Antonio SJ Musumeci 9e6b87ae65 config_passthrough.cpp 2024-04-08 00:22:36 -05:00
Antonio SJ Musumeci 71b00ca4b3 config_passthrough.hpp 2024-04-08 00:09:20 -05:00
Antonio SJ Musumeci 0cff2d7983 checkpoint 2024-04-07 23:39:34 -05:00
Antonio SJ Musumeci c3b580b3ff fuse_release.cpp 2024-04-07 22:35:55 -05:00
Antonio SJ Musumeci 6a59c31e07 fuse_release.cpp 2024-04-07 22:35:44 -05:00
Antonio SJ Musumeci 885a051f2d fuse_create.cpp 2024-04-07 16:33:23 -05:00
Antonio SJ Musumeci e973fd0851 fuse_open.cpp 2024-04-07 16:18:02 -05:00
Antonio SJ Musumeci 9332e42e0a fuse_open.cpp 2024-04-07 16:16:24 -05:00
Antonio SJ Musumeci fb5add18f9 fuse_lowlevel.c 2024-04-07 16:11:44 -05:00
Antonio SJ Musumeci 025300eaf6 fuse_lowlevel.c 2024-04-07 16:11:41 -05:00
Antonio SJ Musumeci 3d1a9005c1 fuse_lowlevel.c 2024-04-07 15:57:16 -05:00
Antonio SJ Musumeci e5b647cb57 fuse_lowlevel.c 2024-04-07 15:57:12 -05:00
Antonio SJ Musumeci dce45e2ba9 fuse_open.cpp 2024-04-07 15:51:43 -05:00
Antonio SJ Musumeci 7c4f14a7db fuse_open.cpp 2024-04-07 15:51:16 -05:00
Antonio SJ Musumeci 893e0d4c94 fuse_lowlevel.c 2024-04-07 15:46:23 -05:00
Antonio SJ Musumeci d472fb1b12 debug.c 2024-04-07 15:38:08 -05:00
Antonio SJ Musumeci 30961779c2 fuse_init.cpp 2024-04-07 15:25:21 -05:00
Antonio SJ Musumeci 2bac614a40 fuse_lowlevel.c 2024-04-07 15:19:23 -05:00
Antonio SJ Musumeci 974e01a4b1 fuse_lowlevel.c 2024-04-07 12:04:32 -05:00
Antonio SJ Musumeci 5c956fe2d5 fuse_init.cpp 2024-04-07 11:52:49 -05:00
Antonio SJ Musumeci 4d9a390866 fuse_open.cpp 2024-04-07 01:50:42 -05:00
Antonio SJ Musumeci fb1e3afdb6 fuse_open.cpp 2024-04-07 01:49:30 -05:00
Antonio SJ Musumeci 10e1b7229e checkpoint 2024-04-07 01:42:28 -05:00
Antonio SJ Musumeci c9b7ed5b8a Add support for file io passthrough
If using Linux 6.9 or above and enabled (passthrough=true) files
opened or created will use the FUSE passthrough feature.

If direct-io=true / cache.files=off it will override passthrough. If
direct-io-allow-mmap is enabled only mmap will passthrough.

HANDLE_KILLPRIV and V2 are enabled now by default to remove the
kernel's need to issue getattr and getxattr requests.

moveonenospc will not work when leveraging passthrough.
2024-04-06 23:55:11 -05:00
18 changed files with 1661 additions and 20 deletions
+33 -3
View File
@@ -167,7 +167,10 @@ These options are the same regardless of whether you use them with the
longer need the data and it can drop its cache. Recommended when
**cache.files=partial|full|auto-full|per-process** to limit double
caching. (default: false)
* **direct-io-allow-mmap=BOOL**: On newer kernels (>= 6.6) it is
* **passthrough=off|ro|wo|rw**: On Linux 6.9 and above passthrough allows for
near native IO performance. See below for more details. (default:
off)
* **direct-io-allow-mmap=BOOL**: On Linux 6.6 and above it is
possible to disable file page caching while still allowing for
shared mmap support. mergerfs will enable this feature if available
but an option is provided to turn it off for testing and debugging
@@ -411,6 +414,32 @@ fact it will not be automatically included.
**fuse** package.
### passthrough
With Linux 6.9 and above there is a feature in FUSE called
"passthrough" which can improve performance by allowing a union or
overlay filesystem (like mergerfs) to pass the file descriptor of a
file opened on an underlying filesystem to the kernel to work on
directly rather than calls always having to go to the FUSE server
(mergerfs). As of Linux 6.9 the functions that can be passthroughed
are regular file read/write IO and mmap. Other functions may be added
in the future.
Passthrough requires `cache.files` to be enabled. `cache.files=off`
(which enables FUSE direct-io feature) will override `passthrough` and
read/write requests will still be sent to mergerfs.
If `cache.files=off` and `direct-io-allow-mmap=true` (the default)
then regular read/write IO will be handled by mergerfs but mmap will
be passthroughed.
NOTE: `moveonenospc` will not work when using `passthrough` as it
removes mergerfs entirely from the read/write process. If an ENOSPC
error occurs it will be returned to the caller app immediately. Since
mergerfs won't be handling the IO it therefore won't be able to handle
any error returned by said IO.
### inodecalc
Inodes (st_ino) are unique identifiers within a filesystem. Each
@@ -1664,6 +1693,8 @@ over the suggestions below (including the benchmarking section.)
NOTE: be sure to read about these features before changing them to
understand what behaviors it may impact
* test theoretical performance using `nullrw` or mounting a ram disk
* enable `passthrough`
* disable `security_capability` and/or `xattr`
* increase cache timeouts `cache.attr`, `cache.entry`, `cache.negative_entry`
* enable (or disable) page caching (`cache.files`)
@@ -1675,7 +1706,6 @@ understand what behaviors it may impact
* change the number of worker threads
* disable `posix_acl`
* disable `async_read`
* test theoretical performance using `nullrw` or mounting a ram disk
* use `symlinkify` if your data is largely static and read-only
* use tiered cache devices
* use LVM and LVM cache to place a SSD in front of your HDDs
@@ -1879,7 +1909,7 @@ more details.
#### rtorrent fails with ENODEV (No such device)
Be sure to set
`cache.files=partial|full|auto-full|per-processe`. rtorrent and some
`cache.files=partial|full|auto-full|per-process`. rtorrent and some
other applications use [mmap](http://linux.die.net/man/2/mmap) to read
and write to files and offer no fallback to traditional methods. FUSE
does not currently support mmap while using `direct_io`. There may be
+7
View File
@@ -667,6 +667,8 @@ int fuse_loop_mt(struct fuse *f);
*/
struct fuse_context *fuse_get_context(void);
int fuse_get_dev_fuse_fd(const struct fuse_context *);
/**
* Check if the current request has already been interrupted
*
@@ -779,6 +781,11 @@ void fuse_gc1();
void fuse_gc();
void fuse_invalidate_all_nodes();
int fuse_passthrough_open(const struct fuse_context *fc,
const int fd);
int fuse_passthrough_close(const struct fuse_context *fc,
const int backing_id);
EXTERN_C_END
#endif /* _FUSE_H_ */
+7 -12
View File
@@ -88,26 +88,18 @@ struct fuse_file_info_t
uint32_t noflush:1;
uint32_t passthrough:1;
/** File handle. May be filled in by filesystem in open().
Available in all other file operations */
uint64_t fh;
uint32_t backing_id;
/** Lock owner id. Available in locking operations and flush */
uint64_t lock_owner;
};
/**
* Capability bits for 'fuse_conn_info.capable' and 'fuse_conn_info.want'
*
* FUSE_CAP_ASYNC_READ: filesystem supports asynchronous read requests
* FUSE_CAP_POSIX_LOCKS: filesystem supports "remote" locking
* FUSE_CAP_ATOMIC_O_TRUNC: filesystem handles the O_TRUNC open flag
* FUSE_CAP_EXPORT_SUPPORT: filesystem handles lookups of "." and ".."
* FUSE_CAP_BIG_WRITES: filesystem can handle write size larger than 4kB
* FUSE_CAP_DONT_MASK: don't apply umask to file mode on create operations
* FUSE_CAP_IOCTL_DIR: ioctl support on directories
* FUSE_CAP_CACHE_SYMLINKS: cache READLINK responses
*/
#define FUSE_CAP_ASYNC_READ (1ULL << 0)
#define FUSE_CAP_POSIX_LOCKS (1ULL << 1)
#define FUSE_CAP_ATOMIC_O_TRUNC (1ULL << 3)
@@ -127,6 +119,9 @@ struct fuse_file_info_t
#define FUSE_CAP_SETXATTR_EXT (1ULL << 22)
#define FUSE_CAP_DIRECT_IO_ALLOW_MMAP (1ULL << 23)
#define FUSE_CAP_CREATE_SUPP_GROUP (1ULL << 24)
#define FUSE_CAP_PASSTHROUGH (1ULL << 25)
#define FUSE_CAP_HANDLE_KILLPRIV (1ULL << 26)
#define FUSE_CAP_HANDLE_KILLPRIV_V2 (1ULL << 27)
/**
+36 -3
View File
@@ -211,6 +211,12 @@
* 7.39
* - add FUSE_DIRECT_IO_ALLOW_MMAP
* - add FUSE_STATX and related structures
*
* 7.40
* - add max_stack_depth to fuse_init_out, add FUSE_PASSTHROUGH init flag
* - add backing_id to fuse_open_out, add FOPEN_PASSTHROUGH open flag
* - add FUSE_NO_EXPORT_SUPPORT init flag
* - add FUSE_NOTIFY_RESEND, add FUSE_HAS_RESEND init flag
*/
#ifndef _LINUX_FUSE_H
@@ -246,7 +252,7 @@
#define FUSE_KERNEL_VERSION 7
/** Minor version number of this interface */
#define FUSE_KERNEL_MINOR_VERSION 39
#define FUSE_KERNEL_MINOR_VERSION 40
/** The node ID of the root inode */
#define FUSE_ROOT_ID 1
@@ -353,6 +359,7 @@ struct fuse_file_lock {
* FOPEN_STREAM: the file is stream-like (no file position at all)
* FOPEN_NOFLUSH: don't flush data cache on close (unless FUSE_WRITEBACK_CACHE)
* FOPEN_PARALLEL_DIRECT_WRITES: Allow concurrent direct writes on the same inode
* FOPEN_PASSTHROUGH: passthrough read/write io for this open file
*/
#define FOPEN_DIRECT_IO (1 << 0)
#define FOPEN_KEEP_CACHE (1 << 1)
@@ -361,6 +368,7 @@ struct fuse_file_lock {
#define FOPEN_STREAM (1 << 4)
#define FOPEN_NOFLUSH (1 << 5)
#define FOPEN_PARALLEL_DIRECT_WRITES (1 << 6)
#define FOPEN_PASSTHROUGH (1 << 7)
/**
* INIT request/reply flags
@@ -410,6 +418,9 @@ struct fuse_file_lock {
* symlink and mknod (single group that matches parent)
* FUSE_HAS_EXPIRE_ONLY: kernel supports expiry-only entry invalidation
* FUSE_DIRECT_IO_ALLOW_MMAP: allow shared mmap in FOPEN_DIRECT_IO mode.
* FUSE_NO_EXPORT_SUPPORT: explicitly disable export support
* FUSE_HAS_RESEND: kernel supports resending pending requests, and the high bit
* of the request ID indicates resend requests
*/
#define FUSE_ASYNC_READ (1 << 0)
#define FUSE_POSIX_LOCKS (1 << 1)
@@ -449,6 +460,9 @@ struct fuse_file_lock {
#define FUSE_CREATE_SUPP_GROUP (1ULL << 34)
#define FUSE_HAS_EXPIRE_ONLY (1ULL << 35)
#define FUSE_DIRECT_IO_ALLOW_MMAP (1ULL << 36)
#define FUSE_PASSTHROUGH (1ULL << 37)
#define FUSE_NO_EXPORT_SUPPORT (1ULL << 38)
#define FUSE_HAS_RESEND (1ULL << 39)
/* Obsolete alias for FUSE_DIRECT_IO_ALLOW_MMAP */
#define FUSE_DIRECT_IO_RELAX FUSE_DIRECT_IO_ALLOW_MMAP
@@ -635,6 +649,7 @@ enum fuse_notify_code {
FUSE_NOTIFY_STORE = 4,
FUSE_NOTIFY_RETRIEVE = 5,
FUSE_NOTIFY_DELETE = 6,
FUSE_NOTIFY_RESEND = 7,
FUSE_NOTIFY_CODE_MAX,
};
@@ -761,7 +776,7 @@ struct fuse_create_in {
struct fuse_open_out {
uint64_t fh;
uint32_t open_flags;
uint32_t padding;
int32_t backing_id;
};
struct fuse_release_in {
@@ -877,7 +892,8 @@ struct fuse_init_out {
uint16_t max_pages;
uint16_t map_alignment;
uint32_t flags2;
uint32_t unused[7];
uint32_t max_stack_depth;
uint32_t unused[6];
};
#define CUSE_INIT_INFO_MAX 4096
@@ -960,6 +976,14 @@ struct fuse_fallocate_in {
uint32_t padding;
};
/**
* FUSE request unique ID flag
*
* Indicates whether this is a resend request. The receiver should handle this
* request accordingly.
*/
#define FUSE_UNIQUE_RESEND (1ULL << 63)
struct fuse_in_header {
uint32_t len;
uint32_t opcode;
@@ -1049,9 +1073,18 @@ struct fuse_notify_retrieve_in {
uint64_t dummy4;
};
struct fuse_backing_map {
int32_t fd;
uint32_t flags;
uint64_t padding;
};
/* Device ioctls: */
#define FUSE_DEV_IOC_MAGIC 229
#define FUSE_DEV_IOC_CLONE _IOR(FUSE_DEV_IOC_MAGIC, 0, uint32_t)
#define FUSE_DEV_IOC_BACKING_OPEN _IOW(FUSE_DEV_IOC_MAGIC, 1, \
struct fuse_backing_map)
#define FUSE_DEV_IOC_BACKING_CLOSE _IOW(FUSE_DEV_IOC_MAGIC, 2, uint32_t)
struct fuse_lseek_in {
uint64_t fh;
+4 -1
View File
@@ -199,6 +199,7 @@ fuse_flag_to_str(const uint64_t offset_)
FUSE_INIT_FLAG_CASE(CREATE_SUPP_GROUP);
FUSE_INIT_FLAG_CASE(HAS_EXPIRE_ONLY);
FUSE_INIT_FLAG_CASE(DIRECT_IO_ALLOW_MMAP);
FUSE_INIT_FLAG_CASE(PASSTHROUGH);
}
return NULL;
@@ -804,13 +805,15 @@ debug_fuse_init_out(const uint64_t unique_,
" time_gran=%u;"
" max_pages=%u;"
" map_alignment=%u;"
" max_stack_depth=%u;"
"\n",
arg->max_background,
arg->congestion_threshold,
arg->max_write,
arg->time_gran,
arg->max_pages,
arg->map_alignment);
arg->map_alignment,
arg->max_stack_depth);
}
static
+34
View File
@@ -47,6 +47,7 @@
#include <syslog.h>
#include <time.h>
#include <unistd.h>
#include <sys/ioctl.h>
#ifdef HAVE_MALLOC_TRIM
#include <malloc.h>
@@ -3682,6 +3683,12 @@ fuse_get_context(void)
return &fuse_get_context_internal()->ctx;
}
int
fuse_get_dev_fuse_fd(const struct fuse_context *fc_)
{
return fuse_chan_fd(fc_->fuse->se->ch);
}
enum {
KEY_HELP,
};
@@ -4156,3 +4163,30 @@ fuse_log_metrics_get(void)
{
return g_LOG_METRICS;
}
int
fuse_passthrough_open(const struct fuse_context *fc_,
const int fd_)
{
int rv;
int dev_fuse_fd;
struct fuse_backing_map bm = {0};
dev_fuse_fd = fuse_get_dev_fuse_fd(fc_);
bm.fd = fd_;
rv = ioctl(dev_fuse_fd,FUSE_DEV_IOC_BACKING_OPEN,&bm);
return rv;
}
int
fuse_passthrough_close(const struct fuse_context *fc_,
const int backing_id_)
{
int dev_fuse_fd;
dev_fuse_fd = fuse_get_dev_fuse_fd(fc_);
return ioctl(dev_fuse_fd, FUSE_DEV_IOC_BACKING_CLOSE, &backing_id_);
}
+20
View File
@@ -277,6 +277,11 @@ fill_open(struct fuse_open_out *arg_,
arg_->open_flags |= FOPEN_PARALLEL_DIRECT_WRITES;
if(ffi_->noflush)
arg_->open_flags |= FOPEN_NOFLUSH;
if(ffi_->passthrough)
{
arg_->open_flags |= FOPEN_PASSTHROUGH;
arg_->backing_id = ffi_->backing_id;
}
}
int
@@ -1175,6 +1180,12 @@ do_init(fuse_req_t req,
f->conn.capable |= FUSE_CAP_DIRECT_IO_ALLOW_MMAP;
if(inargflags & FUSE_CREATE_SUPP_GROUP)
f->conn.capable |= FUSE_CAP_CREATE_SUPP_GROUP;
if(inargflags & FUSE_PASSTHROUGH)
f->conn.capable |= FUSE_CAP_PASSTHROUGH;
if(inargflags & FUSE_HANDLE_KILLPRIV)
f->conn.capable |= FUSE_CAP_HANDLE_KILLPRIV;
if(inargflags & FUSE_HANDLE_KILLPRIV_V2)
f->conn.capable |= FUSE_CAP_HANDLE_KILLPRIV_V2;
}
else
{
@@ -1248,6 +1259,15 @@ do_init(fuse_req_t req,
outargflags |= FUSE_CREATE_SUPP_GROUP;
if(f->conn.want & FUSE_CAP_DIRECT_IO_ALLOW_MMAP)
outargflags |= FUSE_DIRECT_IO_ALLOW_MMAP;
if(f->conn.want & FUSE_CAP_HANDLE_KILLPRIV)
outargflags |= FUSE_HANDLE_KILLPRIV;
if(f->conn.want & FUSE_CAP_HANDLE_KILLPRIV_V2)
outargflags |= FUSE_HANDLE_KILLPRIV_V2;
if(f->conn.want & FUSE_CAP_PASSTHROUGH)
{
outargflags |= FUSE_PASSTHROUGH;
outarg.max_stack_depth = 2;
}
if(inargflags & FUSE_INIT_EXT)
{
+1328
View File
File diff suppressed because it is too large Load Diff
+8
View File
@@ -62,6 +62,8 @@ namespace l
IFERT("export-support");
IFERT("fsname");
IFERT("fuse_msg_size");
IFERT("handle-killpriv");
IFERT("handle-killpriv-v2");
IFERT("mount");
IFERT("nullrw");
IFERT("pid");
@@ -103,6 +105,8 @@ Config::Config()
fsname(),
func(),
fuse_msg_size(FUSE_MAX_MAX_PAGES),
handle_killpriv(true),
handle_killpriv_v2(true),
ignorepponrename(false),
inodecalc("hybrid-hash"),
lazy_umount_mountpoint(false),
@@ -114,6 +118,7 @@ Config::Config()
nfsopenhack(NFSOpenHack::ENUM::OFF),
nullrw(false),
parallel_direct_writes(false),
passthrough(PassthroughEnum::off),
posix_acl(false),
readahead(0),
readdir("seq"),
@@ -180,6 +185,8 @@ Config::Config()
_map["func.unlink"] = &func.unlink;
_map["func.utimens"] = &func.utimens;
_map["fuse_msg_size"] = &fuse_msg_size;
_map["handle-killpriv"] = &handle_killpriv;
_map["handle-killpriv-v2"] = &handle_killpriv_v2;
_map["ignorepponrename"] = &ignorepponrename;
_map["inodecalc"] = &inodecalc;
_map["kernel_cache"] = &kernel_cache;
@@ -194,6 +201,7 @@ Config::Config()
_map["nullrw"] = &nullrw;
_map["pid"] = &pid;
_map["parallel-direct-writes"] = &parallel_direct_writes;
_map["passthrough"] = &passthrough;
_map["pin-threads"] = &fuse_pin_threads;
_map["posix_acl"] = &posix_acl;
_map["readahead"] = &readahead;
+5 -1
View File
@@ -21,12 +21,13 @@
#include "config_cachefiles.hpp"
#include "config_flushonclose.hpp"
#include "config_follow_symlinks.hpp"
#include "config_pid.hpp"
#include "config_inodecalc.hpp"
#include "config_link_exdev.hpp"
#include "config_log_metrics.hpp"
#include "config_moveonenospc.hpp"
#include "config_nfsopenhack.hpp"
#include "config_passthrough.hpp"
#include "config_pid.hpp"
#include "config_rename_exdev.hpp"
#include "config_set.hpp"
#include "config_statfs.hpp"
@@ -125,6 +126,8 @@ public:
ConfigSTR fsname;
Funcs func;
ConfigUINT64 fuse_msg_size;
ConfigBOOL handle_killpriv;
ConfigBOOL handle_killpriv_v2;
ConfigBOOL ignorepponrename;
InodeCalc inodecalc;
ConfigBOOL kernel_cache;
@@ -137,6 +140,7 @@ public:
NFSOpenHack nfsopenhack;
ConfigBOOL nullrw;
ConfigBOOL parallel_direct_writes;
Passthrough passthrough;
ConfigGetPid pid;
ConfigBOOL posix_acl;
ConfigUINT64 readahead;
+43
View File
@@ -0,0 +1,43 @@
#/*
ISC License
Copyright (c) 2024, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config_passthrough.hpp"
#include "ef.hpp"
#include "errno.hpp"
template<>
std::string
Passthrough::to_string() const
{
return _data._to_string();
}
template<>
int
Passthrough::from_string(const std::string &s_)
{
better_enums::optional<PassthroughEnum> e;
e = PassthroughEnum::_from_string_nothrow(s_.c_str());
if(!e)
return -EINVAL;
_data = *e;
return 0;
}
+28
View File
@@ -0,0 +1,28 @@
/*
ISC License
Copyright (c) 2024, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "better_enum.hpp"
#include "enum.hpp"
BETTER_ENUM(PassthroughEnum, uint8_t, off, ro, wo, rw);
typedef Enum<PassthroughEnum> Passthrough;
+6
View File
@@ -60,6 +60,12 @@ public:
return _data;
}
ENUM
operator+() const
{
return _data;
}
public:
bool operator==(const ENUM data_) const
{
+2
View File
@@ -31,12 +31,14 @@ public:
bool const direct_io_)
: FH(fusepath_),
fd(fd_),
backing_id(0),
direct_io(direct_io_)
{
}
public:
int fd;
int backing_id;
uint32_t direct_io:1;
std::mutex mutex;
};
+43
View File
@@ -170,6 +170,29 @@ namespace l
return 0;
}
static
int
passthrough(const fuse_context *fc_,
fuse_file_info_t *ffi_)
{
int backing_id;
FileInfo *fi;
const ugid::SetRootGuard ugid;
fi = reinterpret_cast<FileInfo*>(ffi_->fh);
backing_id = fuse_passthrough_open(fc_,fi->fd);
if(backing_id <= 0)
return 0;
ffi_->passthrough = true;
ffi_->keep_cache = false;
fi->backing_id = backing_id;
ffi_->backing_id = backing_id;
return 0;
}
static
int
create(const Policy::Search &searchFunc_,
@@ -208,6 +231,15 @@ namespace l
}
}
constexpr
const
uint64_t
_(const PassthroughEnum e,
const uint64_t m)
{
return ((((uint64_t)e) << 32) | (m & O_ACCMODE));
}
namespace FUSE
{
int
@@ -247,6 +279,17 @@ namespace FUSE
fc->umask);
}
if(rv != 0)
return rv;
switch(_(cfg->passthrough,ffi_->flags))
{
case _(PassthroughEnum::ro,O_RDONLY):
case _(PassthroughEnum::wo,O_WRONLY):
case _(PassthroughEnum::rw,O_RDWR):
return l::passthrough(fc,ffi_);
}
return rv;
}
}
+3
View File
@@ -147,8 +147,11 @@ namespace FUSE
l::want_if_capable(conn_,FUSE_CAP_DIRECT_IO_ALLOW_MMAP,&cfg->direct_io_allow_mmap);
l::want_if_capable(conn_,FUSE_CAP_DONT_MASK);
l::want_if_capable(conn_,FUSE_CAP_EXPORT_SUPPORT,&cfg->export_support);
l::want_if_capable(conn_,FUSE_CAP_HANDLE_KILLPRIV,&cfg->handle_killpriv);
l::want_if_capable(conn_,FUSE_CAP_HANDLE_KILLPRIV_V2,&cfg->handle_killpriv_v2);
l::want_if_capable(conn_,FUSE_CAP_IOCTL_DIR);
l::want_if_capable(conn_,FUSE_CAP_PARALLEL_DIROPS);
l::want_if_capable(conn_,FUSE_CAP_PASSTHROUGH);
l::want_if_capable(conn_,FUSE_CAP_POSIX_ACL,&cfg->posix_acl);
l::want_if_capable(conn_,FUSE_CAP_READDIR_PLUS,&cfg->readdirplus);
l::want_if_capable(conn_,FUSE_CAP_WRITEBACK_CACHE,&cfg->writeback_cache);
+43
View File
@@ -218,6 +218,29 @@ namespace l
return 0;
}
static
int
passthrough(const fuse_context *fc_,
fuse_file_info_t *ffi_)
{
int backing_id;
FileInfo *fi;
const ugid::SetRootGuard ugid;
fi = reinterpret_cast<FileInfo*>(ffi_->fh);
backing_id = fuse_passthrough_open(fc_,fi->fd);
if(backing_id <= 0)
return 0;
ffi_->passthrough = true;
ffi_->keep_cache = false;
fi->backing_id = backing_id;
ffi_->backing_id = backing_id;
return 0;
}
static
int
open(const Policy::Search &searchFunc_,
@@ -238,6 +261,15 @@ namespace l
}
}
constexpr
const
uint64_t
_(const PassthroughEnum e,
const uint64_t m)
{
return ((((uint64_t)e) << 32) | (m & O_ACCMODE));
}
namespace FUSE
{
int
@@ -264,6 +296,17 @@ namespace FUSE
cfg->link_cow,
cfg->nfsopenhack);
if(rv != 0)
return rv;
switch(_(cfg->passthrough,ffi_->flags))
{
case _(PassthroughEnum::ro,O_RDONLY):
case _(PassthroughEnum::wo,O_WRONLY):
case _(PassthroughEnum::rw,O_RDWR):
return l::passthrough(fc,ffi_);
}
return rv;
}
}
+11
View File
@@ -19,6 +19,7 @@
#include "fileinfo.hpp"
#include "fs_close.hpp"
#include "fs_fadvise.hpp"
#include "ugid.hpp"
#include "fuse.h"
@@ -40,6 +41,16 @@ namespace l
fs::fadvise_dontneed(fi_->fd);
}
if(fi_->backing_id)
{
const fuse_context *fc;
const ugid::SetRootGuard ugid;
fc = fuse_get_context();
fuse_passthrough_close(fc,fi_->backing_id);
}
fs::close(fi_->fd);
delete fi_;