Pass in a FileSystemServer to more classes

This commit is contained in:
Alex Barney 2021-02-05 01:08:44 -07:00
parent dadc019439
commit 58e94e99a9
11 changed files with 118 additions and 151 deletions

View File

@ -7,20 +7,27 @@ namespace LibHac.FsSrv
{
public class AccessFailureManagementServiceImpl
{
private ProgramRegistryImpl _programRegistry;
internal HorizonClient HorizonClient { get; }
private Configuration _config;
private AccessFailureDetectionEventManager _eventManager;
public AccessFailureManagementServiceImpl(ProgramRegistryImpl programRegistry, HorizonClient horizonClient)
internal HorizonClient HorizonClient => _config.FsServer.Globals.Hos;
public AccessFailureManagementServiceImpl(in Configuration configuration)
{
_programRegistry = programRegistry;
HorizonClient = horizonClient;
_config = configuration;
_eventManager = new AccessFailureDetectionEventManager();
}
// LibHac addition
public struct Configuration
{
public FileSystemServer FsServer;
}
internal Result GetProgramInfo(out ProgramInfo programInfo, ulong processId)
{
return _programRegistry.GetProgramInfo(out programInfo, processId);
var registry = new ProgramRegistryImpl(_config.FsServer);
return registry.GetProgramInfo(out programInfo, processId);
}
public Result CreateNotifier(out IEventNotifier notifier, ulong processId, bool notifyOnDeepRetry)

View File

@ -24,8 +24,7 @@ namespace LibHac.FsSrv
public ulong MinimumProgramIdForSdCardLog;
// LibHac additions
public HorizonClient HorizonClient;
public ProgramRegistryImpl ProgramRegistry;
public FileSystemServer FsServer;
}
public void SetAccessLogMode(GlobalAccessLogMode mode)
@ -60,7 +59,8 @@ namespace LibHac.FsSrv
internal Result GetProgramInfo(out ProgramInfo programInfo, ulong processId)
{
return _config.ProgramRegistry.GetProgramInfo(out programInfo, processId);
var registry = new ProgramRegistryImpl(_config.FsServer);
return registry.GetProgramInfo(out programInfo, processId);
}
}
}

View File

@ -28,11 +28,11 @@ namespace LibHac.FsSrv
public ISdCardProxyFileSystemCreator SdCardFileSystemCreator;
// CurrentTimeFunction
// FatFileSystemCacheManager
// AlbumDirectoryFileSystemManager
// BaseFileSystemCreatorHolder
public BisWiperCreator BisWiperCreator;
// Note: The program registry service is global as of FS 10.0.0
public ProgramRegistryImpl ProgramRegistry;
// LibHac additions
public FileSystemServer FsServer;
}
public Result OpenBaseFileSystem(out ReferenceCountedDisposable<IFileSystem> fileSystem,
@ -128,7 +128,8 @@ namespace LibHac.FsSrv
internal Result GetProgramInfo(out ProgramInfo programInfo, ulong processId)
{
return _config.ProgramRegistry.GetProgramInfo(out programInfo, processId);
var registry = new ProgramRegistryImpl(_config.FsServer);
return registry.GetProgramInfo(out programInfo, processId);
}
}
}

View File

@ -148,10 +148,11 @@ namespace LibHac.FsSrv
private Result GetProgramInfo(out ProgramInfo programInfo)
{
return _serviceImpl.GetProgramInfo(out programInfo, _processId);
var registry = new ProgramRegistryImpl(_serviceImpl.Config.FsServer);
return registry.GetProgramInfo(out programInfo, _processId);
}
private Result GetAccessibilityForOpenBisPartition(out Accessibility accessibility, ProgramInfo programInfo,
private static Result GetAccessibilityForOpenBisPartition(out Accessibility accessibility, ProgramInfo programInfo,
BisPartitionId partitionId)
{
Unsafe.SkipInit(out accessibility);
@ -200,7 +201,7 @@ namespace LibHac.FsSrv
public IGameCardStorageCreator GameCardStorageCreator;
// LibHac additions
public ProgramRegistryImpl ProgramRegistry;
public FileSystemServer FsServer;
// Todo: The DeviceOperator in FS uses mostly global state. Decide how to handle this.
public ReferenceCountedDisposable<IDeviceOperator> DeviceOperator;
}
@ -231,10 +232,5 @@ namespace LibHac.FsSrv
return ResultFs.InvalidArgument.Log();
}
}
internal Result GetProgramInfo(out ProgramInfo programInfo, ulong processId)
{
return Config.ProgramRegistry.GetProgramInfo(out programInfo, processId);
}
}
}

