linux/fs/fuse
Jingbo Xu e022f6a1c7 fuse: add support for explicit export disabling
open_by_handle_at(2) can fail with -ESTALE with a valid handle returned
by a previous name_to_handle_at(2) for evicted fuse inodes, which is
especially common when entry_valid_timeout is 0, e.g. when the fuse
daemon is in "cache=none" mode.

The time sequence is like:

	name_to_handle_at(2)	# succeed
	evict fuse inode
	open_by_handle_at(2)	# fail

The root cause is that, with 0 entry_valid_timeout, the dput() called in
name_to_handle_at(2) will trigger iput -> evict(), which will send
FUSE_FORGET to the daemon.  The following open_by_handle_at(2) will send
a new FUSE_LOOKUP request upon inode cache miss since the previous inode
eviction.  Then the fuse daemon may fail the FUSE_LOOKUP request with
-ENOENT as the cached metadata of the requested inode has already been
cleaned up during the previous FUSE_FORGET.  The returned -ENOENT is
treated as -ESTALE when open_by_handle_at(2) returns.

This confuses the application somehow, as open_by_handle_at(2) fails
when the previous name_to_handle_at(2) succeeds.  The returned errno is
also confusing as the requested file is not deleted and already there.
It is reasonable to fail name_to_handle_at(2) early in this case, after
which the application can fallback to open(2) to access files.

Since this issue typically appears when entry_valid_timeout is 0 which
is configured by the fuse daemon, the fuse daemon is the right person to
explicitly disable the export when required.

Also considering FUSE_EXPORT_SUPPORT actually indicates the support for
lookups of "." and "..", and there are existing fuse daemons supporting
export without FUSE_EXPORT_SUPPORT set, for compatibility, we add a new
INIT flag for such purpose.

Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Jingbo Xu <jefflexu@linux.alibaba.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
2024-03-06 09:56:34 +01:00
..
acl.c fs.idmapped.v6.3 2023-02-20 11:53:11 -08:00
control.c fuse: convert to new timestamp accessors 2023-10-18 14:08:21 +02:00
cuse.c driver core: class: remove module * from class_create() 2023-03-17 15:16:33 +01:00
dax.c fuse: dax: set fc->dax to NULL in fuse_dax_conn_free() 2023-12-04 10:16:53 +01:00
dev.c fuse: implement ioctls to manage backing files 2024-03-05 13:40:36 +01:00
dir.c fuse: fix typo for fuse_permission comment 2024-03-06 09:56:11 +01:00
file.c fuse: Convert fuse_writepage_locked to take a folio 2024-03-05 14:07:24 +01:00
fuse_i.h fuse: don't unhash root 2024-03-05 13:40:43 +01:00
inode.c fuse: add support for explicit export disabling 2024-03-06 09:56:34 +01:00
ioctl.c fuse: ioctl: translate ENOSYS in outarg 2023-06-21 11:17:36 +02:00
iomode.c fuse: implement open in passthrough mode 2024-03-05 13:40:42 +01:00
Kconfig fuse: introduce FUSE_PASSTHROUGH capability 2024-02-23 17:36:32 +01:00
Makefile fuse: introduce FUSE_PASSTHROUGH capability 2024-02-23 17:36:32 +01:00
passthrough.c fuse: implement passthrough for mmap 2024-03-05 13:40:42 +01:00
readdir.c fuse: convert to new timestamp accessors 2023-10-18 14:08:21 +02:00
virtio_fs.c virtio_fs: remove duplicate check if queue is broken 2024-03-05 13:40:43 +01:00
xattr.c fuse: move fuse_xattr_handlers to .rodata 2023-10-09 16:24:18 +02:00