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.
This commit is contained in:
FearlessTobi 2024-02-27 17:20:21 +01:00
parent 1a52924eff
commit c14cf18d9f
11 changed files with 75 additions and 50 deletions

View file

@ -471,7 +471,6 @@ struct System::Impl {
applet_manager.Reset(); applet_manager.Reset();
services.reset(); services.reset();
service_manager.reset(); service_manager.reset();
fs_controller.Reset();
program_registry.Reset(); program_registry.Reset();
cheat_engine.reset(); cheat_engine.reset();
telemetry_session.reset(); telemetry_session.reset();

View file

@ -35,6 +35,13 @@ Result ProgramRegistryImpl::RegisterProgram(u64 process_id, u64 program_id, u8 s
data_size, desc.data(), desc_size)); data_size, desc.data(), desc_size));
} }
Result ProgramRegistryImpl::RegisterProgramForLoader(
u64 process_id, u64 program_id, std::shared_ptr<FileSys::RomFSFactory> romfs_factory,
std::shared_ptr<FileSys::SaveDataFactory> save_data_factory) {
R_RETURN(service_impl->RegisterProgramInfoForLoader(process_id, program_id, romfs_factory,
save_data_factory));
}
Result ProgramRegistryImpl::UnregisterProgram(u64 process_id) { Result ProgramRegistryImpl::UnregisterProgram(u64 process_id) {
// Check that we're allowed to register // Check that we're allowed to register
R_UNLESS(initial_program_info.IsInitialProgram(system, m_process_id), ResultPermissionDenied); 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)); R_RETURN(service_impl->UnregisterProgramInfo(process_id));
} }
Result ProgramRegistryImpl::GetProgramInfo(std::shared_ptr<Impl::ProgramInfo>* out,
u64 process_id) {
R_RETURN(service_impl->GetProgramInfo(out, process_id));
}
Result ProgramRegistryImpl::SetCurrentProcess(const Service::ClientProcessId& client_pid) { Result ProgramRegistryImpl::SetCurrentProcess(const Service::ClientProcessId& client_pid) {
// Set our process id // Set our process id
m_process_id = client_pid.pid; m_process_id = client_pid.pid;

View file

@ -4,9 +4,11 @@
#pragma once #pragma once
#include "common/common_funcs.h" #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/result.h"
#include "core/hle/service/cmif_types.h" #include "core/hle/service/cmif_types.h"
#include "core/file_sys/fssrv/impl/fssrv_program_info.h"
namespace Core { namespace Core {
class System; class System;
@ -29,7 +31,13 @@ public:
Result RegisterProgram(u64 process_id, u64 program_id, u8 storage_id, Result RegisterProgram(u64 process_id, u64 program_id, u8 storage_id,
const InBuffer<BufferAttr_HipcMapAlias> data, s64 data_size, const InBuffer<BufferAttr_HipcMapAlias> data, s64 data_size,
const InBuffer<BufferAttr_HipcMapAlias> desc, s64 desc_size); const InBuffer<BufferAttr_HipcMapAlias> 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<FileSys::RomFSFactory> romfs_factory,
std::shared_ptr<FileSys::SaveDataFactory> save_data_factory);
Result UnregisterProgram(u64 process_id); Result UnregisterProgram(u64 process_id);
Result GetProgramInfo(std::shared_ptr<Impl::ProgramInfo>* out, u64 process_id);
Result SetCurrentProcess(const Service::ClientProcessId& client_pid); Result SetCurrentProcess(const Service::ClientProcessId& client_pid);
Result SetEnabledProgramVerification(bool enabled); Result SetEnabledProgramVerification(bool enabled);

View file

@ -22,6 +22,13 @@ Result ProgramRegistryServiceImpl::RegisterProgramInfo(u64 process_id, u64 progr
data_size, desc, desc_size)); data_size, desc, desc_size));
} }
Result ProgramRegistryServiceImpl::RegisterProgramInfoForLoader(
u64 process_id, u64 program_id, std::shared_ptr<FileSys::RomFSFactory> romfs_factory,
std::shared_ptr<FileSys::SaveDataFactory> 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) { Result ProgramRegistryServiceImpl::UnregisterProgramInfo(u64 process_id) {
R_RETURN(m_registry_manager->UnregisterProgram(process_id)); R_RETURN(m_registry_manager->UnregisterProgram(process_id));
} }