View File

@ -1,5 +1,4 @@
using System;
using LibHac.Fs;
using LibHac.Fs.Impl;
using LibHac.Fs.Shim;
using LibHac.FsSrv.Creators;
@ -17,16 +16,12 @@ namespace LibHac.FsSrv
private const ulong SpeedEmulationProgramIdMinimum = 0x100000000000000;
private const ulong SpeedEmulationProgramIdMaximum = 0x100000000001FFF;
internal FileSystemServerImpl Impl => new FileSystemServerImpl(this);
public StorageService Storage => new StorageService(this);
/// <summary>The client instance to be used for internal operations like save indexer access.</summary>
public HorizonClient Hos => Globals.Hos;
private ITimeSpanGenerator Timer { get; }
internal FileSystemServerGlobals Globals;
private HorizonClient Hos => Globals.Hos;
public FileSystemServerImpl Impl => new FileSystemServerImpl(this);
public StorageService Storage => new StorageService(this);
/// <summary>
/// Creates a new <see cref="FileSystemServer"/> and registers its services using the provided HOS client.
/// </summary>
@ -43,8 +38,6 @@ namespace LibHac.FsSrv
Globals.Hos = horizonClient;
Globals.InitMutex = new object();
Timer = config.TimeSpanGenerator ?? new StopWatchTimeSpanGenerator();
FileSystemProxyConfiguration fspConfig = InitializeFileSystemProxyConfiguration(config);
this.InitializeFileSystemProxy(fspConfig);
@ -69,55 +62,41 @@ namespace LibHac.FsSrv
Hos.Fs.SetSdCardAccessibility(true);
}
/// <summary>
/// Creates a new <see cref="FileSystemClient"/> using this <see cref="FileSystemServer"/>'s
/// <see cref="ITimeSpanGenerator"/> for the client's access log.
/// </summary>
/// <returns>The created <see cref="FileSystemClient"/>.</returns>
public FileSystemClient CreateFileSystemClient() => CreateFileSystemClient(Timer);
/// <summary>
/// Creates a new <see cref="FileSystemClient"/>.
/// </summary>
/// <param name="timer">The <see cref="ITimeSpanGenerator"/> to use for the created
/// <see cref="FileSystemClient"/>'s access log.</param>
/// <returns>The created <see cref="FileSystemClient"/>.</returns>
public FileSystemClient CreateFileSystemClient(ITimeSpanGenerator timer)
{
return new FileSystemClient(Hos);
}
private FileSystemProxyConfiguration InitializeFileSystemProxyConfiguration(FileSystemServerConfig config)
{
var saveDataIndexerManager = new SaveDataIndexerManager(Hos.Fs, SaveIndexerId,
new ArrayPoolMemoryResource(), new SdHandleManager(), false);
var programRegistryService = new ProgramRegistryServiceImpl(this);
var programRegistry = new ProgramRegistryImpl(this);
this.InitializeProgramRegistryImpl(programRegistryService);
var baseStorageConfig = new BaseStorageServiceImpl.Configuration();
baseStorageConfig.BisStorageCreator = config.FsCreators.BuiltInStorageCreator;
baseStorageConfig.GameCardStorageCreator = config.FsCreators.GameCardStorageCreator;
baseStorageConfig.ProgramRegistry = programRegistry;
baseStorageConfig.FsServer = this;
baseStorageConfig.DeviceOperator = new ReferenceCountedDisposable<IDeviceOperator>(config.DeviceOperator);
var baseStorageService = new BaseStorageServiceImpl(in baseStorageConfig);
var timeServiceConfig = new TimeServiceImpl.Configuration();
timeServiceConfig.HorizonClient = Hos;
timeServiceConfig.ProgramRegistry = programRegistry;
var timeService = new TimeServiceImpl(in timeServiceConfig);
var timeService = new TimeServiceImpl(this);
var baseFsServiceConfig = new BaseFileSystemServiceImpl.Configuration();
baseFsServiceConfig.BisFileSystemCreator = config.FsCreators.BuiltInStorageFileSystemCreator;
baseFsServiceConfig.GameCardFileSystemCreator = config.FsCreators.GameCardFileSystemCreator;
baseFsServiceConfig.SdCardFileSystemCreator = config.FsCreators.SdCardFileSystemCreator;
baseFsServiceConfig.BisWiperCreator = BisWiper.CreateWiper;
baseFsServiceConfig.ProgramRegistry = programRegistry;
baseFsServiceConfig.FsServer = this;
var baseFsService = new BaseFileSystemServiceImpl(in baseFsServiceConfig);
var accessFailureManagementService = new AccessFailureManagementServiceImpl(programRegistry, Hos);
var accessFailureManagementServiceConfig = new AccessFailureManagementServiceImpl.Configuration();
accessFailureManagementServiceConfig.FsServer = this;
var accessFailureManagementService =
new AccessFailureManagementServiceImpl(in accessFailureManagementServiceConfig);
var speedEmulationRange =
new InternalProgramIdRangeForSpeedEmulation(SpeedEmulationProgramIdMinimum,
SpeedEmulationProgramIdMaximum);
var ncaFsServiceConfig = new NcaFileSystemServiceImpl.Configuration();
ncaFsServiceConfig.BaseFsService = baseFsService;
@ -129,11 +108,9 @@ namespace LibHac.FsSrv
ncaFsServiceConfig.SubDirectoryFsCreator = config.FsCreators.SubDirectoryFileSystemCreator;
ncaFsServiceConfig.EncryptedFsCreator = config.FsCreators.EncryptedFileSystemCreator;
ncaFsServiceConfig.ProgramRegistryService = programRegistryService;
ncaFsServiceConfig.HorizonClient = Hos;
ncaFsServiceConfig.ProgramRegistry = programRegistry;
ncaFsServiceConfig.SpeedEmulationRange =
new InternalProgramIdRangeForSpeedEmulation(SpeedEmulationProgramIdMinimum,
SpeedEmulationProgramIdMaximum);
ncaFsServiceConfig.AccessFailureManagementService = accessFailureManagementService;
ncaFsServiceConfig.SpeedEmulationRange = speedEmulationRange;
ncaFsServiceConfig.FsServer = this;
var ncaFsService = new NcaFileSystemServiceImpl(in ncaFsServiceConfig, config.ExternalKeySet);
@ -146,8 +123,7 @@ namespace LibHac.FsSrv
saveFsServiceConfig.ProgramRegistryService = programRegistryService;
saveFsServiceConfig.ShouldCreateDirectorySaveData = () => true;
saveFsServiceConfig.SaveIndexerManager = saveDataIndexerManager;
saveFsServiceConfig.HorizonClient = Hos;
saveFsServiceConfig.ProgramRegistry = programRegistry;
saveFsServiceConfig.FsServer = this;
var saveFsService = new SaveDataFileSystemServiceImpl(in saveFsServiceConfig);
@ -161,13 +137,14 @@ namespace LibHac.FsSrv
statusReportServiceConfig.MainThreadStackUsageReporter = new DummyStackUsageReporter();
statusReportServiceConfig.IpcWorkerThreadStackUsageReporter = new DummyStackUsageReporter();
statusReportServiceConfig.PipeLineWorkerThreadStackUsageReporter = new DummyStackUsageReporter();
statusReportServiceConfig.FsServer = this;
var statusReportService = new StatusReportServiceImpl(in statusReportServiceConfig);
var accessLogServiceConfig = new AccessLogServiceImpl.Configuration();
accessLogServiceConfig.MinimumProgramIdForSdCardLog = 0x0100000000003000;
accessLogServiceConfig.HorizonClient = Hos;
accessLogServiceConfig.ProgramRegistry = programRegistry;
accessLogServiceConfig.FsServer = this;
var accessLogService = new AccessLogServiceImpl(in accessLogServiceConfig);
var fspConfig = new FileSystemProxyConfiguration
@ -276,12 +253,6 @@ namespace LibHac.FsSrv
/// If null, an empty set will be created.
/// </summary>
public ExternalKeySet ExternalKeySet { get; set; }
/// <summary>
/// Used for generating access log timestamps.
/// If null, a new <see cref="StopWatchTimeSpanGenerator"/> will be created.
/// </summary>
public ITimeSpanGenerator TimeSpanGenerator { get; set; }
}
public readonly struct StorageService

