Fix build of example/memfs_ll.cc on 32 bit architectures
The code uses std::min() which expects its arguments to be size_t. Two
times it uses an offset declared as off_t. While both size_t and off_t
are 32-bit integers, the latter is signed. On 64 bit architectures
the conversation of off_t -> size_t performed automatically. On 32 bit
architectures it needs a type cast.
Bernd Schubert [Mon, 10 Feb 2025 01:45:42 +0000 (02:45 +0100)]
Build fixes for -Og
Cleaning... 18 files.
[35/69] Compiling C object example/passthrough_ll.p/passthrough_ll.c.o
../example/passthrough_ll.c: In function ‘lo_opendir’:
../example/passthrough_ll.c:666:20: warning: ‘fd’ may be used uninitialized [-Wmaybe-uninitialized]
666 | if (fd != -1)
| ^
../example/passthrough_ll.c:637:13: note: ‘fd’ was declared here
637 | int fd;
| ^~
[38/69] Compiling C object test/test_syscalls.p/test_syscalls.c.o
../test/test_syscalls.c: In function ‘test_seekdir’:
../test/test_syscalls.c:804:16: warning: ‘de’ may be used uninitialized [-Wmaybe-uninitialized]
804 | while (de)
| ^~
../test/test_syscalls.c:776:24: note: ‘de’ was declared here
776 | struct dirent *de;
| ^~
Bernd Schubert [Sat, 8 Feb 2025 13:35:46 +0000 (14:35 +0100)]
Rename to fuse_session_new_versioned
Similar previous renames to fuse_main_real_versioned,
but here for the low level fuse_session_new.
Also remove symbol versioned as part of "fuse_session_new"
as that function is not part of the official API/ABI
and to allow easier access with dlopen/dlsym.
Also switch back to a macro fuse_session_new, just in
case some code has some expectations on that.
Luis Henriques [Fri, 31 Jan 2025 16:03:54 +0000 (16:03 +0000)]
fuse_lowlevel.c: drop incorrect comment from convert_to_conn_want_ext()
The comment is probably a leftover from older versions, as the application
of the 32 bits of conn.capable_ext to conn.capable is done before function
convert_to_conn_want_ext() is invoked.
Luis Henriques [Fri, 31 Jan 2025 15:26:20 +0000 (15:26 +0000)]
fuse_lowlevel.c: fix possible 64 bits value truncation
Because conn.want_ext is a uint64_t, copying it into a uint32_t may result
in truncating it's value. This patch fixes a bug in do_init() where the
32 bits copy is again converted into a 64 bits value, because it will be
used in convert_to_conn_want_ext().
Zegang [Wed, 8 Jan 2025 06:50:30 +0000 (14:50 +0800)]
Identify the FD hold by parent process
Issue:
There is no directly way to get the FD
hold by parent process which asked do fuse mount.
Use Case:
For auto_unmount case, identify the FD can easy to close
the FD and make automatically unmount manually and explicitly.
The FD[1] can be got via getenv(FUSE_COMMFD2_ENV).
One potential use case is to satisfy FD-Leak checks.
Solution:
Add an extra env _FUSE_COMMFD2 to store the FD.
This will provide a easy way to get the FD via FUSE_COMMFD2_ENV.
We actually don't need to make fuse_main_real() symboled, as it
is not part of the official API.
The inlined function now always calls into fuse_main_real_317
and the compat ABI function (which should also be available
for dlopen/dlsym) is now always compiled, independent if the
compiler/linker support versioned symbols.
Additionally, fuse_main_real() is also declared as inlined
function and a warning message is created when that function
is called.
Bernd Schubert [Sat, 4 Jan 2025 19:29:18 +0000 (20:29 +0100)]
Avoid global declarion of internal functions that are new in 3.17
_fuse_new() is not supposed to be called by external users
outside of internal functions or static inlined functions.
This also removes several functions from lib/fuse_versionscript
which where added and exported by
commit 58f85bfa9b7d ("Add in the libfuse version a program...)
as these are libfuse internal only.
Bernd Schubert [Sat, 4 Jan 2025 15:08:30 +0000 (16:08 +0100)]
Fix fuse_main_real symbols
Commit 58f85bfa9b7d ("Add in the libfuse version a program...")
forgot to add a fuse_main_real function for libfuse compilations
that are not symboled. That is now added in compat.c.
Amir Goldstein [Thu, 2 Jan 2025 19:25:13 +0000 (20:25 +0100)]
example/passthrough: Enable testing of readdirplus without fill offsets
passthrough example supports the --plus command line argument to reply
to readdirplus with fill_dir_plus and unspecified (0) fill offsets.
As explained in this comment:
https://github.com/libfuse/libfuse/pull/896#issuecomment-1978917041
passthrough example needs a few more changes to be able to test commit dd95d13a ("fix readdirplus when filler is called with zero offset (#896))
With the changes in this commit, readdirplus without fill offsets
can be tested to verify the readdirplus fix above with command line:
Amir Goldstein [Fri, 3 Jan 2025 11:57:15 +0000 (12:57 +0100)]
Fix build of memfs_ll without manual meson reconfigure
After pulling latest code, memfs_ll build would fail because it
builds with C++11.
Changing the default of cpp_std in meson.build is not enough to fix this
problem even if user runs 'meson setup --reconfigure'.
I had to run 'meson setup -Dcpp_std= --reconfigure' to fix the build
as mentioned in this meson issue:
https://github.com/mesonbuild/meson/issues/8062#issuecomment-1568249672
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Amir Goldstein [Wed, 1 Jan 2025 19:47:41 +0000 (20:47 +0100)]
passthrough_ll: set correct keep_cache flag in opendir (#1083)
In cache=always mode, set keep_cache flag in opendir(), same as done
in open() and same as passthrough_hp does in opendir().
In the default cache=auto mode, use readdir cache, but do not set
keep_cache, same as regular files use page cache for an open file,
but do not keep_cache for a new open.
Note that passthrough_hp by default behaves the same as passthrough_ll
cache=always mode and supports the cache=never mode with --nocache, but
it does not support the equivalent of cache=auto mode.
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Bernd Schubert [Sat, 28 Dec 2024 14:10:03 +0000 (15:10 +0100)]
Add 64-bit conn::{capable,want}_ext fields
The previous fields are left for ABI compatibility, although
it is not beautiful to add that complexity when we have to increase
the so-version as we had ABI breakage anyway.
example/printcap is simplified to use an array, as every line would
have needed to be modified anyway. Missing 'FUSE_CAP_PASSTHROUGH'
was added.
Bernd Schubert [Mon, 16 Dec 2024 22:37:29 +0000 (23:37 +0100)]
Allow to have page aligned writes
Read/writes IOs should be page aligned as fuse server
might need to copy data to another buffer otherwise in
order to fulfill network or device storage requirements.
Simple reproducer is example/passthrough*
and opening a file with O_DIRECT - without this change
writing to that file failed with -EINVAL if the underlying
file system was using ext4 (for passthrough_hp the
'passthrough' feature has to be disabled).
The mis-alignment from fuse kernel is not ideal, but we can handle
it by allocation one page more than needed and then using a buffer
that is set up to compensate for kernel misalignment.
This also only set se->buf_reallocable to true when called
by a libfuse internal caller - we do not know what
external callers are doing with the buffer - update to
commit 0e0f43b79b9b
Bernd Schubert [Thu, 12 Dec 2024 15:08:50 +0000 (16:08 +0100)]
examples: Add memfs_ll.cc
This is an initial implementation and quickly hacked together
within a few hours - issues expected.
This also increase to C++17 as memfs_ll makes use of more
recent features.
Background to create this was actually to be able to test large
file names (3 * 1024B), which couldn't be achieved with passthrough
file system as non of the underlying file systems seems to support
that.
Horst Birthelmer [Wed, 20 Nov 2024 15:14:43 +0000 (16:14 +0100)]
support FUSE_TMPFILE in the low level API
Note that name hashes and using paths as parameters
makes it very hard to support
anonymous files in the high level API.
Known Issues:
- tests have to bail out when O_TMPFILE is not supported.
This will always be the case with high level passthrough implementations.
- test_create_and_link_tmpfile has to be skipped
due to unidentified problems with github runner
Joanne Koong [Fri, 15 Nov 2024 04:55:48 +0000 (20:55 -0800)]
Reallocate fuse_session buffer transparently for extended max writes
A previous PR supported extended max writes (eg write requests larger than 1 MB)
by initializing the fuse session buffer size to use the max_pages_limit set in
/proc/sys/fs/fuse. However, this is a huge problem for machines where multiple
fuse servers may be running but only one server needs large writes. In this case,
a lot of memory will be wasted and will lead to OOM issues.
This PR does a reallocation of the session buffer transparently if the server set
"se->conn.max_write" to a value larger than 1 MiB. This is only for buffers that
are "owned" by libfuse - if the server wishes to provide its own allocated buffer
for receiving/processing requests, then it should ensure that buffer is allocated
to the proper size from the start.
Local testing showed:
echo 65535 | sudo tee /proc/sys/fs/fuse/max_pages_limit
dd if=/dev/urandom of=hello_file bs=6M count=2
write requests:
write request size is 5242880
write request size is 1048576
write request size is 5242880
write request size is 1048576
fuse_lowlevel FUSE_INIT: Simplify the max_write/bufsize logic
max_write can be limited by se->op.init() and by the buffer size,
we use the minimum of these two.
Required se->bufsize is then set according to the determined
max_write. The current thread will have the old buffer size,
though, as it already had to the allocation to handle the
FUSE_INIT call (unless splice is used and ths variable
and related buffer is not used at all).
The given bufsize is just a hint for minimum size, allocation
could be actually larger (for example to get huge pages).
Initialize session buffer size to value set by sysctl
Currently in libfuse, the buffer size for a fuse session is
capped at 1 MiB on a 4k page system. A recent patch
upstream [1] was merged that allows the max number of pages
per fuse request to be dynamically configurable through the
/proc/sys interface (/proc/sys/fs/fuse/max_pages_limit).
This commit adds support for this on the libfuse side to set
the fuse session buffer to take into account the max pages
limit set in /proc/sys/fs/fuse/max_pages_limit. If this
sysctl does not exist (eg older kernels), it will default to
old behavior (using FUSE_MAX_MAX_PAGES (256) as the max pages
limit). This allows for things like bigger write buffers per
request.
MJ Harvey [Wed, 21 Aug 2024 12:05:20 +0000 (07:05 -0500)]
fusermount: close inherited fds
When using the auto_unmount option, the fusermount3
watchdog process retains any inherited file descriptors.
This PR ensures they are closed.
Reason is that FDs that are kept open for a long time might
cause issues for applications using libfuse, for example
if these expect a pipe close, but the pipe is kept open
through the inherited file descriptor.
See for example: https://github.com/cvmfs/cvmfs/issues/3645
example/passthrough_hp: No auto FOPEN_DIRECT_IO in passthrough mode
sfs_open and sfs_create set fi->direct_io (FOPEN_DIRECT_IO) when
O_DIRECT is given, in order to benefit from a shared inode lock
in kernel, i.e. to get parallel DIO writes. However, kernel side
disabled passthrough when FOPEN_DIRECT_IO is set. Reads/writes
had been totally failing in this case for O_DIRECT as
sfs_write_buf() and sfs_read() have a sanity check. That sanity
check could be modified, but for performance passthrough is
better than parallel DIO, hence, we only want automatic
FOPEN_DIRECT_IO for O_DIRECT when passthrough is not enabled.
Fixes: https://github.com/libfuse/libfuse/issues/1027
This also fixes automatically switching to FOPEN_DIRECT_IO
for O_DIRECT in sfs_create().