From eca63ccb1006fdec79f6392d38bd74739e1371df Mon Sep 17 00:00:00 2001 From: Takoroka <137927095+Takoroka@users.noreply.github.com> Date: Sun, 1 Nov 2026 12:18:19 -0500 Subject: vfs_real: forget a path when its file is gone The path cache holds weak references, but nothing erased an entry once its file was destroyed, so every path ever opened stayed in the cache until the filesystem was destroyed (title 1's loose RomFS: 206k paths, 24 MB of keys, kept after the game stops). The entry is erased when the file's last reference is dropped, unless the path was opened again meanwhile. --- src/core/file_sys/vfs/vfs_real.cpp | 10 ++++++++-- src/core/file_sys/vfs/vfs_real.h | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'src/core') diff --git a/src/core/file_sys/vfs/vfs_real.cpp b/src/core/file_sys/vfs/vfs_real.cpp index 5b5b54017c..e178bcab58 100644 --- a/src/core/file_sys/vfs/vfs_real.cpp +++ b/src/core/file_sys/vfs/vfs_real.cpp @@ -257,7 +257,8 @@ std::unique_lock RealVfsFilesystem::RefreshReference(const std::stri return lk; } -void RealVfsFilesystem::DropReference(std::unique_ptr&& reference) { +void RealVfsFilesystem::DropReference(std::unique_ptr&& reference, + const std::string& path) { if (in_dtor) return; @@ -266,6 +267,11 @@ void RealVfsFilesystem::DropReference(std::unique_ptr&& reference // Remove from list. this->RemoveReferenceFromListLocked(*reference); + // Forget the path, unless it was opened again since this file's last reference went away. + if (const auto it = cache.find(path); it != cache.end() && it->second.expired()) { + cache.erase(it); + } + // Close the file. if (reference->file) { reference->file.reset(); @@ -316,7 +322,7 @@ RealVfsFile::RealVfsFile(RealVfsFilesystem& base_, std::unique_ptr RefreshReference(const std::string& path, OpenMode perms, FileReference& reference); - void DropReference(std::unique_ptr&& reference); + void DropReference(std::unique_ptr&& reference, const std::string& path); private: friend class RealVfsDirectory; -- cgit v1.2.3