View File

@ -11,9 +11,9 @@ namespace LibHac.FsSrv.Impl
{
public static class AccessControlGlobalMethods
{
public static void SetDebugFlagEnabled(this FileSystemServerImpl fsSrv, bool isEnabled)
public static void SetDebugFlagEnabled(this FileSystemServer fsSrv, bool isEnabled)
{
fsSrv.FsSrv.Globals.AccessControl.DebugFlag = isEnabled;
fsSrv.Globals.AccessControl.DebugFlag = isEnabled;
}
}

View File

@ -3,6 +3,7 @@ using LibHac.Diag;
using LibHac.Fs;
using LibHac.Lr;
using LibHac.Ncm;
using LibHac.Os;
namespace LibHac.FsSrv.Impl
{
@ -12,15 +13,16 @@ namespace LibHac.FsSrv.Impl
private LocationResolver[] _resolvers;
private AddOnContentLocationResolver _aocResolver;
private object _locker;
private SdkMutexType _mutex;
private HorizonClient _hos;
private FileSystemServer _fsServer;
private HorizonClient Hos => _fsServer.Globals.Hos;
public LocationResolverSet(HorizonClient horizonClient)
public LocationResolverSet(FileSystemServer fsServer)
{
_resolvers = new LocationResolver[LocationResolverCount];
_locker = new object();
_hos = horizonClient;
_mutex.Initialize();
_fsServer = fsServer;
}
private Result GetLocationResolver(out LocationResolver resolver, StorageId storageId)
@ -30,23 +32,22 @@ namespace LibHac.FsSrv.Impl
if (!IsValidStorageId(storageId))
return ResultLr.LocationResolverNotFound.Log();
lock (_locker)
{
int index = GetResolverIndexFromStorageId(storageId);
ref LocationResolver lr = ref _resolvers[index];
using ScopedLock<SdkMutexType> lk = ScopedLock.Lock(ref _mutex);
// Open the location resolver if it hasn't been already
if (lr is null && _hos.Lr.OpenLocationResolver(out lr, storageId).IsFailure())
return ResultLr.LocationResolverNotFound.Log();
int index = GetResolverIndexFromStorageId(storageId);
ref LocationResolver lr = ref _resolvers[index];
resolver = lr;
return Result.Success;
}
// Open the location resolver if it hasn't been already
if (lr is null && Hos.Lr.OpenLocationResolver(out lr, storageId).IsFailure())
return ResultLr.LocationResolverNotFound.Log();
resolver = lr;
return Result.Success;
}
private Result GetRegisteredLocationResolver(out RegisteredLocationResolver resolver)
{
Result rc = _hos.Lr.OpenRegisteredLocationResolver(out RegisteredLocationResolver lr);
Result rc = Hos.Lr.OpenRegisteredLocationResolver(out RegisteredLocationResolver lr);
if (rc.IsFailure())
{
@ -61,23 +62,22 @@ namespace LibHac.FsSrv.Impl
private Result GetAddOnContentLocationResolver(out AddOnContentLocationResolver resolver)
{
lock (_locker)
{
if (_aocResolver is null)
{
Result rc = _hos.Lr.OpenAddOnContentLocationResolver(out AddOnContentLocationResolver lr);
if (rc.IsFailure())
{
resolver = default;
return rc;
}
using ScopedLock<SdkMutexType> lk = ScopedLock.Lock(ref _mutex);
_aocResolver = lr;
if (_aocResolver is null)
{
Result rc = Hos.Lr.OpenAddOnContentLocationResolver(out AddOnContentLocationResolver lr);
if (rc.IsFailure())
{
resolver = default;
return rc;
}
resolver = _aocResolver;
return Result.Success;
_aocResolver = lr;
}
resolver = _aocResolver;
return Result.Success;
}
public Result ResolveApplicationControlPath(out Path path, Ncm.ApplicationId applicationId, StorageId storageId)

View File

@ -10,6 +10,7 @@ using LibHac.FsSystem;
using LibHac.FsSystem.NcaUtils;
using LibHac.Lr;
using LibHac.Ncm;
using LibHac.Os;
using LibHac.Spl;
using LibHac.Util;
using RightsId = LibHac.Fs.RightsId;
@ -28,14 +29,14 @@ namespace LibHac.FsSrv
private int _romFsRemountForDataCorruptionCount;
private int _romfsUnrecoverableDataCorruptionByRemountCount;
private int _romFsRecoveredByInvalidateCacheCount;
private object _romfsCountLocker;
private SdkMutexType _romfsCountMutex;
public NcaFileSystemServiceImpl(in Configuration configuration, ExternalKeySet externalKeySet)
{
_config = configuration;
_externalKeyManager = externalKeySet;
_locationResolverSet = new LocationResolverSet(_config.HorizonClient);
_romfsCountLocker = new object();
_locationResolverSet = new LocationResolverSet(_config.FsServer);
_romfsCountMutex.Initialize();
}
public struct Configuration
@ -49,15 +50,13 @@ namespace LibHac.FsSrv
public ISubDirectoryFileSystemCreator SubDirectoryFsCreator;
public IEncryptedFileSystemCreator EncryptedFsCreator;
public ProgramRegistryServiceImpl ProgramRegistryService;
// AccessFailureService
public AccessFailureManagementServiceImpl AccessFailureManagementService;
public InternalProgramIdRangeForSpeedEmulation SpeedEmulationRange;
// LibHac additions
public HorizonClient HorizonClient;
public ProgramRegistryImpl ProgramRegistry;
public FileSystemServer FsServer;
}
private struct MountInfo
{
public bool IsGameCard;
@ -66,7 +65,6 @@ namespace LibHac.FsSrv
public bool CanMountNca;
}
public Result OpenFileSystem(out ReferenceCountedDisposable<IFileSystem> fileSystem, U8Span path,
FileSystemProxyType type, ulong id)
{
@ -881,41 +879,37 @@ namespace LibHac.FsSrv
public void IncrementRomFsRemountForDataCorruptionCount()
{
lock (_romfsCountLocker)
{
_romFsRemountForDataCorruptionCount++;
}
using ScopedLock<SdkMutexType> lk = ScopedLock.Lock(ref _romfsCountMutex);
_romFsRemountForDataCorruptionCount++;
}
public void IncrementRomFsUnrecoverableDataCorruptionByRemountCount()
{
lock (_romfsCountLocker)
{
_romfsUnrecoverableDataCorruptionByRemountCount++;
}
using ScopedLock<SdkMutexType> lk = ScopedLock.Lock(ref _romfsCountMutex);
_romfsUnrecoverableDataCorruptionByRemountCount++;
}
public void IncrementRomFsRecoveredByInvalidateCacheCount()
{
lock (_romfsCountLocker)
{
_romFsRecoveredByInvalidateCacheCount++;
}
using ScopedLock<SdkMutexType> lk = ScopedLock.Lock(ref _romfsCountMutex);
_romFsRecoveredByInvalidateCacheCount++;
}
public void GetAndClearRomFsErrorInfo(out int recoveredByRemountCount, out int unrecoverableCount,
out int recoveredByCacheInvalidationCount)
{
lock (_romfsCountLocker)
{
recoveredByRemountCount = _romFsRemountForDataCorruptionCount;
unrecoverableCount = _romfsUnrecoverableDataCorruptionByRemountCount;
recoveredByCacheInvalidationCount = _romFsRecoveredByInvalidateCacheCount;
using ScopedLock<SdkMutexType> lk = ScopedLock.Lock(ref _romfsCountMutex);
_romFsRemountForDataCorruptionCount = 0;
_romfsUnrecoverableDataCorruptionByRemountCount = 0;
_romFsRecoveredByInvalidateCacheCount = 0;
}
recoveredByRemountCount = _romFsRemountForDataCorruptionCount;
unrecoverableCount = _romfsUnrecoverableDataCorruptionByRemountCount;
recoveredByCacheInvalidationCount = _romFsRecoveredByInvalidateCacheCount;
_romFsRemountForDataCorruptionCount = 0;
_romfsUnrecoverableDataCorruptionByRemountCount = 0;
_romFsRecoveredByInvalidateCacheCount = 0;
}
public Result OpenHostFileSystem(out ReferenceCountedDisposable<IFileSystem> fileSystem, U8Span path, bool openCaseSensitive)
@ -964,12 +958,14 @@ namespace LibHac.FsSrv
internal Result GetProgramInfoByProcessId(out ProgramInfo programInfo, ulong processId)
{
return _config.ProgramRegistry.GetProgramInfo(out programInfo, processId);
var registry = new ProgramRegistryImpl(_config.FsServer);
return registry.GetProgramInfo(out programInfo, processId);
}
internal Result GetProgramInfoByProgramId(out ProgramInfo programInfo, ulong programId)
{
return _config.ProgramRegistry.GetProgramInfoByProgramId(out programInfo, programId);
var registry = new ProgramRegistryImpl(_config.FsServer);
return registry.GetProgramInfoByProgramId(out programInfo, programId);
}
private Result GetPartitionIndex(out int index, FileSystemProxyType fspType)

View File

@ -24,7 +24,7 @@ namespace LibHac.FsSrv
private bool _isSdCardAccessible;
// Timestamp getter
internal HorizonClient Hos => _config.HorizonClient;
internal HorizonClient Hos => _config.FsServer.Globals.Hos;
public SaveDataFileSystemServiceImpl(in Configuration configuration)
{
@ -48,13 +48,13 @@ namespace LibHac.FsSrv
public ISaveDataIndexerManager SaveIndexerManager;
// LibHac additions
public HorizonClient HorizonClient;
public ProgramRegistryImpl ProgramRegistry;
public FileSystemServer FsServer;
}
internal Result GetProgramInfo(out ProgramInfo programInfo, ulong processId)
{
return _config.ProgramRegistry.GetProgramInfo(out programInfo, processId);
var registry = new ProgramRegistryImpl(_config.FsServer);
return registry.GetProgramInfo(out programInfo, processId);
}
public Result DoesSaveDataEntityExist(out bool exists, SaveDataSpaceId spaceId, ulong saveDataId)

View File

@ -54,6 +54,7 @@ namespace LibHac.FsSrv
public IStackUsageReporter IpcWorkerThreadStackUsageReporter;
public IStackUsageReporter PipeLineWorkerThreadStackUsageReporter;
// LibHac additions
public FileSystemServer FsServer;
}

View File

@ -36,29 +36,23 @@ namespace LibHac.FsSrv
public class TimeServiceImpl
{
private Configuration _config;
private long _basePosixTime;
private int _timeDifference;
private SdkMutexType _mutex;
public TimeServiceImpl(in Configuration configuration)
private FileSystemServer _fsServer;
public TimeServiceImpl(FileSystemServer fsServer)
{
_config = configuration;
_fsServer = fsServer;
_basePosixTime = 0;
_timeDifference = 0;
_mutex.Initialize();
}
// The entire Configuration struct is a LibHac addition to avoid using global state
public struct Configuration
{
public HorizonClient HorizonClient;
public ProgramRegistryImpl ProgramRegistry;
}
private long GetSystemSeconds()
{
OsState os = _config.HorizonClient.Os;
OsState os = _fsServer.Globals.Hos.Os;
Tick tick = os.GetSystemTick();
TimeSpan timeSpan = os.ConvertToTimeSpan(tick);
@ -103,7 +97,8 @@ namespace LibHac.FsSrv
internal Result GetProgramInfo(out ProgramInfo programInfo, ulong processId)
{
return _config.ProgramRegistry.GetProgramInfo(out programInfo, processId);
var registry = new ProgramRegistryImpl(_fsServer);
return registry.GetProgramInfo(out programInfo, processId);
}
}
}