fs: first pass at compressed storage (works on iridium with wip hac2l code)

This commit is contained in:
Michael Scire 2022-03-12 13:03:17 -08:00 committed by SciresM
parent df631d74f0
commit d638bbbb62
34 changed files with 2375 additions and 722 deletions

View file

@ -239,10 +239,10 @@ namespace ams::fssystem {
return it != m_attr_list.end() ? std::addressof(*it) : nullptr;
}
const std::pair<uintptr_t, size_t> FileSystemBufferManager::AllocateBufferImpl(size_t size, const BufferAttribute &attr) {
const fs::IBufferManager::MemoryRange FileSystemBufferManager::DoAllocateBuffer(size_t size, const BufferAttribute &attr) {
std::scoped_lock lk(m_mutex);
std::pair<uintptr_t, size_t> range = {};
fs::IBufferManager::MemoryRange range = {};
const auto order = m_buddy_heap.GetOrderFromBytes(size);
AMS_ASSERT(order >= 0);
@ -277,7 +277,7 @@ namespace ams::fssystem {
return range;
}
void FileSystemBufferManager::DeallocateBufferImpl(uintptr_t address, size_t size) {
void FileSystemBufferManager::DoDeallocateBuffer(uintptr_t address, size_t size) {
AMS_ASSERT(util::IsPowerOfTwo(size));
std::scoped_lock lk(m_mutex);
@ -285,7 +285,7 @@ namespace ams::fssystem {
m_buddy_heap.Free(reinterpret_cast<void *>(address), m_buddy_heap.GetOrderFromBytes(size));
}
FileSystemBufferManager::CacheHandle FileSystemBufferManager::RegisterCacheImpl(uintptr_t address, size_t size, const BufferAttribute &attr) {
FileSystemBufferManager::CacheHandle FileSystemBufferManager::DoRegisterCache(uintptr_t address, size_t size, const BufferAttribute &attr) {
std::scoped_lock lk(m_mutex);
CacheHandle handle = 0;
@ -312,10 +312,10 @@ namespace ams::fssystem {
return handle;
}
const std::pair<uintptr_t, size_t> FileSystemBufferManager::AcquireCacheImpl(CacheHandle handle) {
const fs::IBufferManager::MemoryRange FileSystemBufferManager::DoAcquireCache(CacheHandle handle) {
std::scoped_lock lk(m_mutex);
std::pair<uintptr_t, size_t> range = {};
fs::IBufferManager::MemoryRange range = {};
if (m_cache_handle_table.Unregister(std::addressof(range.first), std::addressof(range.second), handle)) {
const size_t total_allocatable_size = m_buddy_heap.GetTotalFreeSize() + m_cache_handle_table.GetTotalCacheSize();
m_peak_total_allocatable_size = std::min(m_peak_total_allocatable_size, total_allocatable_size);
@ -327,33 +327,33 @@ namespace ams::fssystem {
return range;
}
size_t FileSystemBufferManager::GetTotalSizeImpl() const {
size_t FileSystemBufferManager::DoGetTotalSize() const {
return m_total_size;
}
size_t FileSystemBufferManager::GetFreeSizeImpl() const {
size_t FileSystemBufferManager::DoGetFreeSize() const {
std::scoped_lock lk(m_mutex);
return m_buddy_heap.GetTotalFreeSize();
}
size_t FileSystemBufferManager::GetTotalAllocatableSizeImpl() const {
size_t FileSystemBufferManager::DoGetTotalAllocatableSize() const {
return this->GetFreeSize() + m_cache_handle_table.GetTotalCacheSize();
}
size_t FileSystemBufferManager::GetPeakFreeSizeImpl() const {
size_t FileSystemBufferManager::DoGetFreeSizePeak() const {
return m_peak_free_size;
}
size_t FileSystemBufferManager::GetPeakTotalAllocatableSizeImpl() const {
size_t FileSystemBufferManager::DoGetTotalAllocatableSizePeak() const {
return m_peak_total_allocatable_size;
}
size_t FileSystemBufferManager::GetRetriedCountImpl() const {
size_t FileSystemBufferManager::DoGetRetriedCount() const {
return m_retried_count;
}
void FileSystemBufferManager::ClearPeakImpl() {
void FileSystemBufferManager::DoClearPeak() {
m_peak_free_size = this->GetFreeSize();
m_retried_count = 0;
}

View file

@ -117,7 +117,11 @@ namespace ams::fssystem {
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
R_UNLESS(util::IsAligned(offset, BlockSize), fs::ResultInvalidOffset());
R_UNLESS(util::IsAligned(size, BlockSize), fs::ResultInvalidSize());
R_UNLESS(m_table.Includes(offset, size), fs::ResultOutOfRange());
BucketTree::Offsets table_offsets;
R_TRY(m_table.GetOffsets(std::addressof(table_offsets)));
R_UNLESS(table_offsets.IsInclude(offset, size), fs::ResultOutOfRange());
/* Read the data. */
R_TRY(m_data_storage.Read(offset, buffer, size));
@ -130,8 +134,8 @@ namespace ams::fssystem {
R_TRY(m_table.Find(std::addressof(visitor), offset));
{
const auto entry_offset = visitor.Get<Entry>()->GetOffset();
R_UNLESS(util::IsAligned(entry_offset, BlockSize), fs::ResultInvalidAesCtrCounterExtendedEntryOffset());
R_UNLESS(0 <= entry_offset && m_table.Includes(entry_offset), fs::ResultInvalidAesCtrCounterExtendedEntryOffset());
R_UNLESS(util::IsAligned(entry_offset, BlockSize), fs::ResultInvalidAesCtrCounterExtendedEntryOffset());
R_UNLESS(0 <= entry_offset && table_offsets.IsInclude(entry_offset), fs::ResultInvalidAesCtrCounterExtendedEntryOffset());
}
/* Prepare to read in chunks. */
@ -152,9 +156,9 @@ namespace ams::fssystem {
if (visitor.CanMoveNext()) {
R_TRY(visitor.MoveNext());
next_entry_offset = visitor.Get<Entry>()->GetOffset();
R_UNLESS(m_table.Includes(next_entry_offset), fs::ResultInvalidAesCtrCounterExtendedEntryOffset());
R_UNLESS(table_offsets.IsInclude(next_entry_offset), fs::ResultInvalidAesCtrCounterExtendedEntryOffset());
} else {
next_entry_offset = m_table.GetEnd();
next_entry_offset = table_offsets.end_offset;
}
R_UNLESS(util::IsAligned(next_entry_offset, BlockSize), fs::ResultInvalidAesCtrCounterExtendedEntryOffset());
R_UNLESS(cur_offset < next_entry_offset, fs::ResultInvalidAesCtrCounterExtendedEntryOffset());
@ -192,22 +196,13 @@ namespace ams::fssystem {
case fs::OperationId::Invalidate:
{
/* Validate preconditions. */
AMS_ASSERT(offset >= 0);
AMS_ASSERT(this->IsInitialized());
/* Succeed if there's nothing to operate on. */
R_SUCCEED_IF(size == 0);
/* Validate arguments. */
R_UNLESS(util::IsAligned(offset, BlockSize), fs::ResultInvalidOffset());
R_UNLESS(util::IsAligned(size, BlockSize), fs::ResultInvalidSize());
R_UNLESS(m_table.Includes(offset, size), fs::ResultOutOfRange());
/* Invalidate our table's cache. */
R_TRY(m_table.InvalidateCache());
/* Operate on our data storage. */
R_TRY(m_data_storage.OperateRange(dst, dst_size, op_id, offset, size, src, src_size));
R_TRY(m_data_storage.OperateRange(fs::OperationId::Invalidate, 0, std::numeric_limits<s64>::max()));
return ResultSuccess();
}
@ -230,7 +225,11 @@ namespace ams::fssystem {
/* Validate arguments. */
R_UNLESS(util::IsAligned(offset, BlockSize), fs::ResultInvalidOffset());
R_UNLESS(util::IsAligned(size, BlockSize), fs::ResultInvalidSize());
R_UNLESS(m_table.Includes(offset, size), fs::ResultOutOfRange());
BucketTree::Offsets table_offsets;
R_TRY(m_table.GetOffsets(std::addressof(table_offsets)));
R_UNLESS(table_offsets.IsInclude(offset, size), fs::ResultOutOfRange());
/* Operate on our data storage. */
R_TRY(m_data_storage.OperateRange(dst, dst_size, op_id, offset, size, src, src_size));

View file

@ -249,9 +249,10 @@ namespace ams::fssystem {
/* Handle any data after the aligned portion. */
if (core_offset_end < offset_end) {
const auto tail_size = static_cast<size_t>(offset_end - core_offset_end);
const auto tail_buffer = static_cast<char *>(buffer) + (core_offset_end - offset);
const auto tail_size = static_cast<size_t>(offset_end - core_offset_end);
R_TRY(m_base_storage->Read(core_offset_end, pooled_buffer.GetBuffer(), m_data_align));
std::memcpy(buffer, pooled_buffer.GetBuffer(), tail_size);
std::memcpy(tail_buffer, pooled_buffer.GetBuffer(), tail_size);
}
return ResultSuccess();

View file

@ -154,7 +154,7 @@ namespace ams::fssystem {
/* Allocate node. */
R_UNLESS(m_node_l1.Allocate(allocator, node_size), fs::ResultBufferAllocationFailed());
auto node_guard = SCOPE_GUARD { m_node_l1.Free(node_size); };
ON_RESULT_FAILURE { m_node_l1.Free(node_size); };
/* Read node. */
R_TRY(node_storage.Read(0, m_node_l1.Get(), node_size));
@ -186,12 +186,13 @@ namespace ams::fssystem {
m_entry_count = entry_count;
m_offset_count = offset_count;
m_entry_set_count = entry_set_count;
m_start_offset = start_offset;
m_end_offset = end_offset;
m_offset_cache.offsets.start_offset = start_offset;
m_offset_cache.offsets.end_offset = end_offset;
m_offset_cache.is_initialized = true;
/* Cancel guard. */
node_guard.Cancel();
return ResultSuccess();
R_SUCCEED();
}
void BucketTree::Initialize(size_t node_size, s64 end_offset) {
@ -201,7 +202,10 @@ namespace ams::fssystem {
AMS_ASSERT(!this->IsInitialized());
m_node_size = node_size;
m_end_offset = end_offset;
m_offset_cache.offsets.start_offset = 0;
m_offset_cache.offsets.end_offset = end_offset;
m_offset_cache.is_initialized = true;
}
void BucketTree::Finalize() {
@ -214,69 +218,77 @@ namespace ams::fssystem {
m_entry_count = 0;
m_offset_count = 0;
m_entry_set_count = 0;
m_start_offset = 0;
m_end_offset = 0;
m_offset_cache.offsets.start_offset = 0;
m_offset_cache.offsets.end_offset = 0;
m_offset_cache.is_initialized = false;
}
}
Result BucketTree::Find(Visitor *visitor, s64 virtual_address) const {
Result BucketTree::Find(Visitor *visitor, s64 virtual_address) {
AMS_ASSERT(visitor != nullptr);
AMS_ASSERT(this->IsInitialized());
R_UNLESS(virtual_address >= 0, fs::ResultInvalidOffset());
R_UNLESS(!this->IsEmpty(), fs::ResultOutOfRange());
R_TRY(visitor->Initialize(this));
BucketTree::Offsets offsets;
R_TRY(this->GetOffsets(std::addressof(offsets)));
R_TRY(visitor->Initialize(this, offsets));
return visitor->Find(virtual_address);
}
Result BucketTree::InvalidateCache() {
/* Invalidate the node storage cache. */
{
s64 storage_size;
R_TRY(m_node_storage.GetSize(std::addressof(storage_size)));
R_TRY(m_node_storage.OperateRange(fs::OperationId::Invalidate, 0, storage_size));
}
/* Refresh start/end offsets. */
{
/* Read node. */
R_TRY(m_node_storage.Read(0, m_node_l1.Get(), m_node_size));
/* Verify node. */
R_TRY(m_node_l1->Verify(0, m_node_size, sizeof(s64)));
/* Validate offsets. */
const auto * const node = m_node_l1.Get<Node>();
s64 start_offset;
if (m_offset_count < m_entry_set_count && node->GetCount() < m_offset_count) {
start_offset = *node->GetEnd();
} else {
start_offset = *node->GetBegin();
}
const auto end_offset = node->GetEndOffset();
R_UNLESS(0 <= start_offset && start_offset <= node->GetBeginOffset(), fs::ResultInvalidBucketTreeEntryOffset());
R_UNLESS(start_offset < end_offset, fs::ResultInvalidBucketTreeEntryOffset());
/* Set refreshed offsets. */
m_start_offset = start_offset;
m_end_offset = end_offset;
}
R_TRY(m_node_storage.OperateRange(fs::OperationId::Invalidate, 0, std::numeric_limits<s64>::max()));
/* Invalidate the entry storage cache. */
{
s64 storage_size;
R_TRY(m_entry_storage.GetSize(std::addressof(storage_size)));
R_TRY(m_entry_storage.OperateRange(fs::OperationId::Invalidate, 0, storage_size));
}
R_TRY(m_entry_storage.OperateRange(fs::OperationId::Invalidate, 0, std::numeric_limits<s64>::max()));
return ResultSuccess();
/* Reset our offsets. */
m_offset_cache.is_initialized = false;
R_SUCCEED();
}
Result BucketTree::Visitor::Initialize(const BucketTree *tree) {
Result BucketTree::EnsureOffsetCache() {
/* If we already have an offset cache, we're good. */
R_SUCCEED_IF(m_offset_cache.is_initialized);
/* Acquire exclusive right to edit the offset cache. */
std::scoped_lock lk(m_offset_cache.mutex);
/* Check again, to be sure. */
R_SUCCEED_IF(m_offset_cache.is_initialized);
/* Read/verify L1. */
R_TRY(m_node_storage.Read(0, m_node_l1.Get(), m_node_size));
R_TRY(m_node_l1->Verify(0, m_node_size, sizeof(s64)));
/* Get the node. */
auto * const node = m_node_l1.Get<Node>();
s64 start_offset;
if (m_offset_count < m_entry_set_count && node->GetCount() < m_offset_count) {
start_offset = *node->GetEnd();
} else {
start_offset = *node->GetBegin();
}
const auto end_offset = node->GetEndOffset();
R_UNLESS(0 <= start_offset && start_offset <= node->GetBeginOffset(), fs::ResultInvalidBucketTreeEntryOffset());
R_UNLESS(start_offset < end_offset, fs::ResultInvalidBucketTreeEntryOffset());
m_offset_cache.offsets.start_offset = start_offset;
m_offset_cache.offsets.end_offset = end_offset;
m_offset_cache.is_initialized = true;
R_SUCCEED();
}
Result BucketTree::Visitor::Initialize(const BucketTree *tree, const BucketTree::Offsets &offsets) {
AMS_ASSERT(tree != nullptr);
AMS_ASSERT(m_tree == nullptr || m_tree == tree);
@ -284,7 +296,8 @@ namespace ams::fssystem {
m_entry = tree->GetAllocator()->Allocate(tree->m_entry_size);
R_UNLESS(m_entry != nullptr, fs::ResultBufferAllocationFailed());
m_tree = tree;
m_tree = tree;
m_offsets = offsets;
}
return ResultSuccess();
@ -319,7 +332,7 @@ namespace ams::fssystem {
/* Read the new entry. */
const auto entry_size = m_tree->m_entry_size;
const auto entry_offset = impl::GetBucketTreeEntryOffset(m_entry_set.info.index, m_tree->m_node_size, entry_size, entry_index);
R_TRY(m_tree->m_entry_storage.Read(entry_offset, std::addressof(m_entry), entry_size));
R_TRY(m_tree->m_entry_storage.Read(entry_offset, m_entry, entry_size));
/* Note that we changed index. */
m_entry_index = entry_index;
@ -357,7 +370,7 @@ namespace ams::fssystem {
/* Read the new entry. */
const auto entry_size = m_tree->m_entry_size;
const auto entry_offset = impl::GetBucketTreeEntryOffset(m_entry_set.info.index, m_tree->m_node_size, entry_size, entry_index);
R_TRY(m_tree->m_entry_storage.Read(entry_offset, std::addressof(m_entry), entry_size));
R_TRY(m_tree->m_entry_storage.Read(entry_offset, m_entry, entry_size));
/* Note that we changed index. */
m_entry_index = entry_index;

View file

@ -59,14 +59,17 @@ namespace ams::fssystem {
R_UNLESS(out_entries != nullptr || entry_count == 0, fs::ResultNullptrArgument());
/* Check that our range is valid. */
R_UNLESS(m_table.Includes(offset, size), fs::ResultOutOfRange());
BucketTree::Offsets table_offsets;
R_TRY(m_table.GetOffsets(std::addressof(table_offsets)));
R_UNLESS(table_offsets.IsInclude(offset, size), fs::ResultOutOfRange());
/* Find the offset in our tree. */
BucketTree::Visitor visitor;
R_TRY(m_table.Find(std::addressof(visitor), offset));
{
const auto entry_offset = visitor.Get<Entry>()->GetVirtualOffset();
R_UNLESS(0 <= entry_offset && m_table.Includes(entry_offset), fs::ResultInvalidIndirectEntryOffset());
R_UNLESS(0 <= entry_offset && table_offsets.IsInclude(entry_offset), fs::ResultInvalidIndirectEntryOffset());
}
/* Prepare to loop over entries. */
@ -96,7 +99,7 @@ namespace ams::fssystem {
/* Write the output count. */
*out_entry_count = count;
return ResultSuccess();
R_SUCCEED();
}
Result IndirectStorage::Read(s64 offset, void *buffer, size_t size) {
@ -110,35 +113,28 @@ namespace ams::fssystem {
/* Ensure that we have a buffer to read to. */
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
R_TRY(this->OperatePerEntry<true>(offset, size, [=](fs::IStorage *storage, s64 data_offset, s64 cur_offset, s64 cur_size) -> Result {
R_TRY((this->OperatePerEntry<true, true>(offset, size, [=](fs::IStorage *storage, s64 data_offset, s64 cur_offset, s64 cur_size) -> Result {
R_TRY(storage->Read(data_offset, reinterpret_cast<u8 *>(buffer) + (cur_offset - offset), static_cast<size_t>(cur_size)));
return ResultSuccess();
}));
R_SUCCEED();
})));
return ResultSuccess();
R_SUCCEED();
}
Result IndirectStorage::OperateRange(void *dst, size_t dst_size, fs::OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) {
switch (op_id) {
case fs::OperationId::Invalidate:
{
if (size > 0) {
/* Validate arguments. */
R_UNLESS(m_table.Includes(offset, size), fs::ResultOutOfRange());
if (!m_table.IsEmpty()) {
/* Invalidate our table's cache. */
R_TRY(m_table.InvalidateCache());
if (!m_table.IsEmpty()) {
/* Invalidate our table's cache. */
R_TRY(m_table.InvalidateCache());
/* Operate on our entries. */
R_TRY(this->OperatePerEntry<false>(offset, size, [=](fs::IStorage *storage, s64 data_offset, s64 cur_offset, s64 cur_size) -> Result {
AMS_UNUSED(cur_offset);
R_TRY(storage->OperateRange(dst, dst_size, op_id, data_offset, cur_size, src, src_size));
return ResultSuccess();
}));
/* Invalidate our storages. */
for (auto &storage : m_data_storage) {
R_TRY(storage.OperateRange(fs::OperationId::Invalidate, 0, std::numeric_limits<s64>::max()));
}
return ResultSuccess();
}
return ResultSuccess();
R_SUCCEED();
}
case fs::OperationId::QueryRange:
{
@ -148,33 +144,37 @@ namespace ams::fssystem {
if (size > 0) {
/* Validate arguments. */
R_UNLESS(m_table.Includes(offset, size), fs::ResultOutOfRange());
BucketTree::Offsets table_offsets;
R_TRY(m_table.GetOffsets(std::addressof(table_offsets)));
R_UNLESS(table_offsets.IsInclude(offset, size), fs::ResultOutOfRange());
if (!m_table.IsEmpty()) {
/* Create a new info. */
fs::QueryRangeInfo merged_info;
merged_info.Clear();
/* Operate on our entries. */
R_TRY(this->OperatePerEntry<false>(offset, size, [=, &merged_info](fs::IStorage *storage, s64 data_offset, s64 cur_offset, s64 cur_size) -> Result {
R_TRY((this->OperatePerEntry<false, true>(offset, size, [=, &merged_info](fs::IStorage *storage, s64 data_offset, s64 cur_offset, s64 cur_size) -> Result {
AMS_UNUSED(cur_offset);
fs::QueryRangeInfo cur_info;
R_TRY(storage->OperateRange(std::addressof(cur_info), sizeof(cur_info), op_id, data_offset, cur_size, src, src_size));
merged_info.Merge(cur_info);
return ResultSuccess();
}));
R_SUCCEED();
})));
/* Write the merged info. */
*reinterpret_cast<fs::QueryRangeInfo *>(dst) = merged_info;
}
}
return ResultSuccess();
R_SUCCEED();
}
default:
return fs::ResultUnsupportedOperationInIndirectStorageC();
}
return ResultSuccess();
R_SUCCEED();
}
}

View file

@ -17,7 +17,7 @@
namespace ams::fssystem {
Result IntegrityRomFsStorage::Initialize(save::HierarchicalIntegrityVerificationInformation level_hash_info, Hash master_hash, save::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation storage_info, IBufferManager *bm, IHash256GeneratorFactory *hgf) {
Result IntegrityRomFsStorage::Initialize(save::HierarchicalIntegrityVerificationInformation level_hash_info, Hash master_hash, save::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation storage_info, fs::IBufferManager *bm, IHash256GeneratorFactory *hgf) {
/* Validate preconditions. */
AMS_ASSERT(bm != nullptr);

View file

@ -1105,7 +1105,7 @@ namespace ams::fssystem {
return this->CreateCompressedStorage(out, out_cmp, out_meta, std::move(base_storage), compression_info, m_reader->GetDecompressor(), m_allocator, m_buffer_manager);
}
Result NcaFileSystemDriver::CreateCompressedStorage(std::shared_ptr<fs::IStorage> *out, std::shared_ptr<fssystem::CompressedStorage> *out_cmp, std::shared_ptr<fs::IStorage> *out_meta, std::shared_ptr<fs::IStorage> base_storage, const NcaCompressionInfo &compression_info, GetDecompressorFunction get_decompressor, MemoryResource *allocator, IBufferManager *buffer_manager) {
Result NcaFileSystemDriver::CreateCompressedStorage(std::shared_ptr<fs::IStorage> *out, std::shared_ptr<fssystem::CompressedStorage> *out_cmp, std::shared_ptr<fs::IStorage> *out_meta, std::shared_ptr<fs::IStorage> base_storage, const NcaCompressionInfo &compression_info, GetDecompressorFunction get_decompressor, MemoryResource *allocator, fs::IBufferManager *buffer_manager) {
/* Check pre-conditions. */
AMS_ASSERT(out != nullptr);
AMS_ASSERT(base_storage != nullptr);

View file

@ -29,13 +29,17 @@ namespace ams::fssystem {
R_UNLESS(buffer != nullptr, fs::ResultNullptrArgument());
if (this->GetEntryTable().IsEmpty()) {
R_UNLESS(this->GetEntryTable().Includes(offset, size), fs::ResultOutOfRange());
BucketTree::Offsets table_offsets;
R_TRY(this->GetEntryTable().GetOffsets(std::addressof(table_offsets)));
R_UNLESS(table_offsets.IsInclude(offset, size), fs::ResultOutOfRange());
std::memset(buffer, 0, size);
} else {
R_TRY(this->OperatePerEntry<false>(offset, size, [=](fs::IStorage *storage, s64 data_offset, s64 cur_offset, s64 cur_size) -> Result {
R_TRY((this->OperatePerEntry<false, true>(offset, size, [=](fs::IStorage *storage, s64 data_offset, s64 cur_offset, s64 cur_size) -> Result {
R_TRY(storage->Read(data_offset, reinterpret_cast<u8 *>(buffer) + (cur_offset - offset), static_cast<size_t>(cur_size)));
return ResultSuccess();
}));
})));
}
return ResultSuccess();

View file

@ -35,7 +35,7 @@ namespace ams::fssystem::save {
private:
BufferedStorage *m_buffered_storage;
std::pair<uintptr_t, size_t> m_memory_range;
IBufferManager::CacheHandle m_cache_handle;
fs::IBufferManager::CacheHandle m_cache_handle;
s64 m_offset;
std::atomic<bool> m_is_valid;
std::atomic<bool> m_is_dirty;
@ -139,7 +139,7 @@ namespace ams::fssystem::save {
/* Ensure our buffer state is coherent. */
if (m_memory_range.first != InvalidAddress && !m_is_dirty) {
if (this->IsValid()) {
m_cache_handle = m_buffered_storage->m_buffer_manager->RegisterCache(m_memory_range.first, m_memory_range.second, IBufferManager::BufferAttribute());
m_cache_handle = m_buffered_storage->m_buffer_manager->RegisterCache(m_memory_range.first, m_memory_range.second, fs::IBufferManager::BufferAttribute());
} else {
m_buffered_storage->m_buffer_manager->DeallocateBuffer(m_memory_range.first, m_memory_range.second);
}
@ -360,11 +360,11 @@ namespace ams::fssystem::save {
}
private:
Result AllocateFetchBuffer() {
IBufferManager *buffer_manager = m_buffered_storage->m_buffer_manager;
fs::IBufferManager *buffer_manager = m_buffered_storage->m_buffer_manager;
AMS_ASSERT(buffer_manager->AcquireCache(m_cache_handle).first == InvalidAddress);
auto range_guard = SCOPE_GUARD { m_memory_range.first = InvalidAddress; };
R_TRY(buffers::AllocateBufferUsingBufferManagerContext(std::addressof(m_memory_range), buffer_manager, m_buffered_storage->m_block_size, IBufferManager::BufferAttribute(), [](const std::pair<uintptr_t, size_t> &buffer) {
R_TRY(buffers::AllocateBufferUsingBufferManagerContext(std::addressof(m_memory_range), buffer_manager, m_buffered_storage->m_block_size, fs::IBufferManager::BufferAttribute(), [](const std::pair<uintptr_t, size_t> &buffer) {
return buffer.first != 0;
}, AMS_CURRENT_FUNCTION_NAME));
@ -591,7 +591,7 @@ namespace ams::fssystem::save {
this->Finalize();
}
Result BufferedStorage::Initialize(fs::SubStorage base_storage, IBufferManager *buffer_manager, size_t block_size, s32 buffer_count) {
Result BufferedStorage::Initialize(fs::SubStorage base_storage, fs::IBufferManager *buffer_manager, size_t block_size, s32 buffer_count) {
AMS_ASSERT(buffer_manager != nullptr);
AMS_ASSERT(block_size > 0);
AMS_ASSERT(util::IsPowerOfTwo(block_size));

View file

@ -17,7 +17,7 @@
namespace ams::fssystem::save {
Result IntegrityVerificationStorage::Initialize(fs::SubStorage hs, fs::SubStorage ds, s64 verif_block_size, s64 upper_layer_verif_block_size, IBufferManager *bm, fssystem::IHash256GeneratorFactory *hgf, const fs::HashSalt &salt, bool is_real_data, fs::StorageType storage_type) {
Result IntegrityVerificationStorage::Initialize(fs::SubStorage hs, fs::SubStorage ds, s64 verif_block_size, s64 upper_layer_verif_block_size, fs::IBufferManager *bm, fssystem::IHash256GeneratorFactory *hgf, const fs::HashSalt &salt, bool is_real_data, fs::StorageType storage_type) {
/* Validate preconditions. */
AMS_ASSERT(verif_block_size >= HashSize);
AMS_ASSERT(bm != nullptr);