View file

@ -7,6 +7,8 @@
#include "core/file_sys/fs_program_index_map_info.h" #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_index_map_info_manager.h"
#include "core/file_sys/fssrv/impl/fssrv_program_registry_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" #include "core/hle/result.h"
namespace Core { namespace Core {
@ -24,11 +26,16 @@ class ProgramRegistryServiceImpl {
public: public:
struct Configuration {}; struct Configuration {};
ProgramRegistryServiceImpl(Core::System& system_, ProgramRegistryServiceImpl(Core::System& system_, Impl::InitialProgramInfo& program_info,
Impl::InitialProgramInfo& program_info, const Configuration& cfg); const Configuration& cfg);
Result RegisterProgramInfo(u64 process_id, u64 program_id, u8 storage_id, const void* data, Result RegisterProgramInfo(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);
// 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<FileSys::RomFSFactory> romfs_factory,
std::shared_ptr<FileSys::SaveDataFactory> save_data_factory);
Result UnregisterProgramInfo(u64 process_id); Result UnregisterProgramInfo(u64 process_id);
Result ResetProgramIndexMapInfo(const ProgramIndexMapInfo* infos, int count); Result ResetProgramIndexMapInfo(const ProgramIndexMapInfo* infos, int count);

View file

@ -13,11 +13,8 @@
namespace FileSys::FsSrv::Impl { namespace FileSys::FsSrv::Impl {
struct ProgramIndexMapInfoEntry : public Common::IntrusiveListBaseNode<ProgramIndexMapInfoEntry> { struct ProgramIndexMapInfoEntry : public ProgramIndexMapInfo,
u64 program_id; public Common::IntrusiveListBaseNode<ProgramIndexMapInfoEntry> {};
u64 base_program_id;
u8 program_index;
};
class ProgramIndexMapInfoManager { class ProgramIndexMapInfoManager {
YUZU_NON_COPYABLE(ProgramIndexMapInfoManager); YUZU_NON_COPYABLE(ProgramIndexMapInfoManager);

View file

@ -5,6 +5,7 @@
#include "core/file_sys/fssrv/impl/fssrv_access_control.h" #include "core/file_sys/fssrv/impl/fssrv_access_control.h"
#include "core/file_sys/romfs_factory.h" #include "core/file_sys/romfs_factory.h"
#include "core/file_sys/savedata_factory.h"
namespace Core { namespace Core {
class System; class System;
@ -20,13 +21,19 @@ private:
u64 m_program_id; u64 m_program_id;
FileSys::StorageId m_storage_id; FileSys::StorageId m_storage_id;
AccessControl m_access_control; AccessControl m_access_control;
// Needed to work around current fs limitations
std::shared_ptr<RomFSFactory> m_romfs_factory;
std::shared_ptr<SaveDataFactory> m_save_data_factory;
public: public:
ProgramInfo(u64 process_id, u64 program_id, u8 storage_id, const void* data, s64 data_size, 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<RomFSFactory> romfs_factory,
std::shared_ptr<SaveDataFactory> save_data_factory)
: m_process_id(process_id), m_access_control(data, data_size, desc, desc_size) { : m_process_id(process_id), m_access_control(data, data_size, desc, desc_size) {
m_program_id = program_id; m_program_id = program_id;
m_storage_id = static_cast<FileSys::StorageId>(storage_id); m_storage_id = static_cast<FileSys::StorageId>(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) ProgramInfo(const void* data, s64 data_size, const void* desc, s64 desc_size)
@ -49,6 +56,12 @@ public:
AccessControl& GetAccessControl() { AccessControl& GetAccessControl() {
return m_access_control; return m_access_control;
} }
std::shared_ptr<RomFSFactory> GetRomFsFactory() {
return m_romfs_factory;
}
std::shared_ptr<SaveDataFactory> GetSaveDataFactory() {
return m_save_data_factory;
}
}; };
struct ProgramInfoNode : public Common::IntrusiveListBaseNode<ProgramInfoNode> { struct ProgramInfoNode : public Common::IntrusiveListBaseNode<ProgramInfoNode> {

View file

@ -11,9 +11,10 @@ ProgramRegistryManager::ProgramRegistryManager(Core::System& system_,
InitialProgramInfo& program_info) InitialProgramInfo& program_info)
: m_initial_program_info{program_info}, system{system_} {} : m_initial_program_info{program_info}, system{system_} {}
Result ProgramRegistryManager::RegisterProgram(u64 process_id, u64 program_id, u8 storage_id, Result ProgramRegistryManager::RegisterProgram(
const void* data, s64 data_size, const void* desc, u64 process_id, u64 program_id, u8 storage_id, const void* data, s64 data_size,
s64 desc_size) { const void* desc, s64 desc_size, std::shared_ptr<FileSys::RomFSFactory> romfs_factory,
std::shared_ptr<FileSys::SaveDataFactory> save_data_factory) {
// Allocate a new node // Allocate a new node
std::unique_ptr<ProgramInfoNode> new_node(new ProgramInfoNode()); std::unique_ptr<ProgramInfoNode> new_node(new ProgramInfoNode());
R_UNLESS(new_node != nullptr, ResultAllocationMemoryFailedInProgramRegistryManagerA); 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 // Create a new program info
{ {
// Allocate the new info // Allocate the new info
std::shared_ptr<ProgramInfo> new_info = std::make_shared<ProgramInfo>( std::shared_ptr<ProgramInfo> new_info =
process_id, program_id, storage_id, data, data_size, desc, desc_size); std::make_shared<ProgramInfo>(process_id, program_id, storage_id, data, data_size, desc,
desc_size, romfs_factory, save_data_factory);
R_UNLESS(new_info != nullptr, ResultAllocationMemoryFailedInProgramRegistryManagerA); R_UNLESS(new_info != nullptr, ResultAllocationMemoryFailedInProgramRegistryManagerA);
// Set the info in the node // Set the info in the node

View file

@ -7,6 +7,8 @@
#include "common/common_funcs.h" #include "common/common_funcs.h"
#include "common/intrusive_list.h" #include "common/intrusive_list.h"
#include "core/file_sys/fssrv/impl/fssrv_program_info.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 { namespace Core {
class System; class System;
@ -22,7 +24,9 @@ public:
explicit ProgramRegistryManager(Core::System& system_, InitialProgramInfo& program_info); explicit ProgramRegistryManager(Core::System& system_, InitialProgramInfo& program_info);
Result RegisterProgram(u64 process_id, u64 program_id, u8 storage_id, const void* data, 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<FileSys::RomFSFactory> romfs_factory = nullptr,
std::shared_ptr<FileSys::SaveDataFactory> save_data_factory = nullptr);
Result UnregisterProgram(u64 process_id); Result UnregisterProgram(u64 process_id);
Result GetProgramInfo(std::shared_ptr<ProgramInfo>* out, u64 process_id); Result GetProgramInfo(std::shared_ptr<ProgramInfo>* out, u64 process_id);

View file

@ -298,13 +298,8 @@ FileSystemController::~FileSystemController() = default;
Result FileSystemController::RegisterProcess( Result FileSystemController::RegisterProcess(
ProcessId process_id, ProgramId program_id, ProcessId process_id, ProgramId program_id,
std::shared_ptr<FileSys::RomFSFactory>&& romfs_factory) { std::shared_ptr<FileSys::RomFSFactory>&& romfs_factory) {
std::scoped_lock lk{registration_lock}; system.GetProgramRegistry().RegisterProgramForLoader(
process_id, program_id, std::move(romfs_factory), CreateSaveDataFactory(program_id));
registrations.emplace(process_id, Registration{
.program_id = program_id,
.romfs_factory = std::move(romfs_factory),
.save_data_factory = CreateSaveDataFactory(program_id),
});
LOG_DEBUG(Service_FS, "Registered for process {}", process_id); LOG_DEBUG(Service_FS, "Registered for process {}", process_id);
return ResultSuccess; return ResultSuccess;
@ -313,31 +308,28 @@ Result FileSystemController::RegisterProcess(
Result FileSystemController::OpenProcess( Result FileSystemController::OpenProcess(
ProgramId* out_program_id, std::shared_ptr<SaveDataController>* out_save_data_controller, ProgramId* out_program_id, std::shared_ptr<SaveDataController>* out_save_data_controller,
std::shared_ptr<RomFsController>* out_romfs_controller, ProcessId process_id) { std::shared_ptr<RomFsController>* out_romfs_controller, ProcessId process_id) {
std::scoped_lock lk{registration_lock}; std::shared_ptr<FileSys::FsSrv::Impl::ProgramInfo> out_info;
if (system.GetProgramRegistry().GetProgramInfo(&out_info, process_id) != ResultSuccess) {
const auto it = registrations.find(process_id);
if (it == registrations.end()) {
return FileSys::ResultTargetNotFound; return FileSys::ResultTargetNotFound;
} }
*out_program_id = it->second.program_id; *out_program_id = out_info->GetProgramId();
*out_save_data_controller = *out_save_data_controller =
std::make_shared<SaveDataController>(system, it->second.save_data_factory); std::make_shared<SaveDataController>(system, out_info->GetSaveDataFactory());
*out_romfs_controller = *out_romfs_controller =
std::make_shared<RomFsController>(it->second.romfs_factory, it->second.program_id); std::make_shared<RomFsController>(out_info->GetRomFsFactory(), out_info->GetProgramId());
return ResultSuccess; return ResultSuccess;
} }
void FileSystemController::SetPackedUpdate(ProcessId process_id, FileSys::VirtualFile update_raw) { void FileSystemController::SetPackedUpdate(ProcessId process_id, FileSys::VirtualFile update_raw) {
LOG_TRACE(Service_FS, "Setting packed update for romfs"); LOG_TRACE(Service_FS, "Setting packed update for romfs");
std::scoped_lock lk{registration_lock}; std::shared_ptr<FileSys::FsSrv::Impl::ProgramInfo> out_info;
const auto it = registrations.find(process_id); if (system.GetProgramRegistry().GetProgramInfo(&out_info, process_id) != ResultSuccess) {
if (it == registrations.end()) {
return; return;
} }
it->second.romfs_factory->SetPackedUpdate(std::move(update_raw)); out_info->GetRomFsFactory()->SetPackedUpdate(std::move(update_raw));
} }
std::shared_ptr<SaveDataController> FileSystemController::OpenSaveDataController() { std::shared_ptr<SaveDataController> 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) { void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system); auto server_manager = std::make_unique<ServerManager>(system);

View file

@ -121,20 +121,9 @@ public:
// above is called. // above is called.
void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite = true); void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite = true);
void Reset();
private: private:
std::shared_ptr<FileSys::SaveDataFactory> CreateSaveDataFactory(ProgramId program_id); std::shared_ptr<FileSys::SaveDataFactory> CreateSaveDataFactory(ProgramId program_id);
struct Registration {
ProgramId program_id;
std::shared_ptr<FileSys::RomFSFactory> romfs_factory;
std::shared_ptr<FileSys::SaveDataFactory> save_data_factory;
};
std::mutex registration_lock;
std::map<ProcessId, Registration> registrations;
std::unique_ptr<FileSys::SDMCFactory> sdmc_factory; std::unique_ptr<FileSys::SDMCFactory> sdmc_factory;
std::unique_ptr<FileSys::BISFactory> bis_factory; std::unique_ptr<FileSys::BISFactory> bis_factory;