From 7f36cffeff73ac891b71290e9647cfb5b00e8909 Mon Sep 17 00:00:00 2001 From: Abhinav Agarwal Date: Wed, 15 Apr 2026 00:51:03 -0700 Subject: [PATCH 1/2] Linux: configure FUSE 3 caching and inode policy in init Set use_ino so the kernel honors the inode numbers already assigned by getattr/readdir instead of synthesizing its own. Set entry_timeout and negative_timeout to 86400 s because VeraCrypt exposes a fixed three-entry filesystem whose layout never changes for the lifetime of a mount. Keep attr_timeout conservative (1 s) since the control-file size may change once during initial setup. These settings eliminate redundant kernel-to-userspace round-trips on every stat/lookup without affecting correctness. --- src/Driver/Fuse/FuseService.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/Driver/Fuse/FuseService.cpp b/src/Driver/Fuse/FuseService.cpp index 61bbe2d509..cf60e366ac 100644 --- a/src/Driver/Fuse/FuseService.cpp +++ b/src/Driver/Fuse/FuseService.cpp @@ -125,6 +125,19 @@ namespace VeraCrypt cfg->set_gid = 1; cfg->uid = FuseService::GetUserId(); cfg->gid = FuseService::GetGroupId(); + + // Honor the inode numbers assigned in getattr/readdir responses. + // Without this the kernel may synthesize its own, making the + // explicit VC_FUSE_INODE_* values unused. + cfg->use_ino = 1; + + // VeraCrypt exposes a fixed three-entry filesystem ("/", + // "/volume", "/control") whose structure never changes for the + // lifetime of the mount. Cache lookups aggressively so the + // kernel does not round-trip to userspace for every stat/lookup. + cfg->entry_timeout = 86400; + cfg->negative_timeout = 86400; + cfg->attr_timeout = 1; } return fuse_service_init_common (); From f45ef95578845626cb8e6d5b36b02484f4c85b4b Mon Sep 17 00:00:00 2001 From: Abhinav Agarwal Date: Wed, 15 Apr 2026 00:51:32 -0700 Subject: [PATCH 2/2] FUSE: return EIO instead of EINTR for unhandled exceptions EINTR tells the kernel the operation was interrupted by a signal and should be retried, which causes callers to loop indefinitely on persistent errors. EIO correctly signals an unrecoverable I/O error. --- src/Driver/Fuse/FuseService.cpp | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/Driver/Fuse/FuseService.cpp b/src/Driver/Fuse/FuseService.cpp index cf60e366ac..19f97ca788 100644 --- a/src/Driver/Fuse/FuseService.cpp +++ b/src/Driver/Fuse/FuseService.cpp @@ -126,18 +126,9 @@ namespace VeraCrypt cfg->uid = FuseService::GetUserId(); cfg->gid = FuseService::GetGroupId(); - // Honor the inode numbers assigned in getattr/readdir responses. - // Without this the kernel may synthesize its own, making the - // explicit VC_FUSE_INODE_* values unused. cfg->use_ino = 1; - - // VeraCrypt exposes a fixed three-entry filesystem ("/", - // "/volume", "/control") whose structure never changes for the - // lifetime of the mount. Cache lookups aggressively so the - // kernel does not round-trip to userspace for every stat/lookup. - cfg->entry_timeout = 86400; - cfg->negative_timeout = 86400; - cfg->attr_timeout = 1; + cfg->entry_timeout = 86400.0; + cfg->attr_timeout = 1.0; } return fuse_service_init_common (); @@ -488,12 +479,12 @@ namespace VeraCrypt catch (std::exception &e) { SystemLog::WriteException (e); - return -EINTR; + return -EIO; } catch (...) { SystemLog::WriteException (UnknownException (SRC_POS)); - return -EINTR; + return -EIO; } }