Ciaran [Wed, 21 Dec 2022 00:44:50 +0000 (16:44 -0800)]
update mount.c, in order to pass through -n.
autofs uses automount, which calls fuse, during an sshfs call. fuse complains about -n being an unknown option (ref. https://github.com/libfuse/libfuse/issues/715)
this one line edit provides the command to be accepted, and pass through, allowing autofs-automount to operate on the mount, even though it is already in the mtab, given the nature of autofs/automount.
Zhansong Gao [Wed, 30 Nov 2022 08:01:50 +0000 (16:01 +0800)]
Make it work even if max_idle_threads is set to 0
It may happen that none of the worker threads are running
if max_idle_threads is set to 0 although few people will do this.
Adding a limit of keeping at least one worker thread will make
our code more rigorous.
Fix the fuse_parse_cmdline@FUSE_3.0 ABI compat symbol
There was a simple typo and sym1 didn't match the function name
with the older __asm__(".symver " sym1 "," sym2) way to define
ABI compatibility.
Witht the newer "__attribute__ ((symver (sym2)))" sym1 is not used
at all and in manual testing the issue didn't come up therefore.
Frank Dinoff [Tue, 26 Jul 2022 19:49:01 +0000 (15:49 -0400)]
Use destroy_req instead of free to destroy fuse_req
If we get the interrupt before the fuse op, the fuse_req is deleted without
decrementing the refcount on the cloned file descriptor. This leads to a
leak of the cloned /dev/fuse file descriptor.
Bernd Schubert [Thu, 24 Mar 2022 11:19:57 +0000 (12:19 +0100)]
fuse-loop/fuse_do_work: Avoid lots of thread creations/destructions
On benchmarking metadata operations with a single threaded bonnie++
and "max_idle_threads" limited to 1, 'top' was showing suspicious
160% cpu usage.
Profiling the system with flame graphs showed that an astonishing
amount of CPU time was spent in thread creation and destruction.
After verifying the code it turned out that fuse_do_work() was
creating a new thread every time all existing idle threads
were already busy. And then just a few lines later after processing
the current request it noticed that it had created too many threads
and destructed the current thread. I.e. there was a thread
creation/destruction ping-pong.
Code is changed to only create new threads if the max number of
threads is not reached.
Furthermore, thread destruction is disabled, as creation/destruction
is expensive in general.
With this change cpu usage of passthrough_hp went from ~160% to
~80% (with different values of max_idle_threads). And bonnie
values got approximately faster by 90%. This is a with single
threaded bonnie++
bonnie++ -x 4 -q -s0 -d <path> -n 30:1:1:10 -r 0
Without this patch, using the default max_idle_threads=10 and just
a single bonnie++ the thread creation/destruction code path is not
triggered. Just one libfuse and one application thread is just
a corner case - the requirement for the issue was just
n-application-threads >= max_idle_threads.
struct fuse_loop_config was passed as a plain struct, without any
version identifer. This had two implications
1) Any addition of new parameters required a FUSE_SYMVER for
fuse_session_loop_mt() and fuse_loop_mt() as otherwise a read
beyond end-of previous struct size might have happened.
2) Filesystems also might have been recompiled and the developer
might not have noticed the struct extensions and unexpected for
the developer (or people recomliling the code) uninitialized
parameters would have been passed.
Code is updated to have struct fuse_loop_config as an opaque/private
data type for file systems that want version 312
(FUSE_MAKE_VERSION(3, 12)). The deprecated fuse_loop_config_v1
is visible, but should not be used outside of internal
conversion functions
File systems that want version >= 32 < 312 get the previous
struct (through ifdefs) and the #define of fuse_loop_mt
and fuse_session_loop_mt ensures that these recompiled file
systems call into the previous API, which then converts
the struct. This is similar to existing compiled applications
when just libfuse updated, but binaries it is solved with
the FUSE_SYMVER ABI compact declarations.
Results in '-fsanitize=address,undefined ... -O2 -g' that made
compilation to give errors with recent gcc versions.
bernd@t1700bs build-ubuntu>ninja -v
[1/2] ccache gcc -Itest/test_syscalls.p -Itest -I../test -Iinclude -I../include -Ilib -I../lib -I. -I.. -fdiagnostics-color=always -fsanitize=address,undefined -fno-omit-frame-pointer -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -Werror -O2 -g -D_REENTRANT -DHAVE_CONFIG_H -Wno-sign-compare -Wstrict-prototypes -Wmissing-declarations -Wwrite-strings -fno-strict-aliasing -Wno-unused-result -DHAVE_SYMVER_ATTRIBUTE -MD -MQ test/test_syscalls.p/test_syscalls.c.o -MF test/test_syscalls.p/test_syscalls.c.o.d -o test/test_syscalls.p/test_syscalls.c.o -c ../test/test_syscalls.c
FAILED: test/test_syscalls.p/test_syscalls.c.o
ccache gcc -Itest/test_syscalls.p -Itest -I../test -Iinclude -I../include -Ilib -I../lib -I. -I.. -fdiagnostics-color=always -fsanitize=address,undefined -fno-omit-frame-pointer -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -Werror -O2 -g -D_REENTRANT -DHAVE_CONFIG_H -Wno-sign-compare -Wstrict-prototypes -Wmissing-declarations -Wwrite-strings -fno-strict-aliasing -Wno-unused-result -DHAVE_SYMVER_ATTRIBUTE -MD -MQ test/test_syscalls.p/test_syscalls.c.o -MF test/test_syscalls.p/test_syscalls.c.o.d -o test/test_syscalls.p/test_syscalls.c.o -c ../test/test_syscalls.c
In file included from /usr/include/string.h:519,
from ../test/test_syscalls.c:7:
In function ‘strncpy’,
inlined from ‘test_socket’ at ../test/test_syscalls.c:1885:2,
inlined from ‘main’ at ../test/test_syscalls.c:2030:9:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:95:10: error: ‘__builtin_strncpy’ output may be truncated copying 107 bytes from a string of length 1023 [-Werror=stringop-truncation]
95 | return __builtin___strncpy_chk (__dest, __src, __len,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
96 | __glibc_objsize (__dest));
| ~~~~~~~~~~~~~~~~~~~~~~~~~
I disagree a bit on the gcc sanity here, as the code was behaving
correctly and even already checked the string length. But sice
the string length is already verified, that length can be used
for the final strncpy.
Dharmendra Singh [Mon, 28 Feb 2022 11:15:06 +0000 (11:15 +0000)]
Modify structures in libfuse to handle flags beyond 32 bits.
In fuse kernel, 'commit 53db28933e95 ("fuse: extend init flags")'
made the changes to handle flags going beyond 32 bits but i think
changes were not done in libfuse to handle the same.
This patch prepares the ground in libfuse for incoming FUSE kernel
patches (Atomic open + lookup) where flags went beyond 32 bits.
It makes struct same as in fuse kernel resulting in name change of
few fields.
Bernd Schubert [Tue, 22 Mar 2022 21:10:01 +0000 (22:10 +0100)]
passthrough_hp: Fix inode ref in sfs_unlink
sfs_unlink may call do_lookup(), which increases the inode ref count,
but since that function does not return attributes that lookup ref
count won't get automatically decreased.
Frank Dinoff [Mon, 21 Mar 2022 17:13:21 +0000 (13:13 -0400)]
Fix fd leak with clone_fd
do_interrupt would destroy_req on the request without decrementing the
channel's refcount. With clone_fd this could leak file descriptors if
the worker thread holding the cloned fd was destroyed. (Only
max_idle_threads are kept).
Fixed returning an error condition to ioctl(2) (#641)
When returning a negative error code by ->ioctl() to the high level
interface, no error is propagated to the low level, and the reply
message to the kernel is shown as successful.
A negative result is however returned to kernel, so the kernel can
detect the bad condition, but this appears to not be the case since
kernel 5.15.
The proposed fix is more in line with the usual processing of errors
in fuse, taking into account that ioctl(2) always returns a non-negative
value in the absence of errors.
Co-authored-by: Jean-Pierre André <jpandre@users.sourceforge.net>
Document possible NULL paths when directories are removed (#633)
When directories with open handles are removed, the releasedir and
fsyncdir operations might be called with a NULL path. That is because
there is no hiding behavior like for regular files and the nodes get
removed immediately.
Giulio Benetti [Tue, 3 Aug 2021 21:39:46 +0000 (23:39 +0200)]
meson.build: fix wrong .symver detection
As pointed here [1] __has_attribute() is broken for many attributes and
if it doesn't support the specific attribute it returns true, so we
can't really rely on that for this check. This lead to Buildroot
libfuse3 build failure [2] where that shows up with:
```
error: symver is only supported on ELF platforms
```
Indeed Microblaze doesn't support ELF since it doesn't include elfos.h,
but __has_attribute(symver) returns true.
So let's substitute the #ifdef __has_attribute() with a stronger test on
a function foo() with __attribute__((symver ("test@TEST"))).
Amir Goldstein [Tue, 22 Jun 2021 11:03:22 +0000 (14:03 +0300)]
Do not run unlinked files test on passthrough_hp with old kernels
test_syscalls unlinked testfiles check fails on passthourhg_hp without
the kernel commit "fuse: fix illegal access to inode with reused nodeid"
queued for kernel 5.14 [1].
Make this check opt-in and do not run it with kernel version before 5.14.
Amir Goldstein [Sat, 12 Jun 2021 14:37:13 +0000 (17:37 +0300)]
passthrough_hp: excercise reusing inode numbers
Before last unlink() release the reference on inode.fd to allow reuse
of underlying fs inode number, mark the server inode "deleted" and bump
it's generation counter.
When same inode number is found on lookup(), the server inode object will
be reused as well.
Skip this when inode has an open file and when writeback cache is enabled.
This will be used to verify inode reuse bug fix in the kernel.
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Amir Goldstein [Wed, 9 Jun 2021 16:32:46 +0000 (19:32 +0300)]
test/test_syscalls.c: check unlinked testfiles at the end of the test
On some tests on regular files, open an O_PATH fd of the testfile and
record it along side the size and mode and inode.
At the end of all tests, use recorded testfiles info to re-check the size
mode and inode of the unlinked testfiles.
With O_PATH fd, the server does not have to keep the inode alive so FUSE
inode may be stale or bad. Therefore, ESTALE and EIO are valid results
for fstat() on the old testfile fd's, but returning the wrong size or
mode is an invalid result.
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Fix returning d_ino and d_type by readdir(3) in non-plus mode
When not using the readdir_plus mode, the d_type was not returned,
and the use_ino flag was not used for returning d_ino.
This patch fixes the returned values for d_ino and d_type by readdir(3)
The test for the returned value of d_ino has been adjusted to also
take the d_type into consideration and to check the returned values in
both basic readdir and readdir_plus modes. This is done by executing
the passthrough test twice.
Co-authored-by: Jean-Pierre André <jpandre@users.sourceforge.net>
Martin Pärtel [Wed, 3 Feb 2021 09:53:21 +0000 (11:53 +0200)]
Fix returning inode numbers from readdir() in offset==0 mode. (#584)
- Test added for all passthrough examples.
- passthrough.c uses offset==0 mode. The others don't.
- passthrough.c changed to set FUSE_FILL_DIR_PLUS to make the test pass.
- This fixes #583.
Stephen Kitt [Thu, 28 Jan 2021 21:51:10 +0000 (22:51 +0100)]
Ignore "-o nonempty" (#582)
Commit 0bef21e8543d removed "-o nonempty" since mounting over
non-empty directories is always allowed. But this broke tools which
specify "-o nonempty". Since the expected behaviour is the same
anyway, ignoring the "nonempty" option seems safe, and allows programs
specifying "-o nonempty" to continue working with fusermount3.
fusermount: Check for argv[0] being present (#577)
It is perfectly legal to execute a program with argc == 0 and therefore
no argv.
fusermount needs to check for this case, otherwise it will pass a NULL
poiunter to strdup() and cause undefined behavior.
Especially since fusermount is setuid root, we need to extra be careful.
Signed-off-by: Richard Weinberger <richard@nod.at>
Sargun Dhillon [Sun, 27 Dec 2020 11:17:46 +0000 (03:17 -0800)]
util/fusermount.c: Assume the kernel supports UMOUNT_NOFOLLOW (#574)
UMOUNT_NOFOLLOW was added in Kernel 2.6.34. It's been 10 years since it's been added
Kernel 5.9, and 5.10 break this check mechanism[1]. Let's deprecate it.
Zhiqiang Liu [Wed, 11 Nov 2020 02:00:23 +0000 (10:00 +0800)]
buffer.c: correct return value when buf is NULL
In commit d614415a ("buffer.c: check whether buf is
NULL in fuse_bufvec_advance func"), if fuse_bufvec_current
func returns NULL, it returns 1 directly. Actually,
we should return 0 when buf is NULL.
Fixes: d614415a ("buffer.c: check whether buf is NULL in fuse_bufvec_advance func") Signed-off-by: Zhiqiang Liu <liuzhiqiang26@huawei.com> Signed-off-by: Haotian Li <lihaotian9@huawei.com>
Zhiqiang Liu [Thu, 5 Nov 2020 09:24:12 +0000 (17:24 +0800)]
mount.fuse.c: fix potential memory leak in main func
In mount.fuse.c, there are several memory leak problems in
main func. For example, setuid_name is allocated by calling
xstrdup func, however it is not freed before calling execl func.
Signed-off-by: Zhiqiang Liu <liuzhiqiang26@huawei.com> Signed-off-by: Haotian Li <lihaotian9@huawei.com>
In mount.fuse.c, pwd is set by calling getpwnam func.
If the matching entry is not found or an error occurs in
getpwnam func, pwd will be NULL. So we need to check
whether pwd is NULL before accessing it.
Signed-off-by: Zhiqiang Liu <liuzhiqiang26@huawei.com> Signed-off-by: Haotian Li <lihaotian9@huawei.com>
Allow caching symlinks in kernel page cache. (#551)
This commit defines a new capability called `FUSE_CAP_CACHE_SYMLINKS`.
It is off by default but you can now enable it by setting this flag in
in the `want` field of the `fuse_conn_info` structure.
When enabled, the kernel will save symlinks in its page cache,
by making use of the feature introduced in kernel 4.20:
https://github.com/torvalds/linux/commit/5571f1e65486be025f73fa6aa30fb03725d362a2