From 0398b34370f9a6d739e0101378770c7d592a4806 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Thu, 10 Aug 2023 21:49:19 -0400
Subject: [PATCH] fssystem: reduce overalignment of unbuffered storage
 operations

---
 ...rchical_integrity_verification_storage.cpp | 11 ++---
 ...rarchical_integrity_verification_storage.h |  2 +-
 .../fssystem_hierarchical_sha256_storage.cpp  | 25 +-----------
 ...ssystem_integrity_verification_storage.cpp |  4 --
 .../fssystem_nca_file_system_driver.cpp       | 40 +++++++++++--------
 5 files changed, 28 insertions(+), 54 deletions(-)

diff --git a/src/core/file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.cpp b/src/core/file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.cpp
index b2e031d5f2..4a75b53083 100644
--- a/src/core/file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.cpp
+++ b/src/core/file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.cpp
@@ -17,8 +17,6 @@ Result HierarchicalIntegrityVerificationStorage::Initialize(
     const HierarchicalIntegrityVerificationInformation& info,
     HierarchicalStorageInformation storage, int max_data_cache_entries, int max_hash_cache_entries,
     s8 buffer_level) {
-    using AlignedStorage = AlignmentMatchingStoragePooledBuffer<1>;
-
     // Validate preconditions.
     ASSERT(IntegrityMinLayerCount <= info.max_layers && info.max_layers <= IntegrityMaxLayerCount);
 
@@ -38,8 +36,7 @@ Result HierarchicalIntegrityVerificationStorage::Initialize(
     };
 
     // Initialize the top level buffer storage.
-    m_buffer_storages[0] = std::make_shared<AlignedStorage>(
-        m_verify_storages[0], static_cast<s64>(1) << info.info[0].block_order);
+    m_buffer_storages[0] = m_verify_storages[0];
     R_UNLESS(m_buffer_storages[0] != nullptr, ResultAllocationMemoryFailedAllocateShared);
 
     // Prepare to initialize the level storages.
@@ -65,8 +62,7 @@ Result HierarchicalIntegrityVerificationStorage::Initialize(
             static_cast<s64>(1) << info.info[level].block_order, false);
 
         // Initialize the buffer storage.
-        m_buffer_storages[level + 1] = std::make_shared<AlignedStorage>(
-            m_verify_storages[level + 1], static_cast<s64>(1) << info.info[level + 1].block_order);
+        m_buffer_storages[level + 1] = m_verify_storages[level + 1];
         R_UNLESS(m_buffer_storages[level + 1] != nullptr,
                  ResultAllocationMemoryFailedAllocateShared);
     }
@@ -82,8 +78,7 @@ Result HierarchicalIntegrityVerificationStorage::Initialize(
             static_cast<s64>(1) << info.info[level].block_order, true);
 
         // Initialize the buffer storage.
-        m_buffer_storages[level + 1] = std::make_shared<AlignedStorage>(
-            m_verify_storages[level + 1], static_cast<s64>(1) << info.info[level + 1].block_order);
+        m_buffer_storages[level + 1] = m_verify_storages[level + 1];
         R_UNLESS(m_buffer_storages[level + 1] != nullptr,
                  ResultAllocationMemoryFailedAllocateShared);
     }
diff --git a/src/core/file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.h b/src/core/file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.h
index 5e0a1d143d..3d216e4ae3 100644
--- a/src/core/file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.h
+++ b/src/core/file_sys/fssystem/fssystem_hierarchical_integrity_verification_storage.h
@@ -123,7 +123,7 @@ private:
 
 private:
     std::shared_ptr<IntegrityVerificationStorage> m_verify_storages[MaxLayers - 1];
-    std::shared_ptr<AlignmentMatchingStoragePooledBuffer<1>> m_buffer_storages[MaxLayers - 1];
+    VirtualFile m_buffer_storages[MaxLayers - 1];
     s64 m_data_size;
     s32 m_max_layers;
 
diff --git a/src/core/file_sys/fssystem/fssystem_hierarchical_sha256_storage.cpp b/src/core/file_sys/fssystem/fssystem_hierarchical_sha256_storage.cpp
index 357fa7741a..caea0b8f8b 100644
--- a/src/core/file_sys/fssystem/fssystem_hierarchical_sha256_storage.cpp
+++ b/src/core/file_sys/fssystem/fssystem_hierarchical_sha256_storage.cpp
@@ -73,31 +73,8 @@ size_t HierarchicalSha256Storage::Read(u8* buffer, size_t size, size_t offset) c
     // Validate that we have a buffer to read into.
     ASSERT(buffer != nullptr);
 
-    // Validate preconditions.
-    ASSERT(Common::IsAligned(offset, m_hash_target_block_size));
-    ASSERT(Common::IsAligned(size, m_hash_target_block_size));
-
     // Read the data.
-    const size_t reduced_size = static_cast<size_t>(
-        std::min<s64>(m_base_storage_size,
-                      Common::AlignUp(offset + size, m_hash_target_block_size)) -
-        offset);
-    m_base_storage->Read(buffer, reduced_size, offset);
-
-    // Setup tracking variables.
-    auto cur_offset = offset;
-    auto remaining_size = reduced_size;
-    while (remaining_size > 0) {
-        const auto cur_size =
-            static_cast<size_t>(std::min<s64>(m_hash_target_block_size, remaining_size));
-        ASSERT(static_cast<size_t>(cur_offset >> m_log_size_ratio) < m_hash_buffer_size);
-
-        // Advance.
-        cur_offset += cur_size;
-        remaining_size -= cur_size;
-    }
-
-    return size;
+    return m_base_storage->Read(buffer, size, offset);
 }
 
 } // namespace FileSys
