aboutsummaryrefslogtreecommitdiffstats
path: root/lib/fuse.c
AgeCommit message (Collapse)AuthorLines
2023-06-08Remove unnecessary `_GNU_SOURCE` in `fuse.c` (#787)Matthias Görgens-4/+0
We stopped using pthread_rwlock_t in 3fecccca989328ed2c0ac68860ee1ceec0673972, so we don't need `_GNU_SOURCE` anymore in `fuse.c`
2023-05-11Fix issue #746. (#782)Peri-0/+14
Added a secondary check in fuse_lib_unlink() after hide_node() to check again under a lock if the (now hidden) file is still open. If not then delete it. This should synchronise fuse_lib_unlink() with fuse_lib_release(), when nullpath_ok is set.
2023-04-14Fix memory leak in high level API (#781)Matthias Görgens-2/+1
Previously, in the high level API if we received a signal between setting up signal handlers and processing INIT, we would leak ``` $ ./example/hello -s -d -f mountpoint/ [9/9] Linking target example/hello_ll FUSE library version: 3.14.1 nullpath_ok: 0 ================================================================= ==178330==ERROR: LeakSanitizer: detected memory leaks Direct leak of 352 byte(s) in 1 object(s) allocated from: #0 0x7fbb19abf411 in __interceptor_calloc /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:77 #1 0x7fbb1a0efd3b in fuse_fs_new ../lib/fuse.c:4814 #2 0x7fbb1a0f02b5 in fuse_new_31 ../lib/fuse.c:4913 #3 0x7fbb1a10ec5e in fuse_main_real ../lib/helper.c:345 #4 0x5625db8ab418 in main ../example/hello.c:176 #5 0x7fbb1983c78f (/usr/lib/libc.so.6+0x2378f) SUMMARY: AddressSanitizer: 352 byte(s) leaked in 1 allocation(s). ``` That's because `fuse_lowlevel.c`s `fuse_session_destroy` would only call the user supplied `op.destroy`, if INIT had been processed, but the high level API relied on `op.destroy` to free `f->fs`. This patch moves the freeing into `fuse_destroy` that will always be called by our high-level API.
2023-03-03Enable parallel direct writes on the same file.Dharmendra singh-1/+8
Right now fuse kernel serializes direct writes on the same file. This serialization is good for such FUSE implementations which rely on the inode lock to avoid any data inconsistency issues but it hurts badly such FUSE implementations which have their own mechanism of dealing with cache/data integrity and can handle parallel direct writes on the same file. This patch allows parallel direct writes on the same file to be enabled with the help of a flag FOPEN_PARALLEL_DIRECT_WRITES. FUSE implementations which want to use this feature can set this flag during fuse init. Default behaviour remains same i.e no parallel direct writes on the same file. Corresponding fuse kernel patch(Merged). https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=v6.2&id=153524053bbb0d27bb2e0be36d1b46862e9ce74c
2023-01-28Install a the configure_file (config.h) and use in headersBernd Schubert-1/+1
This addresses: https://github.com/libfuse/libfuse/issues/724 HAVE_LIBC_VERSIONED_SYMBOLS configures the library if to use versioned symbols and is set at meson configuration time. External filesystems (the main target, actually) include fuse headers and the preprocessor then acts on HAVE_LIBC_VERSIONED_SYMBOLS. Problem was now that 'config.h' was not distributed with libfuse and so HAVE_LIBC_VERSIONED_SYMBOLS was never defined with external tools and the preprocessor did the wrong decision. This commit also increases the the minimal meson version, as this depends on meson feature only available in 0.50 <quote 'meson' > WARNING: Project specifies a minimum meson_ version '>= 0.42' but uses features which were added in newer versions: * 0.50.0: {'install arg in configure_file'} </quote> Additionally the config file has been renamed to "fuse_config.h" to avoid clashes - 'config.h' is not very specific.
2023-01-13Fix loading of FUSE modulesGoswin von Brederlow-3/+3
dlsym returns the address of the module factory symbol, not the actual function (#722) pointer. Change the type of `factory` to `fuse_module_factory_t*` to reflect this and then dereference it when registering the module. This is a followup to d92bf83, which introduced a NULL pointer dereference when dlsym returns NULL, and 8ec7fd9, which reverted it back to not dereferencing the symbol at all. Fixes: #721 Co-authored-by: Goswin von Brederlow <brederlo@q-leap.de>
2023-01-04Remove partial locking of paths when using high-level APIKyle Lippincott-54/+10
As described in https://github.com/libfuse/libfuse/issues/695 and below, partial locking of paths can cause a deadlock. Partial locking was added to prevent starvation, but it's unclear what specific cases of starvation were of concern. As far as I was able to determine, since we support reader locks that give priority to writers (to prevent starvation), this means that to starve the queue element, we'd need a constant stream of queued requests that lock the path for write. Write locks are used when the element is being (potentially) removed, so this stream of requests that starve the `rename` or `lock` operations seems unlikely. ### Summarizing issue #695 The high-level API handles locking of the node structures it maintains to prevent concurrent requests from deleting nodes that are in use by other requests. This means that requests that might remove these structs (`rmdir`, `rename`, `unlink`, `link`) need to acquire an (internally managed - not pthread) exclusive lock before doing so. In the case where the lock is already held (for read or for write), the operation is placed onto a queue of waiters. On every unlock, the queue is reinspected for any element that might now be able to make progress. Since `rename` and `link` involve two paths, when added to the queue, a single queue entry requires that we lock two different paths. There was, prior to this change, support for partially locking the first queue element if it had two paths to lock. This partial locking can cause a deadlock: - set up a situation where the first element in the queue is partially locked (such as by holding a reader lock on one of the paths being renamed, but not the other). For example: `/rmthis/foo/foo.txt` [not-yet-locked] and `/rmthis/bar/bar.txt` [locked] - add an `rmdir` for an ancestor directory of the not-yet-locked path to the queue. In this example: `/rmthis` After getting into this situation, we have the following `treelock` values: - `/rmthis`: 1 current reader (due to the locked `/rmthis/bar/bar.txt`), one waiting writer (`rmdir`): no new readers will acquire a read lock here. - `/rmthis/bar`: 1 reader (the locked `/rmthis/bar/bar.txt`) - `/rmthis/bar/bar.txt`: 1 writer (the locked `/rmthis/bar/bar.txt`) This is deadlocked, because the partial lock will never be able to be completely locked, as doing so would require adding a reader lock on `/rmthis`, and that will be rejected due to write lock requests having priority -- until the writer succeeds in locking it, no new readers can be added. However, the writer (the `rmdir`) will never be able to acquire its write lock, as the reader lock will never be dropped -- there's no support for downgrading a partially locked element to be unlocked, the only state change that's allowed involves it becoming completely locked.
2023-01-04Move try_get_path2 earlier in the fileKyle Lippincott-21/+21
2022-09-04API update for fuse_loop_config additionsBernd Schubert-7/+33
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. Signed-off-by: Bernd Schubert <bschubert@ddn.com>
2022-07-02Remove member m from fuse_fs (#684)Nozomi Miyamori-6/+0
fuse_fs.m is no longer used. Modules are now managed by fuse_modules. fix: free dangling pointer of module #683
2022-03-14Merge branch 'master' into fopen_noflushNikolaus Rath-2/+4
2022-02-09Fixed returning an error condition to ioctl(2) (#641)Jean-Pierre André-0/+2
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>
2022-01-11Avoid ENOENT response when recently invalidated fuse_ino_t is received from ↵Ken Schalk-2/+2
the kernel (#636)
2022-01-03Add no_rofd_flush mount optionAmir Goldstein-0/+6
To disable flush for read-only fd. Signed-off-by: Amir Goldstein <amir73il@gmail.com>
2021-08-25remove executable file mode bit from source filesa1346054-0/+0
2021-03-18Fix returning d_ino and d_type by readdir(3) in non-plus modeJean-Pierre André-0/+5
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>
2021-02-03Fix returning inode numbers from readdir() in offset==0 mode. (#584)Martin Pärtel-1/+1
- 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.
2020-11-17fix errno comparisonhuman-1/+1
this affected `-o remember` in single-thread mode, it could prematurely exit if a signal was received # start an example filesystem from example/ ./passthrough -f -s -o remember=5 ./mnt # make the poll() call return with EINTR pkill -PIPE passthrough
2020-10-29remove fuse_mutex_initRosen Penev-2/+2
This seems to have been added before 2006 to fix a uclibc bug. It doesn't seem to be the case anymore so just get rid of it. Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-09-11Implement GCC 10 style symbol versioning (#545)Tom Callaway-4/+4
2019-11-03Implement lseek operation (#457)Yuri Per-0/+43
2019-09-04Introduce callback for loggingStefan Hajnoczi-74/+75
Introduce an API for custom log handler functions. This allows libfuse applications to send messages to syslog(3) or other logging systems. See include/fuse_log.h for details. Convert libfuse from fprintf(stderr, ...) to log_fuse(level, ...). Most messages are error messages with FUSE_LOG_ERR log level. There are also some debug messages which now use the FUSE_LOG_DEBUG log level. Note that lib/mount_util.c is used by both libfuse and fusermount3. Since fusermount3 does not link against libfuse, we cannot call fuse_log() from lib/mount_util.c. This file will continue to use fprintf(stderr, ...) until someone figures out how to split it up. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2019-08-29Avoid gcc 9.1 strncpy(3) warnings (#447)Stefan Hajnoczi-1/+1
Recent GCC releases have warnings related to common strncpy(3) bugs. These warnings can be avoided by explicitly NUL-terminating the buffer or using memcpy(3) when the intention is to copy just the characters without the NUL terminator. This commit fixes the following warnings: [1/27] Compiling C object 'test/9f86d08@@test_syscalls@exe/test_syscalls.c.o'. In function ‘test_socket’, inlined from ‘main’ at ../test/test_syscalls.c:1899:9: ../test/test_syscalls.c:1760:2: warning: ‘strncpy’ output may be truncated copying 108 bytes from a string of length 1023 [-Wstringop-truncation] 1760 | strncpy(su.sun_path, testsock, sizeof(su.sun_path)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [2/27] Compiling C object 'lib/76b5a35@@fuse3@sha/fuse.c.o'. ../lib/fuse.c: In function ‘add_name’: ../lib/fuse.c:968:2: warning: ‘strncpy’ output truncated before terminating nul copying as many bytes from a string as its length [-Wstringop-truncation] 968 | strncpy(s, name, len); | ^~~~~~~~~~~~~~~~~~~~~ ../lib/fuse.c:944:15: note: length computed here 944 | size_t len = strlen(name); | ^~~~~~~~~~~~ [3/27] Compiling C object 'lib/76b5a35@@fuse3@sha/fuse_lowlevel.c.o'. ../lib/fuse_lowlevel.c: In function ‘fuse_add_direntry’: ../lib/fuse_lowlevel.c:288:2: warning: ‘strncpy’ output truncated before terminating nul copying as many bytes from a string as its length [-Wstringop-truncation] 288 | strncpy(dirent->name, name, namelen); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../lib/fuse_lowlevel.c:276:12: note: length computed here 276 | namelen = strlen(name); | ^~~~~~~~~~~~ ../lib/fuse_lowlevel.c: In function ‘fuse_add_direntry_plus’: ../lib/fuse_lowlevel.c:381:2: warning: ‘strncpy’ output truncated before terminating nul copying as many bytes from a string as its length [-Wstringop-truncation] 381 | strncpy(dirent->name, name, namelen); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../lib/fuse_lowlevel.c:366:12: note: length computed here 366 | namelen = strlen(name); | ^~~~~~~~~~~~ Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2019-06-06Don't return expression in function returning voidMichael Forney-1/+1
This is a constraint violation in ISO C[0]. [0] http://port70.net/~nsz/c/c11/n1570.html#6.8.6.4p1
2019-06-06Don't omit second operand to `?` operatorMichael Forney-1/+1
This is a GNU C extension.
2019-03-11Defined the (*ioctl)() commands as unsigned int (#381)Jean-Pierre André-6/+7
Instead of the Posix ioctl(2) command, Linux uses its own variant of ioctl() in which the commands are requested as "unsigned long" and truncated to 32 bits by the fuse kernel module. Transmitting the commands to user space file systems as "unsigned int" is a workaround for processing ioctl() commands which do not fit into a signed int.
2019-02-13fuse_free_buf(): to check flags of each buffer, rather than only 0thAlbert Chen-1/+1
Fixes: #360
2018-12-22fix memory leak in print_module_help methodalex-0/+1
2018-11-19libfuse: add copy_file_range() supportNiels de Vos-0/+63
Add support for the relatively new copy_file_range() syscall. Backend filesystems can now implement an efficient way of cloning/duplicating data ranges within files. See 'man 2 copy_file_range' for more details.
2018-08-26Fix memory leak of FUSE modulesRostislav-3/+23
2018-08-26Fix invalid free of memory pointer in 'struct fuse_buf'Rostislav-1/+2
2018-07-25Remove unused member of 'struct fuse_dh'Rostislav Skudnov-1/+0
2018-07-21Fix readdir() bug when a non-zero offset is specified in filler (#269)Rostislav-11/+15
The bug occurs when a filesystem client reads a directory until the end, seeks using seekdir() to some valid non-zero position and calls readdir(). A valid 'struct dirent *' is expected, but NULL is returned instead. Pseudocode demonstrating the bug: DIR *dp = opendir("some_dir"); struct dirent *de = readdir(dp); /* Get offset of the second entry */ long offset = telldir(dp); /* Read directory until the end */ while (de) de = readdir(de); seekdir(dp, offset); de = readdir(dp); /* de must contain the second entry, but NULL is returned instead */ The reason of the bug is that when the end of directory is reached, the kernel calls FUSE_READDIR op with an offset at the end of directory, so the filesystem's .readdir callback never calls the filler function, and we end up with dh->filled set to 1. After seekdir(), FUSE_READDIR is called again with a new offset, but this time the filesystem's .readdir callback is never called, and an empty reply is returned. Fix by setting dh->filled to 1 only when zero offsets are given to filler function.
2018-05-18rename: perform user mode dir loop check when not done in kernelBill Zissimooulos-10/+12
Fix conditionals as per maintainer's request.
2018-05-18rename: perform user mode dir loop check when not done in kernelBill Zissimooulos-3/+59
Linux performs the dir loop check (rename(a, a/b/c) or rename(a/b/c, a), etc.) in kernel. Unfortunately other systems do not perform this check (e.g. FreeBSD). This results in a deadlock in get_path2, because libfuse did not expect to handle such cases. We add a check_dir_loop function that performs the dir loop check in user mode and enable it on systems that need it.
2018-02-09Fix uninitialised read in fuse_new_30() (#231) (#234)Ashley Pittman-0/+3
Ensure that conf is always zero before it's read from to prevent sporadic failure at startup if higher layers were build against version 3.0 Signed-off-by: Ashley Pittman <ashley.m.pittman@intel.com>
2017-11-03Backed out d92bf83Nikolaus Rath-1/+1
This change is bogus. fuse_module_factory_t is already a pointer type. Additionally, if dlsym returns NULL, then you will be dereferencing it causing a segfault. In my testing, a segfault will happen even if dlsym returns successfully. Thanks to Michael Theall for spotting!
2017-09-27Adding pointer dereferencing after calling dlsym()Sangwoo Moon-1/+1
dlsym() resolves the location of the loaded symbol, therefore dlsym() returns the type (fuse_module_factory_t *), not (fuse_module_factory_t). Added pinter dereferencing to correctly refer the factory function.
2017-09-25fuse_lib_ioctl(): don't call memcpy with NULL argumentNikolaus Rath-1/+1
This was detected by using clang's undefined behavior sanitizer, but didn't seem to cause problems in practice.
2017-09-19Make *_loop_mt() available in version 3.0 againNikolaus Rath-1/+1
The old versions of these symbols were defined with version tag FUSE_3.0, so this is what we have to use in the .symver directive.
2017-09-19Don't use external symbol names in internal filesNikolaus Rath-4/+1
The fuse_session_loop_mt() and fuse_loop_mt() symbols are only visible when linking against the shared object. The code in lib/, however, is compiled *into* the shared object and should thus use the internal names of these functions. Surprisingly enough, the code still worked before - but only when link time optimization was disabled. Unfortunately, we still can't compile with LTO because it seems that enabling LTO somehow makes the tagged symbols vanish. Without lto, we have: $ nm lib/libfuse3.so | grep fuse_new 0000000000011070 T fuse_new_30 0000000000010a00 t fuse_new_31 0000000000011070 T fuse_new@FUSE_3.0 0000000000010a00 T fuse_new@@FUSE_3.1 and with LTO: $ nm lib/libfuse3.so | grep fuse_new 0000000000019a70 T fuse_new_30 0000000000019270 t fuse_new_31 See also issue #198.
2017-08-24Add idle_threads mount option.Joseph Dodge-2/+14
2017-08-24Allow inode cache invalidation in high-level APISławek Rudnicki-0/+40
We re-introduce the functionality of invalidating the caches for an inode specified by path by adding a new routine fuse_invalidate_path. This is useful for network-based file systems which use the high-level API, enabling them to notify the kernel about external changes. This is a revival of Miklos Szeredi's original code for the fuse_invalidate routine.
2017-08-22Allow building without iconv.Nikolaus Rath-0/+6
cfg.has('HAVE_ICONV') was always true.
2017-08-14directly call fuse_new_31() instead of fuse_new() internallyuserwithuid-2/+0
this fixes building with lto, which failed since commit 503e32d01e4db00e90d7acfd81ab05386559069f
2017-08-11fuse_lib_init(): don't set FUSE_CAP_EXPORT_SUPPORT unconditionallyNikolaus Rath-1/+2
FreeBSD kernel does not support this.
2017-07-13Only declare fuse_new_30() when FUSE_USE_VERSION == 30Nikolaus Rath-24/+26
This function shouldn't be called when using a newer fuse version, so we should not define it in that case.
2017-07-13fuse_new_30(): call fuse_new_31(), not fuse_new()Nikolaus Rath-1/+1
I believe this function call is resolved by the compiler, not the linker, so this seems safer. Thanks to Chris Clayton for spotting this.
2017-07-08Fixup symbol versioning for GCC 4.xNikolaus Rath-4/+7
GCC 4.8 doesn't like to rename fuse_new_30 to fuse_new, if we also define an implementation for fuse_new.
2017-07-08Added public fuse_lib_help(), bumped minor versionNikolaus Rath-40/+85