mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Implement JournalIntegritySaveDataFileSystemDriver
This commit is contained in:
parent
45975ddadd
commit
8027310320
7 changed files with 274 additions and 46 deletions
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using LibHac.Diag;
|
using LibHac.Diag;
|
||||||
using LibHac.Fs;
|
using LibHac.Fs;
|
||||||
using Buffer = LibHac.Mem.Buffer;
|
using Buffer = LibHac.Mem.Buffer;
|
||||||
|
@ -19,8 +20,7 @@ public struct ScopedBufferManagerContextRegistration : IDisposable
|
||||||
{
|
{
|
||||||
private BufferManagerContext _oldContext;
|
private BufferManagerContext _oldContext;
|
||||||
|
|
||||||
// ReSharper disable once UnusedParameter.Local
|
public ScopedBufferManagerContextRegistration()
|
||||||
public ScopedBufferManagerContextRegistration(int unused = default)
|
|
||||||
{
|
{
|
||||||
_oldContext = BufferManagerUtility.GetBufferManagerContext();
|
_oldContext = BufferManagerUtility.GetBufferManagerContext();
|
||||||
}
|
}
|
||||||
|
@ -41,15 +41,15 @@ internal static class BufferManagerUtility
|
||||||
|
|
||||||
public delegate bool IsValidBufferFunction(in Buffer buffer);
|
public delegate bool IsValidBufferFunction(in Buffer buffer);
|
||||||
|
|
||||||
public static Result DoContinuouslyUntilBufferIsAllocated(Func<Result> function, Func<Result> onFailure,
|
public static Result DoContinuouslyUntilBufferIsAllocated([InstantHandle] Func<Result> function,
|
||||||
[CallerMemberName] string callerName = "")
|
[InstantHandle] Func<Result> onFailure, [CallerMemberName] string callerName = "")
|
||||||
{
|
{
|
||||||
const int bufferAllocationRetryLogCountMax = 10;
|
const int bufferAllocationRetryLogCountMax = 10;
|
||||||
const int bufferAllocationRetryLogInterval = 100;
|
const int bufferAllocationRetryLogInterval = 100;
|
||||||
|
|
||||||
Result result;
|
Result result;
|
||||||
|
|
||||||
for (int count = 1; ; count++)
|
for (int count = 1;; count++)
|
||||||
{
|
{
|
||||||
result = function();
|
result = function();
|
||||||
if (!ResultFs.BufferAllocationFailed.Includes(result))
|
if (!ResultFs.BufferAllocationFailed.Includes(result))
|
||||||
|
@ -71,7 +71,7 @@ internal static class BufferManagerUtility
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result DoContinuouslyUntilBufferIsAllocated(Func<Result> function,
|
public static Result DoContinuouslyUntilBufferIsAllocated([InstantHandle] Func<Result> function,
|
||||||
[CallerMemberName] string callerName = "")
|
[CallerMemberName] string callerName = "")
|
||||||
{
|
{
|
||||||
return DoContinuouslyUntilBufferIsAllocated(function, static () => Result.Success, callerName);
|
return DoContinuouslyUntilBufferIsAllocated(function, static () => Result.Success, callerName);
|
||||||
|
|
|
@ -125,9 +125,15 @@ file static class Anonymous
|
||||||
|
|
||||||
public class JournalIntegritySaveDataFileSystem : IFileSystem
|
public class JournalIntegritySaveDataFileSystem : IFileSystem
|
||||||
{
|
{
|
||||||
public struct ExtraData { }
|
public struct ExtraData
|
||||||
|
{
|
||||||
|
public int Dummy;
|
||||||
|
}
|
||||||
|
|
||||||
public struct FileSystemLayoutHeader { }
|
public struct FileSystemLayoutHeader
|
||||||
|
{
|
||||||
|
public int Dummy;
|
||||||
|
}
|
||||||
|
|
||||||
public struct MasterHeader
|
public struct MasterHeader
|
||||||
{
|
{
|
||||||
|
@ -136,7 +142,9 @@ public class JournalIntegritySaveDataFileSystem : IFileSystem
|
||||||
public long Counter;
|
public long Counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct CommitData2 { }
|
public struct CommitData2
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ControlAreaHolder : IDisposable
|
public class ControlAreaHolder : IDisposable
|
||||||
|
@ -435,10 +443,12 @@ public class JournalIntegritySaveDataFileSystem : IFileSystem
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result QuerySize(out long outSizeTotal, long sizeBlock, int countAvailableBlock,
|
public static Result QuerySize(out long outSizeTotal, long sizeBlock, uint countAvailableBlock,
|
||||||
int countJournalBlock, int countExpandMax, uint minimumVersion)
|
uint countJournalBlock, int countExpandMax, uint minimumVersion)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
// Todo: Implement
|
||||||
|
outSizeTotal = 0;
|
||||||
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Result Sign(Span<byte> outBuffer, IMacGenerator macGenerator,
|
private static Result Sign(Span<byte> outBuffer, IMacGenerator macGenerator,
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
// ReSharper disable UnusedMember.Local UnusedType.Local
|
using LibHac.Common;
|
||||||
#pragma warning disable CS0169 // Field is never used
|
using LibHac.Diag;
|
||||||
using System;
|
|
||||||
using LibHac.Fs;
|
using LibHac.Fs;
|
||||||
|
using LibHac.FsSystem.Buffers;
|
||||||
using LibHac.Os;
|
using LibHac.Os;
|
||||||
using LibHac.Util;
|
using LibHac.Util;
|
||||||
|
|
||||||
namespace LibHac.FsSystem.Save;
|
namespace LibHac.FsSystem.Save;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides access to a <see cref="JournalIntegritySaveDataFileSystem"/>. Abstracts some operations such as expansion,
|
||||||
|
/// and retries operations if buffer allocation fails.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Based on nnSdk 17.5.0 (FS 17.0.0)</remarks>
|
||||||
public class JournalIntegritySaveDataFileSystemDriver : ProxyFileSystemWithRetryingBufferAllocation, IInternalStorageFileSystem
|
public class JournalIntegritySaveDataFileSystemDriver : ProxyFileSystemWithRetryingBufferAllocation, IInternalStorageFileSystem
|
||||||
{
|
{
|
||||||
private ValueSubStorage _baseStorage;
|
private ValueSubStorage _baseStorage;
|
||||||
|
@ -17,26 +22,70 @@ public class JournalIntegritySaveDataFileSystemDriver : ProxyFileSystemWithRetry
|
||||||
|
|
||||||
public JournalIntegritySaveDataFileSystemDriver()
|
public JournalIntegritySaveDataFileSystemDriver()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_baseStorage = new ValueSubStorage();
|
||||||
|
_mutex = new SdkRecursiveMutex();
|
||||||
|
_fileSystem = new JournalIntegritySaveDataFileSystem();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
FinalizeObject();
|
||||||
|
_fileSystem.Dispose();
|
||||||
|
_baseStorage.Dispose();
|
||||||
|
base.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result QueryDataBlockCount(out uint outCountDataBlock, long blockSize, long availableSize,
|
public static Result QueryDataBlockCount(out uint outCountDataBlock, long blockSize, long totalSize,
|
||||||
long journalSize, int countExpandMax, uint version)
|
long journalSize, int countExpandMax, uint version)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
outCountDataBlock = 0;
|
||||||
|
|
||||||
|
uint lowerBound = 0;
|
||||||
|
uint upperBound = (uint)(totalSize / blockSize);
|
||||||
|
uint journalBlockCount = (uint)(journalSize / blockSize);
|
||||||
|
|
||||||
|
int iterationsRemaining = 32;
|
||||||
|
|
||||||
|
// Do a binary search to find the maximum number of data blocks you can have without going over the total
|
||||||
|
// save image size limit.
|
||||||
|
uint midpoint;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (upperBound == lowerBound)
|
||||||
|
break;
|
||||||
|
if (iterationsRemaining-- == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
midpoint = (upperBound + lowerBound) / 2;
|
||||||
|
Result res = QueryTotalSize(out long sizeQuery, blockSize, midpoint, journalBlockCount, countExpandMax, version);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
if (sizeQuery > totalSize)
|
||||||
|
upperBound = midpoint;
|
||||||
|
else
|
||||||
|
lowerBound = midpoint;
|
||||||
|
} while (upperBound - lowerBound > 1 || midpoint != lowerBound);
|
||||||
|
|
||||||
|
{
|
||||||
|
Result res = QueryTotalSize(out long sizeQuery, blockSize, lowerBound, journalBlockCount, countExpandMax, version);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
if (sizeQuery > totalSize)
|
||||||
|
{
|
||||||
|
return ResultFs.UsableSpaceNotEnough.Log();
|
||||||
|
}
|
||||||
|
|
||||||
|
outCountDataBlock = lowerBound;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result QueryTotalSize(out long outSizeTotal, long blockSize, uint countAvailableBlock,
|
public static Result QueryTotalSize(out long outSizeTotal, long blockSize, uint countAvailableBlock,
|
||||||
uint countJournalBlock, int countExpandMax, uint version)
|
uint countJournalBlock, int countExpandMax, uint version)
|
||||||
{
|
{
|
||||||
// Todo: Implement
|
return JournalIntegritySaveDataFileSystem.QuerySize(out outSizeTotal, blockSize, countAvailableBlock,
|
||||||
outSizeTotal = 0;
|
countJournalBlock, countExpandMax, version).Ret();
|
||||||
return Result.Success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result Format(
|
public static Result Format(
|
||||||
|
@ -52,12 +101,33 @@ public class JournalIntegritySaveDataFileSystemDriver : ProxyFileSystemWithRetry
|
||||||
RandomDataGenerator encryptionKeyGenerator,
|
RandomDataGenerator encryptionKeyGenerator,
|
||||||
uint version)
|
uint version)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
// Create a local copy of the SubStorage so it can be captured for use in a local function or lambda
|
||||||
|
using var tempSaveFileStorage = new ValueSubStorage(in saveFileStorage);
|
||||||
|
|
||||||
|
var locker = new SdkRecursiveMutex();
|
||||||
|
|
||||||
|
var bufferManagerSet = new FileSystemBufferManagerSet();
|
||||||
|
for (int i = 0; i < bufferManagerSet.Buffers.Length; i++)
|
||||||
|
{
|
||||||
|
bufferManagerSet.Buffers[i] = bufferManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BufferManagerUtility.DoContinuouslyUntilBufferIsAllocated(FormatImpl).Ret();
|
||||||
|
|
||||||
|
Result FormatImpl()
|
||||||
|
{
|
||||||
|
using var scopedRegistration = new ScopedBufferManagerContextRegistration();
|
||||||
|
|
||||||
|
return JournalIntegritySaveDataFileSystem.Format(in tempSaveFileStorage, blockSize, blockCount,
|
||||||
|
journalBlockCount, countExpandMax, bufferManagerSet, bufferManager, locker, macGenerator,
|
||||||
|
hashGeneratorFactorySelector, hashSalt, encryptionKeyGenerator, version).Ret();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long QueryExpandLogSize(long blockSize, uint availableBlockCount, uint journalBlockCount)
|
public static long QueryExpandLogSize(long blockSize, uint availableBlockCount, uint journalBlockCount)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
long dataSize = ((long)journalBlockCount + availableBlockCount) * blockSize;
|
||||||
|
return BitUtil.DivideUp(dataSize, 0x2000000) * 0x10000 + 0x100000;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result OperateExpand(
|
public static Result OperateExpand(
|
||||||
|
@ -71,7 +141,49 @@ public class JournalIntegritySaveDataFileSystemDriver : ProxyFileSystemWithRetry
|
||||||
IHash256GeneratorFactorySelector hashGeneratorFactorySelector,
|
IHash256GeneratorFactorySelector hashGeneratorFactorySelector,
|
||||||
uint minimumVersion)
|
uint minimumVersion)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
using var tempBaseStorage = new ValueSubStorage(in baseStorage);
|
||||||
|
using var tempLogStorage = new ValueSubStorage(in logStorage);
|
||||||
|
|
||||||
|
var locker = new SdkRecursiveMutex();
|
||||||
|
|
||||||
|
return BufferManagerUtility.DoContinuouslyUntilBufferIsAllocated(OperateImpl).Ret();
|
||||||
|
|
||||||
|
Result OperateImpl()
|
||||||
|
{
|
||||||
|
using var scopedRegistration = new ScopedBufferManagerContextRegistration();
|
||||||
|
using var unionStorage = new UnionStorage();
|
||||||
|
|
||||||
|
Result res = tempLogStorage.GetSize(out long logStorageSize);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
using var storageBufferingLog = new BufferedStorage();
|
||||||
|
res = storageBufferingLog.Initialize(in tempLogStorage, bufferManager, (int)blockSize, bufferCount: 2);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
using var bufferedLogStorage = new ValueSubStorage(storageBufferingLog, 0, logStorageSize);
|
||||||
|
|
||||||
|
res = UnionStorage.Format(in bufferedLogStorage, blockSize);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
res = unionStorage.Initialize(in tempBaseStorage, in bufferedLogStorage, blockSize);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
res = unionStorage.GetSize(out long sizeUnionStorage);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
using var tempUnionStorage = new ValueSubStorage(unionStorage, 0, sizeUnionStorage);
|
||||||
|
res = JournalIntegritySaveDataFileSystem.Expand(in tempUnionStorage, availableBlockCount, journalBlockCount,
|
||||||
|
bufferManager, locker, macGenerator, hashGeneratorFactorySelector, minimumVersion);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
res = unionStorage.Freeze();
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
res = unionStorage.Flush();
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result CommitExpand(
|
public static Result CommitExpand(
|
||||||
|
@ -80,61 +192,150 @@ public class JournalIntegritySaveDataFileSystemDriver : ProxyFileSystemWithRetry
|
||||||
long blockSize,
|
long blockSize,
|
||||||
IBufferManager bufferManager)
|
IBufferManager bufferManager)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
using var tempBaseStorage = new ValueSubStorage(in baseStorage);
|
||||||
|
using var tempLogStorage = new ValueSubStorage(in logStorage);
|
||||||
|
|
||||||
|
return BufferManagerUtility.DoContinuouslyUntilBufferIsAllocated(CommitImpl).Ret();
|
||||||
|
|
||||||
|
Result CommitImpl()
|
||||||
|
{
|
||||||
|
using var scopedRegistration = new ScopedBufferManagerContextRegistration();
|
||||||
|
using var unionStorage = new UnionStorage();
|
||||||
|
|
||||||
|
Result res = tempBaseStorage.GetSize(out long baseStorageSize);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
using var storageBufferingBase = new BufferedStorage();
|
||||||
|
res = storageBufferingBase.Initialize(in tempBaseStorage, bufferManager, (int)blockSize, bufferCount: 16);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
res = tempLogStorage.GetSize(out long logStorageSize);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
using var storageBufferingLog = new BufferedStorage();
|
||||||
|
res = storageBufferingBase.Initialize(in tempLogStorage, bufferManager, (int)blockSize, bufferCount: 2);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
using var bufferedBaseStorage = new ValueSubStorage(storageBufferingBase, 0, baseStorageSize);
|
||||||
|
using var bufferedLogStorage = new ValueSubStorage(storageBufferingLog, 0, logStorageSize);
|
||||||
|
|
||||||
|
res = unionStorage.Initialize(in bufferedBaseStorage, in bufferedLogStorage, blockSize);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
res = unionStorage.Commit();
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
res = unionStorage.Flush();
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result ReadExtraData(out JournalIntegritySaveDataFileSystem.ExtraData outData,
|
public static Result ReadExtraData(out JournalIntegritySaveDataFileSystem.ExtraData outData,
|
||||||
in ValueSubStorage saveImageStorage, IBufferManager bufferManager, IMacGenerator macGenerator,
|
in ValueSubStorage saveImageStorage, IBufferManager bufferManager, IMacGenerator macGenerator,
|
||||||
IHash256GeneratorFactorySelector hashGeneratorFactorySelector, uint minimumVersion)
|
IHash256GeneratorFactorySelector hashGeneratorFactorySelector, uint minimumVersion)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
UnsafeHelpers.SkipParamInit(out outData);
|
||||||
|
|
||||||
|
using var tempSaveImageStorage = new ValueSubStorage(in saveImageStorage);
|
||||||
|
JournalIntegritySaveDataFileSystem.ExtraData extraData = default;
|
||||||
|
|
||||||
|
Result res = BufferManagerUtility.DoContinuouslyUntilBufferIsAllocated(ReadExtraDataImpl).Ret();
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
outData = extraData;
|
||||||
|
return Result.Success;
|
||||||
|
|
||||||
|
Result ReadExtraDataImpl()
|
||||||
|
{
|
||||||
|
using var scopedRegistration = new ScopedBufferManagerContextRegistration();
|
||||||
|
|
||||||
|
return JournalIntegritySaveDataFileSystem.ReadExtraData(out extraData, in tempSaveImageStorage,
|
||||||
|
bufferManager, macGenerator, hashGeneratorFactorySelector, minimumVersion).Ret();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result Initialize(in ValueSubStorage baseStorage, IBufferManager bufferManager, IMacGenerator macGenerator,
|
public Result Initialize(in ValueSubStorage baseStorage, IBufferManager bufferManager, IMacGenerator macGenerator,
|
||||||
IHash256GeneratorFactorySelector hashGeneratorFactorySelector, uint minimumVersion)
|
IHash256GeneratorFactorySelector hashGeneratorFactorySelector, uint minimumVersion)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Assert.SdkRequiresNotNull(bufferManager);
|
||||||
|
|
||||||
|
_baseStorage.Set(in baseStorage);
|
||||||
|
_bufferManager = bufferManager;
|
||||||
|
_bufferManagerSet = new FileSystemBufferManagerSet();
|
||||||
|
|
||||||
|
for (int i = 0; i < _bufferManagerSet.Buffers.Length; i++)
|
||||||
|
{
|
||||||
|
_bufferManagerSet.Buffers[i] = bufferManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FinalizeObject()
|
using var scopedRegistration = new ScopedBufferManagerContextRegistration();
|
||||||
|
BufferManagerUtility.EnableBlockingBufferManagerAllocation();
|
||||||
|
|
||||||
|
Result res = _fileSystem.Initialize(in _baseStorage, _bufferManagerSet, _bufferManager, _mutex, macGenerator,
|
||||||
|
hashGeneratorFactorySelector, minimumVersion);
|
||||||
|
if (res.IsFailure()) return res.Miss();
|
||||||
|
|
||||||
|
base.Initialize(_fileSystem);
|
||||||
|
return Result.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public new void FinalizeObject()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
using var scopedRegistration = new ScopedBufferManagerContextRegistration();
|
||||||
|
BufferManagerUtility.EnableBlockingBufferManagerAllocation();
|
||||||
|
|
||||||
|
_fileSystem.FinalizeObject();
|
||||||
|
base.FinalizeObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result WriteExtraData(in JournalIntegritySaveDataFileSystem.ExtraData extraData)
|
public Result WriteExtraData(in JournalIntegritySaveDataFileSystem.ExtraData extraData)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return _fileSystem.WriteExtraData(in extraData).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result ReadExtraData(out JournalIntegritySaveDataFileSystem.ExtraData outExtraData)
|
public void ReadExtraData(out JournalIntegritySaveDataFileSystem.ExtraData outExtraData)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
_fileSystem.ReadExtraData(out outExtraData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result RollbackOnlyModified()
|
public Result RollbackOnlyModified()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return BufferManagerUtility.DoContinuouslyUntilBufferIsAllocated(RollbackOnlyModifiedImpl).Ret();
|
||||||
|
|
||||||
|
Result RollbackOnlyModifiedImpl()
|
||||||
|
{
|
||||||
|
using var scopedRegistration = new ScopedBufferManagerContextRegistration();
|
||||||
|
|
||||||
|
return _fileSystem.RollbackOnlyModified().Ret();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result UpdateMac(in ValueSubStorage saveDataStorage, IMacGenerator macGenerator,
|
public static Result UpdateMac(in ValueSubStorage saveDataStorage, IMacGenerator macGenerator,
|
||||||
IHash256GeneratorFactorySelector hashGeneratorFactorySelector, uint minimumVersion)
|
IHash256GeneratorFactorySelector hashGeneratorFactorySelector, uint minimumVersion)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return JournalIntegritySaveDataFileSystem
|
||||||
|
.UpdateMac(in saveDataStorage, macGenerator, hashGeneratorFactorySelector, minimumVersion).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long GetCounterForBundledCommit()
|
public long GetCounterForBundledCommit()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return _fileSystem.GetCounterForBundledCommit();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result CommitFileSystem()
|
public Result CommitFileSystem()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return Commit().Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ExtractParameters(out JournalIntegritySaveDataParameters outParams)
|
public void ExtractParameters(out JournalIntegritySaveDataParameters outParams)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
outParams = default;
|
||||||
|
|
||||||
|
_fileSystem.ExtractParameters(out outParams.BlockSize, out outParams.CountDataBlock,
|
||||||
|
out outParams.CountJournalBlock, out outParams.CountExpandMax, out outParams.Version,
|
||||||
|
out outParams.IsMetaSetVerificationEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JournalIntegritySaveDataParameters SetUpSaveDataParameters(long blockSize, long dataSize, long journalSize)
|
public static JournalIntegritySaveDataParameters SetUpSaveDataParameters(long blockSize, long dataSize, long journalSize)
|
||||||
|
@ -151,11 +352,23 @@ public class JournalIntegritySaveDataFileSystemDriver : ProxyFileSystemWithRetry
|
||||||
|
|
||||||
public Result AcceptVisitor(IInternalStorageFileSystemVisitor visitor)
|
public Result AcceptVisitor(IInternalStorageFileSystemVisitor visitor)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Assert.SdkRequiresNotNull(visitor);
|
||||||
|
|
||||||
|
return BufferManagerUtility.DoContinuouslyUntilBufferIsAllocated(AcceptVisitorImpl).Ret();
|
||||||
|
|
||||||
|
Result AcceptVisitorImpl()
|
||||||
|
{
|
||||||
|
using var scopedRegistration = new ScopedBufferManagerContextRegistration();
|
||||||
|
BufferManagerUtility.EnableBlockingBufferManagerAllocation();
|
||||||
|
|
||||||
|
return _fileSystem.AcceptVisitor(visitor).Ret();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result UpdateMac(IMacGenerator macGenerator)
|
public Result UpdateMac(IMacGenerator macGenerator)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Assert.SdkRequiresNotNull(macGenerator);
|
||||||
|
|
||||||
|
return _fileSystem.UpdateMacAndCommit(macGenerator).Ret();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -107,7 +107,7 @@ public class ProxyFileSystemWithRetryingBufferAllocation : IFileSystem
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Finalize(IFileSystem fileSystem)
|
public void FinalizeObject()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ public interface IInternalStorageFileSystem
|
||||||
{
|
{
|
||||||
Result AcceptVisitor(IInternalStorageFileSystemVisitor visitor);
|
Result AcceptVisitor(IInternalStorageFileSystemVisitor visitor);
|
||||||
Result WriteExtraData(in JournalIntegritySaveDataFileSystem.ExtraData extraData);
|
Result WriteExtraData(in JournalIntegritySaveDataFileSystem.ExtraData extraData);
|
||||||
Result ReadExtraData(out JournalIntegritySaveDataFileSystem.ExtraData outExtraData);
|
void ReadExtraData(out JournalIntegritySaveDataFileSystem.ExtraData outExtraData);
|
||||||
Result CommitFileSystem();
|
Result CommitFileSystem();
|
||||||
Result UpdateMac(IMacGenerator macGenerator);
|
Result UpdateMac(IMacGenerator macGenerator);
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ public class UnionStorage : IStorage
|
||||||
header[0] = blockSize;
|
header[0] = blockSize;
|
||||||
header[1] = Sentinel;
|
header[1] = Sentinel;
|
||||||
|
|
||||||
return storage.Write(0, SpanHelpers.AsReadOnlyByteSpan(in header));
|
return storage.Write(0, SpanHelpers.AsReadOnlyByteSpan(in header)).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result Initialize(ref readonly ValueSubStorage baseStorage, ref readonly ValueSubStorage logStorage,
|
public Result Initialize(ref readonly ValueSubStorage baseStorage, ref readonly ValueSubStorage logStorage,
|
||||||
|
@ -157,7 +157,7 @@ public class UnionStorage : IStorage
|
||||||
if (res.IsFailure()) return res.Miss();
|
if (res.IsFailure()) return res.Miss();
|
||||||
}
|
}
|
||||||
|
|
||||||
return _baseStorage.Flush();
|
return _baseStorage.Flush().Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result Read(long offset, Span<byte> destination)
|
public override Result Read(long offset, Span<byte> destination)
|
||||||
|
@ -292,7 +292,7 @@ public class UnionStorage : IStorage
|
||||||
{
|
{
|
||||||
Assert.SdkRequiresNotNull(_buffer);
|
Assert.SdkRequiresNotNull(_buffer);
|
||||||
|
|
||||||
return _baseStorage.GetSize(out size);
|
return _baseStorage.GetSize(out size).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Result SetSize(long size)
|
public override Result SetSize(long size)
|
||||||
|
@ -317,7 +317,7 @@ public class UnionStorage : IStorage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _baseStorage.OperateRange(outBuffer, operationId, offset, size, inBuffer);
|
return _baseStorage.OperateRange(outBuffer, operationId, offset, size, inBuffer).Ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result FindLog(out bool logFound, out long outLogOffset, long offsetOriginal)
|
private Result FindLog(out bool logFound, out long outLogOffset, long offsetOriginal)
|
||||||
|
|
|
@ -43,4 +43,9 @@
|
||||||
</AssemblyAttribute>
|
</AssemblyAttribute>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<!-- Packages that are only used when building -->
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="JetBrains.Annotations" Version="2023.3.0" ExcludeAssets="runtime" PrivateAssets="all" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
Loading…
Reference in a new issue