From c14cf18d9fcbb941f9facb4b130ba57e37eb0551 Mon Sep 17 00:00:00 2001 From: FearlessTobi Date: Tue, 27 Feb 2024 17:20:21 +0100 Subject: [PATCH] fs: Use the ProgramRegistry in the FileSystemController I am not really happy how this turned out, but I don't see a better way with the limitations imposed by our current filesystem code. --- src/core/core.cpp | 1 - .../fssrv/fssrv_program_registry_impl.cpp | 12 +++++++ .../fssrv/fssrv_program_registry_impl.h | 10 +++++- .../fssrv/fssrv_program_registry_service.cpp | 7 ++++ .../fssrv/fssrv_program_registry_service.h | 11 +++++-- .../fssrv_program_index_map_info_manager.h | 7 ++-- .../file_sys/fssrv/impl/fssrv_program_info.h | 15 ++++++++- .../impl/fssrv_program_registry_manager.cpp | 12 ++++--- .../impl/fssrv_program_registry_manager.h | 6 +++- .../hle/service/filesystem/filesystem.cpp | 33 ++++++------------- src/core/hle/service/filesystem/filesystem.h | 11 ------- 11 files changed, 75 insertions(+), 50 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 959fe7719d..ee294ed75a 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -471,7 +471,6 @@ struct System::Impl { applet_manager.Reset(); services.reset(); service_manager.reset(); - fs_controller.Reset(); program_registry.Reset(); cheat_engine.reset(); telemetry_session.reset(); diff --git a/src/core/file_sys/fssrv/fssrv_program_registry_impl.cpp b/src/core/file_sys/fssrv/fssrv_program_registry_impl.cpp index f7da4919fa..40ab547669 100644 --- a/src/core/file_sys/fssrv/fssrv_program_registry_impl.cpp +++ b/src/core/file_sys/fssrv/fssrv_program_registry_impl.cpp @@ -35,6 +35,13 @@ Result ProgramRegistryImpl::RegisterProgram(u64 process_id, u64 program_id, u8 s data_size, desc.data(), desc_size)); } +Result ProgramRegistryImpl::RegisterProgramForLoader( + u64 process_id, u64 program_id, std::shared_ptr romfs_factory, + std::shared_ptr save_data_factory) { + R_RETURN(service_impl->RegisterProgramInfoForLoader(process_id, program_id, romfs_factory, + save_data_factory)); +} + Result ProgramRegistryImpl::UnregisterProgram(u64 process_id) { // Check that we're allowed to register R_UNLESS(initial_program_info.IsInitialProgram(system, m_process_id), ResultPermissionDenied); @@ -43,6 +50,11 @@ Result ProgramRegistryImpl::UnregisterProgram(u64 process_id) { R_RETURN(service_impl->UnregisterProgramInfo(process_id)); } +Result ProgramRegistryImpl::GetProgramInfo(std::shared_ptr* out, + u64 process_id) { + R_RETURN(service_impl->GetProgramInfo(out, process_id)); +} + Result ProgramRegistryImpl::SetCurrentProcess(const Service::ClientProcessId& client_pid) { // Set our process id m_process_id = client_pid.pid; diff --git a/src/core/file_sys/fssrv/fssrv_program_registry_impl.h b/src/core/file_sys/fssrv/fssrv_program_registry_impl.h index e8650884de..519447aad5 100644 --- a/src/core/file_sys/fssrv/fssrv_program_registry_impl.h +++ b/src/core/file_sys/fssrv/fssrv_program_registry_impl.h @@ -4,9 +4,11 @@ #pragma once #include "common/common_funcs.h" +#include "core/file_sys/fssrv/impl/fssrv_program_info.h" +#include "core/file_sys/romfs_factory.h" +#include "core/file_sys/savedata_factory.h" #include "core/hle/result.h" #include "core/hle/service/cmif_types.h" -#include "core/file_sys/fssrv/impl/fssrv_program_info.h" namespace Core { class System; @@ -29,7 +31,13 @@ public: Result RegisterProgram(u64 process_id, u64 program_id, u8 storage_id, const InBuffer data, s64 data_size, const InBuffer desc, s64 desc_size); + // This function is not accurate to the Switch, but it is needed to work around current + // limitations in our fs implementation + Result RegisterProgramForLoader(u64 process_id, u64 program_id, + std::shared_ptr romfs_factory, + std::shared_ptr save_data_factory); Result UnregisterProgram(u64 process_id); + Result GetProgramInfo(std::shared_ptr* out, u64 process_id); Result SetCurrentProcess(const Service::ClientProcessId& client_pid); Result SetEnabledProgramVerification(bool enabled); diff --git a/src/core/file_sys/fssrv/fssrv_program_registry_service.cpp b/src/core/file_sys/fssrv/fssrv_program_registry_service.cpp index 8dcd4d61d3..71fba90ba6 100644 --- a/src/core/file_sys/fssrv/fssrv_program_registry_service.cpp +++ b/src/core/file_sys/fssrv/fssrv_program_registry_service.cpp @@ -22,6 +22,13 @@ Result ProgramRegistryServiceImpl::RegisterProgramInfo(u64 process_id, u64 progr data_size, desc, desc_size)); } +Result ProgramRegistryServiceImpl::RegisterProgramInfoForLoader( + u64 process_id, u64 program_id, std::shared_ptr romfs_factory, + std::shared_ptr save_data_factory) { + R_RETURN(m_registry_manager->RegisterProgram(process_id, program_id, 0, nullptr, 0, nullptr, 0, + romfs_factory, save_data_factory)); +} + Result ProgramRegistryServiceImpl::UnregisterProgramInfo(u64 process_id) { R_RETURN(m_registry_manager->UnregisterProgram(process_id)); } diff --git a/src/core/file_sys/fssrv/fssrv_program_registry_service.h b/src/core/file_sys/fssrv/fssrv_program_registry_service.h index 07b444504a..8a3e3df632 100644 --- a/src/core/file_sys/fssrv/fssrv_program_registry_service.h +++ b/src/core/file_sys/fssrv/fssrv_program_registry_service.h @@ -7,6 +7,8 @@ #include "core/file_sys/fs_program_index_map_info.h" #include "core/file_sys/fssrv/impl/fssrv_program_index_map_info_manager.h" #include "core/file_sys/fssrv/impl/fssrv_program_registry_manager.h" +#include "core/file_sys/romfs_factory.h" +#include "core/file_sys/savedata_factory.h" #include "core/hle/result.h" namespace Core { @@ -24,11 +26,16 @@ class ProgramRegistryServiceImpl { public: struct Configuration {}; - ProgramRegistryServiceImpl(Core::System& system_, - Impl::InitialProgramInfo& program_info, const Configuration& cfg); + ProgramRegistryServiceImpl(Core::System& system_, Impl::InitialProgramInfo& program_info, + const Configuration& cfg); Result RegisterProgramInfo(u64 process_id, u64 program_id, u8 storage_id, const void* data, s64 data_size, const void* desc, s64 desc_size); + // This function is not accurate to the Switch, but it is needed to work around current + // limitations in our fs implementation + Result RegisterProgramInfoForLoader( + u64 process_id, u64 program_id, std::shared_ptr romfs_factory, + std::shared_ptr save_data_factory); Result UnregisterProgramInfo(u64 process_id); Result ResetProgramIndexMapInfo(const ProgramIndexMapInfo* infos, int count); diff --git a/src/core/file_sys/fssrv/impl/fssrv_program_index_map_info_manager.h b/src/core/file_sys/fssrv/impl/fssrv_program_index_map_info_manager.h index 699cf4f515..e870b53ff9 100644 --- a/src/core/file_sys/fssrv/impl/fssrv_program_index_map_info_manager.h +++ b/src/core/file_sys/fssrv/impl/fssrv_program_index_map_info_manager.h @@ -13,11 +13,8 @@ namespace FileSys::FsSrv::Impl { -struct ProgramIndexMapInfoEntry : public Common::IntrusiveListBaseNode { - u64 program_id; - u64 base_program_id; - u8 program_index; -}; +struct ProgramIndexMapInfoEntry : public ProgramIndexMapInfo, + public Common::IntrusiveListBaseNode {}; class ProgramIndexMapInfoManager { YUZU_NON_COPYABLE(ProgramIndexMapInfoManager); diff --git a/src/core/file_sys/fssrv/impl/fssrv_program_info.h b/src/core/file_sys/fssrv/impl/fssrv_program_info.h index ae26a49b05..0f48268371 100644 --- a/src/core/file_sys/fssrv/impl/fssrv_program_info.h +++ b/src/core/file_sys/fssrv/impl/fssrv_program_info.h @@ -5,6 +5,7 @@ #include "core/file_sys/fssrv/impl/fssrv_access_control.h" #include "core/file_sys/romfs_factory.h" +#include "core/file_sys/savedata_factory.h" namespace Core { class System; @@ -20,13 +21,19 @@ private: u64 m_program_id; FileSys::StorageId m_storage_id; AccessControl m_access_control; + // Needed to work around current fs limitations + std::shared_ptr m_romfs_factory; + std::shared_ptr m_save_data_factory; public: ProgramInfo(u64 process_id, u64 program_id, u8 storage_id, const void* data, s64 data_size, - const void* desc, s64 desc_size) + const void* desc, s64 desc_size, std::shared_ptr romfs_factory, + std::shared_ptr save_data_factory) : m_process_id(process_id), m_access_control(data, data_size, desc, desc_size) { m_program_id = program_id; m_storage_id = static_cast(storage_id); + m_romfs_factory = romfs_factory; + m_save_data_factory = save_data_factory; } ProgramInfo(const void* data, s64 data_size, const void* desc, s64 desc_size) @@ -49,6 +56,12 @@ public: AccessControl& GetAccessControl() { return m_access_control; } + std::shared_ptr GetRomFsFactory() { + return m_romfs_factory; + } + std::shared_ptr GetSaveDataFactory() { + return m_save_data_factory; + } }; struct ProgramInfoNode : public Common::IntrusiveListBaseNode { diff --git a/src/core/file_sys/fssrv/impl/fssrv_program_registry_manager.cpp b/src/core/file_sys/fssrv/impl/fssrv_program_registry_manager.cpp index 7120e4b8b5..87c584084c 100644 --- a/src/core/file_sys/fssrv/impl/fssrv_program_registry_manager.cpp +++ b/src/core/file_sys/fssrv/impl/fssrv_program_registry_manager.cpp @@ -11,9 +11,10 @@ ProgramRegistryManager::ProgramRegistryManager(Core::System& system_, InitialProgramInfo& program_info) : m_initial_program_info{program_info}, system{system_} {} -Result ProgramRegistryManager::RegisterProgram(u64 process_id, u64 program_id, u8 storage_id, - const void* data, s64 data_size, const void* desc, - s64 desc_size) { +Result ProgramRegistryManager::RegisterProgram( + u64 process_id, u64 program_id, u8 storage_id, const void* data, s64 data_size, + const void* desc, s64 desc_size, std::shared_ptr romfs_factory, + std::shared_ptr save_data_factory) { // Allocate a new node std::unique_ptr new_node(new ProgramInfoNode()); R_UNLESS(new_node != nullptr, ResultAllocationMemoryFailedInProgramRegistryManagerA); @@ -21,8 +22,9 @@ Result ProgramRegistryManager::RegisterProgram(u64 process_id, u64 program_id, u // Create a new program info { // Allocate the new info - std::shared_ptr new_info = std::make_shared( - process_id, program_id, storage_id, data, data_size, desc, desc_size); + std::shared_ptr new_info = + std::make_shared(process_id, program_id, storage_id, data, data_size, desc, + desc_size, romfs_factory, save_data_factory); R_UNLESS(new_info != nullptr, ResultAllocationMemoryFailedInProgramRegistryManagerA); // Set the info in the node diff --git a/src/core/file_sys/fssrv/impl/fssrv_program_registry_manager.h b/src/core/file_sys/fssrv/impl/fssrv_program_registry_manager.h index 36593244c3..2275177e29 100644 --- a/src/core/file_sys/fssrv/impl/fssrv_program_registry_manager.h +++ b/src/core/file_sys/fssrv/impl/fssrv_program_registry_manager.h @@ -7,6 +7,8 @@ #include "common/common_funcs.h" #include "common/intrusive_list.h" #include "core/file_sys/fssrv/impl/fssrv_program_info.h" +#include "core/file_sys/romfs_factory.h" +#include "core/file_sys/savedata_factory.h" namespace Core { class System; @@ -22,7 +24,9 @@ public: explicit ProgramRegistryManager(Core::System& system_, InitialProgramInfo& program_info); Result RegisterProgram(u64 process_id, u64 program_id, u8 storage_id, const void* data, - s64 data_size, const void* desc, s64 desc_size); + s64 data_size, const void* desc, s64 desc_size, + std::shared_ptr romfs_factory = nullptr, + std::shared_ptr save_data_factory = nullptr); Result UnregisterProgram(u64 process_id); Result GetProgramInfo(std::shared_ptr* out, u64 process_id); diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index bf2e864d9b..14e7139b8c 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -298,13 +298,8 @@ FileSystemController::~FileSystemController() = default; Result FileSystemController::RegisterProcess( ProcessId process_id, ProgramId program_id, std::shared_ptr&& romfs_factory) { - std::scoped_lock lk{registration_lock}; - - registrations.emplace(process_id, Registration{ - .program_id = program_id, - .romfs_factory = std::move(romfs_factory), - .save_data_factory = CreateSaveDataFactory(program_id), - }); + system.GetProgramRegistry().RegisterProgramForLoader( + process_id, program_id, std::move(romfs_factory), CreateSaveDataFactory(program_id)); LOG_DEBUG(Service_FS, "Registered for process {}", process_id); return ResultSuccess; @@ -313,31 +308,28 @@ Result FileSystemController::RegisterProcess( Result FileSystemController::OpenProcess( ProgramId* out_program_id, std::shared_ptr* out_save_data_controller, std::shared_ptr* out_romfs_controller, ProcessId process_id) { - std::scoped_lock lk{registration_lock}; - - const auto it = registrations.find(process_id); - if (it == registrations.end()) { + std::shared_ptr out_info; + if (system.GetProgramRegistry().GetProgramInfo(&out_info, process_id) != ResultSuccess) { return FileSys::ResultTargetNotFound; } - *out_program_id = it->second.program_id; + *out_program_id = out_info->GetProgramId(); *out_save_data_controller = - std::make_shared(system, it->second.save_data_factory); + std::make_shared(system, out_info->GetSaveDataFactory()); *out_romfs_controller = - std::make_shared(it->second.romfs_factory, it->second.program_id); + std::make_shared(out_info->GetRomFsFactory(), out_info->GetProgramId()); return ResultSuccess; } void FileSystemController::SetPackedUpdate(ProcessId process_id, FileSys::VirtualFile update_raw) { LOG_TRACE(Service_FS, "Setting packed update for romfs"); - std::scoped_lock lk{registration_lock}; - const auto it = registrations.find(process_id); - if (it == registrations.end()) { + std::shared_ptr out_info; + if (system.GetProgramRegistry().GetProgramInfo(&out_info, process_id) != ResultSuccess) { return; } - it->second.romfs_factory->SetPackedUpdate(std::move(update_raw)); + out_info->GetRomFsFactory()->SetPackedUpdate(std::move(update_raw)); } std::shared_ptr FileSystemController::OpenSaveDataController() { @@ -715,11 +707,6 @@ void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool ove } } -void FileSystemController::Reset() { - std::scoped_lock lk{registration_lock}; - registrations.clear(); -} - void LoopProcess(Core::System& system) { auto server_manager = std::make_unique(system); diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h index 718500385b..22ea3468e1 100644 --- a/src/core/hle/service/filesystem/filesystem.h +++ b/src/core/hle/service/filesystem/filesystem.h @@ -121,20 +121,9 @@ public: // above is called. void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite = true); - void Reset(); - private: std::shared_ptr CreateSaveDataFactory(ProgramId program_id); - struct Registration { - ProgramId program_id; - std::shared_ptr romfs_factory; - std::shared_ptr save_data_factory; - }; - - std::mutex registration_lock; - std::map registrations; - std::unique_ptr sdmc_factory; std::unique_ptr bis_factory;