On 5/14/25 14:14, Allison Karlitskaya wrote:
FILESYSTEM_MAX_STACK_DEPTH is defined privately inside of the kernel,
but you need to know its value to properly implement fd passthrough on a
FUSE filesystem. So far most users have been assuming its current value
of 2, but there's nothing that says that it won't change.
Use one of the unused fields in fuse_init_in to add a max_stack_depth
uint32_t (matching the max_stack_depth uint32_t in fuse_init_out). If
CONFIG_FUSE_PASSTHROUGH is configured then this is set to the maximum
value that the kernel will accept for the corresponding field in
fuse_init_out (ie: FILESYSTEM_MAX_STACK_DEPTH).
Let's not treat this as an ABI change: this struct is zero-initialized
and the maximum max_stack_depth is non-zero (and always will be) so
userspace can easily find out for itself if the value is present in the
struct or not.
Signed-off-by: Allison Karlitskaya <allison.karlitskaya@xxxxxxxxxx>
---
fs/fuse/inode.c | 4 +++-
include/uapi/linux/fuse.h | 3 ++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index fd48e8d37f2e..46fd37eec9ae 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -1497,8 +1497,10 @@ void fuse_send_init(struct fuse_mount *fm)
#endif
if (fm->fc->auto_submounts)
flags |= FUSE_SUBMOUNTS;
- if (IS_ENABLED(CONFIG_FUSE_PASSTHROUGH))
+ if (IS_ENABLED(CONFIG_FUSE_PASSTHROUGH)) {
flags |= FUSE_PASSTHROUGH;
+ ia->in.max_stack_depth = FILESYSTEM_MAX_STACK_DEPTH;
+ }
/*
* This is just an information flag for fuse server. No need to check
diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h
index 5ec43ecbceb7..eb5d77d50176 100644
--- a/include/uapi/linux/fuse.h
+++ b/include/uapi/linux/fuse.h
@@ -895,7 +895,8 @@ struct fuse_init_in {
uint32_t max_readahead;
uint32_t flags;
uint32_t flags2;
- uint32_t unused[11];
+ uint32_t max_stack_depth;
Objections to make this a uint8_t? In fuse_init_out it just had slipped
through in review. (And I wonder a bit if we should post change it in
fuse_init_out.
Thanks,
Bernd