diff --git a/src/core/file_sys/fssystem/fssystem_integrity_verification_storage.cpp b/src/core/file_sys/fssystem/fssystem_integrity_verification_storage.cpp
index ef36b755ea..0dba0c8d9a 100644
--- a/src/core/file_sys/fssystem/fssystem_integrity_verification_storage.cpp
+++ b/src/core/file_sys/fssystem/fssystem_integrity_verification_storage.cpp
@@ -48,10 +48,6 @@ void IntegrityVerificationStorage::Finalize() {
 }
 
 size_t IntegrityVerificationStorage::Read(u8* buffer, size_t size, size_t offset) const {
-    // Validate preconditions.
-    ASSERT(Common::IsAligned(offset, static_cast<size_t>(m_verification_block_size)));
-    ASSERT(Common::IsAligned(size, static_cast<size_t>(m_verification_block_size)));
-
     // Succeed if zero size.
     if (size == 0) {
         return size;
diff --git a/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp b/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp
index b1b5fb156c..450135ae00 100644
--- a/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp
+++ b/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp
@@ -508,12 +508,15 @@ Result NcaFileSystemDriver::CreateSparseStorageMetaStorage(VirtualFile* out,
                                     offset + meta_offset, sparse_info.MakeAesCtrUpperIv(upper_iv),
                                     AlignmentStorageRequirement::None));
 
-    // Create meta storage.
-    auto meta_storage = std::make_shared<OffsetVfsFile>(decrypted_storage, meta_size, 0);
-    R_UNLESS(meta_storage != nullptr, ResultAllocationMemoryFailedAllocateShared);
+    // Create buffered storage.
+    std::vector<u8> meta_data(meta_size);
+    decrypted_storage->Read(meta_data.data(), meta_size, 0);
+
+    auto buffered_storage = std::make_shared<VectorVfsFile>(std::move(meta_data));
+    R_UNLESS(buffered_storage != nullptr, ResultAllocationMemoryFailedAllocateShared);
 
     // Set the output.
-    *out = std::move(meta_storage);
+    *out = std::move(buffered_storage);
     R_SUCCEED();
 }
 
@@ -817,13 +820,15 @@ Result NcaFileSystemDriver::CreateAesCtrExStorageMetaStorage(
     auto meta_storage = std::make_shared<OffsetVfsFile>(decrypted_storage, meta_size, 0);
     R_UNLESS(meta_storage != nullptr, ResultAllocationMemoryFailedAllocateShared);
 
-    // Create an alignment-matching storage.
-    using AlignedStorage = AlignmentMatchingStorage<NcaHeader::CtrBlockSize, 1>;
-    auto aligned_storage = std::make_shared<AlignedStorage>(std::move(meta_storage));
-    R_UNLESS(aligned_storage != nullptr, ResultAllocationMemoryFailedAllocateShared);
+    // Create buffered storage.
+    std::vector<u8> meta_data(meta_size);
+    meta_storage->Read(meta_data.data(), meta_size, 0);
+
+    auto buffered_storage = std::make_shared<VectorVfsFile>(std::move(meta_data));
+    R_UNLESS(buffered_storage != nullptr, ResultAllocationMemoryFailedAllocateShared);
 
     // Set the output.
-    *out = std::move(aligned_storage);
+    *out = std::move(buffered_storage);
     R_SUCCEED();
 }
 
@@ -937,8 +942,15 @@ Result NcaFileSystemDriver::CreateIndirectStorageMetaStorage(VirtualFile* out,
                                                         patch_info.indirect_offset);
     R_UNLESS(meta_storage != nullptr, ResultAllocationMemoryFailedAllocateShared);
 
+    // Create buffered storage.
+    std::vector<u8> meta_data(patch_info.indirect_size);
+    meta_storage->Read(meta_data.data(), patch_info.indirect_size, 0);
+
+    auto buffered_storage = std::make_shared<VectorVfsFile>(std::move(meta_data));
+    R_UNLESS(buffered_storage != nullptr, ResultAllocationMemoryFailedAllocateShared);
+
     // Set the output.
-    *out = std::move(meta_storage);
+    *out = std::move(buffered_storage);
     R_SUCCEED();
 }
 
@@ -1090,7 +1102,6 @@ Result NcaFileSystemDriver::CreateSha256Storage(
 
     // Define storage types.
     using VerificationStorage = HierarchicalSha256Storage;
-    using AlignedStorage = AlignmentMatchingStoragePooledBuffer<1>;
 
     // Validate the hash data.
     R_UNLESS(Common::IsPowerOfTwo(hash_data.hash_block_size),
@@ -1141,13 +1152,8 @@ Result NcaFileSystemDriver::CreateSha256Storage(
                                            hash_data.hash_block_size,
                                            buffer_hold_storage->GetBuffer(), hash_buffer_size));
 
-    // Make the aligned storage.
-    auto aligned_storage = std::make_shared<AlignedStorage>(std::move(verification_storage),
-                                                            hash_data.hash_block_size);
-    R_UNLESS(aligned_storage != nullptr, ResultAllocationMemoryFailedAllocateShared);
-
     // Set the output.
-    *out = std::move(aligned_storage);
+    *out = std::move(verification_storage);
     R_SUCCEED();
 }