From 975deb7528cd98460528553f6a9162bfbcd6cab1 Mon Sep 17 00:00:00 2001
From: FearlessTobi <thm.frey@gmail.com>
Date: Fri, 19 Jan 2024 00:17:28 +0100
Subject: [PATCH] Address review comments and fix compilation problems

---
 .../app/src/main/jni/game_metadata.cpp        |  12 +-
 src/android/app/src/main/jni/native.cpp       |  15 +-
 src/common/overflow.h                         |   1 +
 src/core/file_sys/fs_directory.h              |   2 +-
 src/core/file_sys/fs_file.h                   |  14 +-
 src/core/file_sys/fs_filesystem.h             |   6 +-
 src/core/file_sys/fs_memory_management.h      |  20 +-
 src/core/file_sys/fs_operate_range.h          |   4 +-
 src/core/file_sys/fs_path.h                   | 150 +++++------
 src/core/file_sys/fs_path_utility.h           | 249 +++++++++---------
 src/core/file_sys/fs_string_util.h            |  29 +-
 src/core/hle/service/filesystem/filesystem.h  |   1 +
 src/core/hle/service/glue/time/manager.cpp    |   2 +-
 src/core/hle/service/glue/time/manager.h      |   2 +-
 .../service/glue/time/time_zone_binary.cpp    |   2 +-
 src/frontend_common/content_manager.h         |   9 +-
 16 files changed, 249 insertions(+), 269 deletions(-)

diff --git a/src/android/app/src/main/jni/game_metadata.cpp b/src/android/app/src/main/jni/game_metadata.cpp
index 78f604c704..8f0da1413b 100644
--- a/src/android/app/src/main/jni/game_metadata.cpp
+++ b/src/android/app/src/main/jni/game_metadata.cpp
@@ -1,12 +1,12 @@
 // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include <core/core.h>
-#include <core/file_sys/mode.h>
-#include <core/file_sys/patch_manager.h>
-#include <core/loader/nro.h>
-#include <jni.h>
+#include "core/core.h"
+#include "core/file_sys/fs_filesystem.h"
+#include "core/file_sys/patch_manager.h"
 #include "core/loader/loader.h"
+#include "core/loader/nro.h"
+#include "jni.h"
 #include "jni/android_common/android_common.h"
 #include "native.h"
 
@@ -79,7 +79,7 @@ extern "C" {
 jboolean Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIsValid(JNIEnv* env, jobject obj,
                                                                jstring jpath) {
     const auto file = EmulationSession::GetInstance().System().GetFilesystem()->OpenFile(
-        GetJString(env, jpath), FileSys::Mode::Read);
+        GetJString(env, jpath), FileSys::OpenMode::Read);
     if (!file) {
         return false;
     }
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp
index 247f2c2b34..3fd9a500c1 100644
--- a/src/android/app/src/main/jni/native.cpp
+++ b/src/android/app/src/main/jni/native.cpp
@@ -35,9 +35,10 @@
 #include "core/crypto/key_manager.h"
 #include "core/file_sys/card_image.h"
 #include "core/file_sys/content_archive.h"
+#include "core/file_sys/fs_filesystem.h"
 #include "core/file_sys/submission_package.h"
-#include "core/file_sys/vfs.h"
-#include "core/file_sys/vfs_real.h"
+#include "core/file_sys/vfs/vfs.h"
+#include "core/file_sys/vfs/vfs_real.h"
 #include "core/frontend/applets/cabinet.h"
 #include "core/frontend/applets/controller.h"
 #include "core/frontend/applets/error.h"
@@ -154,7 +155,7 @@ void EmulationSession::SurfaceChanged() {
 }
 
 void EmulationSession::ConfigureFilesystemProvider(const std::string& filepath) {
-    const auto file = m_system.GetFilesystem()->OpenFile(filepath, FileSys::Mode::Read);
+    const auto file = m_system.GetFilesystem()->OpenFile(filepath, FileSys::OpenMode::Read);
     if (!file) {
         return;
     }
@@ -475,8 +476,8 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_doesUpdateMatchProgram(JNIEnv* en
     u64 program_id = EmulationSession::GetProgramId(env, jprogramId);
     std::string updatePath = GetJString(env, jupdatePath);
     std::shared_ptr<FileSys::NSP> nsp = std::make_shared<FileSys::NSP>(
-        EmulationSession::GetInstance().System().GetFilesystem()->OpenFile(updatePath,
-                                                                           FileSys::Mode::Read));
+        EmulationSession::GetInstance().System().GetFilesystem()->OpenFile(
+            updatePath, FileSys::OpenMode::Read));
     for (const auto& item : nsp->GetNCAs()) {
         for (const auto& nca_details : item.second) {
             if (nca_details.second->GetName().ends_with(".cnmt.nca")) {
@@ -719,7 +720,7 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeEmptyUserDirectory(JNIEnv*
                                                                         jobject instance) {
     const auto nand_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir);
     auto vfs_nand_dir = EmulationSession::GetInstance().System().GetFilesystem()->OpenDirectory(
-        Common::FS::PathToUTF8String(nand_dir), FileSys::Mode::Read);
+        Common::FS::PathToUTF8String(nand_dir), FileSys::OpenMode::Read);
 
     const auto user_id = EmulationSession::GetInstance().System().GetProfileManager().GetUser(
         static_cast<std::size_t>(0));
@@ -889,7 +890,7 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getSavePath(JNIEnv* env, jobject j
 
     const auto nandDir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir);
     auto vfsNandDir = system.GetFilesystem()->OpenDirectory(Common::FS::PathToUTF8String(nandDir),
-                                                            FileSys::Mode::Read);
+                                                            FileSys::OpenMode::Read);
 
     const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath(
         {}, vfsNandDir, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData,
diff --git a/src/common/overflow.h b/src/common/overflow.h
index e765c0d89f..e184ead953 100644
--- a/src/common/overflow.h
+++ b/src/common/overflow.h
@@ -3,6 +3,7 @@
 
 #pragma once
 
+#include <algorithm>
 #include <type_traits>
 #include "bit_cast.h"
 
diff --git a/src/core/file_sys/fs_directory.h b/src/core/file_sys/fs_directory.h
index cba6155f86..25c9cb18a3 100644
--- a/src/core/file_sys/fs_directory.h
+++ b/src/core/file_sys/fs_directory.h
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #pragma once
diff --git a/src/core/file_sys/fs_file.h b/src/core/file_sys/fs_file.h
index 35f66b959c..4fb77e8dbf 100644
--- a/src/core/file_sys/fs_file.h
+++ b/src/core/file_sys/fs_file.h
@@ -1,12 +1,14 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #pragma once
 
+#include "common/common_types.h"
+
 namespace FileSys {
 
 struct ReadOption {
-    u32 _value;
+    u32 value;
 
     static const ReadOption None;
 };
@@ -18,7 +20,7 @@ enum ReadOptionFlag : u32 {
 inline constexpr const ReadOption ReadOption::None = {ReadOptionFlag_None};
 
 inline constexpr bool operator==(const ReadOption& lhs, const ReadOption& rhs) {
-    return lhs._value == rhs._value;
+    return lhs.value == rhs.value;
 }
 
 inline constexpr bool operator!=(const ReadOption& lhs, const ReadOption& rhs) {
@@ -33,10 +35,10 @@ enum WriteOptionFlag : u32 {
 };
 
 struct WriteOption {
-    u32 _value;
+    u32 value;
 
     constexpr inline bool HasFlushFlag() const {
-        return _value & WriteOptionFlag_Flush;
+        return value & WriteOptionFlag_Flush;
     }
 
     static const WriteOption None;
@@ -47,7 +49,7 @@ inline constexpr const WriteOption WriteOption::None = {WriteOptionFlag_None};
 inline constexpr const WriteOption WriteOption::Flush = {WriteOptionFlag_Flush};
 
 inline constexpr bool operator==(const WriteOption& lhs, const WriteOption& rhs) {
-    return lhs._value == rhs._value;
+    return lhs.value == rhs.value;
 }
 
 inline constexpr bool operator!=(const WriteOption& lhs, const WriteOption& rhs) {
diff --git a/src/core/file_sys/fs_filesystem.h b/src/core/file_sys/fs_filesystem.h
index 436d6c7310..7f237b7fac 100644
--- a/src/core/file_sys/fs_filesystem.h
+++ b/src/core/file_sys/fs_filesystem.h
@@ -3,6 +3,9 @@
 
 #pragma once
 
+#include "common/common_funcs.h"
+#include "common/common_types.h"
+
 namespace FileSys {
 
 enum class OpenMode : u32 {
@@ -20,9 +23,6 @@ enum class OpenDirectoryMode : u64 {
     File = (1 << 1),
 
     All = (Directory | File),
-
-    /* TODO: Separate enum, like N? */
-    _NotRequireFileSize = (1 << 31),
 };
 DECLARE_ENUM_FLAG_OPERATORS(OpenDirectoryMode)
 
diff --git a/src/core/file_sys/fs_memory_management.h b/src/core/file_sys/fs_memory_management.h
index 596143ba91..f03c6354b8 100644
--- a/src/core/file_sys/fs_memory_management.h
+++ b/src/core/file_sys/fs_memory_management.h
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #pragma once
@@ -8,39 +8,31 @@
 
 namespace FileSys {
 
-std::mutex g_mutex;
-
 constexpr size_t RequiredAlignment = alignof(u64);
 
 void* AllocateUnsafe(size_t size) {
-    /* Allocate. */
+    // Allocate
     void* const ptr = ::operator new(size, std::align_val_t{RequiredAlignment});
 
-    /* Check alignment. */
+    // Check alignment
     ASSERT(Common::IsAligned(reinterpret_cast<uintptr_t>(ptr), RequiredAlignment));
 
-    /* Return allocated pointer. */
+    // Return allocated pointer
     return ptr;
 }
 
 void DeallocateUnsafe(void* ptr, size_t size) {
-    /* Deallocate the pointer. */
+    // Deallocate the pointer
     ::operator delete(ptr, std::align_val_t{RequiredAlignment});
 }
 
 void* Allocate(size_t size) {
-    /* Lock the allocator. */
-    std::scoped_lock lk(g_mutex);
-
     return AllocateUnsafe(size);
 }
 
 void Deallocate(void* ptr, size_t size) {
-    /* If the pointer is non-null, deallocate it. */
+    // If the pointer is non-null, deallocate it
     if (ptr != nullptr) {
-        /* Lock the allocator. */
-        std::scoped_lock lk(g_mutex);
-
         DeallocateUnsafe(ptr, size);
     }
 }
diff --git a/src/core/file_sys/fs_operate_range.h b/src/core/file_sys/fs_operate_range.h
index 7509999071..04ea64cc01 100644
--- a/src/core/file_sys/fs_operate_range.h
+++ b/src/core/file_sys/fs_operate_range.h
@@ -1,8 +1,10 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #pragma once
 
+#include "common/common_types.h"
+
 namespace FileSys {
 
 enum class OperationId : s64 {
diff --git a/src/core/file_sys/fs_path.h b/src/core/file_sys/fs_path.h
index 9ea4526442..56ba08a6a5 100644
--- a/src/core/file_sys/fs_path.h
+++ b/src/core/file_sys/fs_path.h
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #pragma once
@@ -34,8 +34,7 @@ public:
         size_t m_length_and_is_normalized;
 
     public:
-        constexpr WriteBuffer() : m_buffer(nullptr), m_length_and_is_normalized(0) { /* ... */
-        }
+        constexpr WriteBuffer() : m_buffer(nullptr), m_length_and_is_normalized(0) {}
 
         constexpr ~WriteBuffer() {
             if (m_buffer != nullptr) {
@@ -113,35 +112,32 @@ private:
     WriteBuffer m_write_buffer;
 
 public:
-    constexpr Path() : m_str(EmptyPath), m_write_buffer() {
-        /* ... */
-    }
+    constexpr Path() : m_str(EmptyPath), m_write_buffer() {}
 
     constexpr Path(const char* s) : m_str(s), m_write_buffer() {
         m_write_buffer.SetNormalized();
     }
 
-    constexpr ~Path() { /* ... */
-    }
+    constexpr ~Path() = default;
 
     constexpr Result SetShallowBuffer(const char* buffer) {
-        /* Check pre-conditions. */
+        // Check pre-conditions
         ASSERT(m_write_buffer.GetLength() == 0);
 
-        /* Check the buffer is valid. */
+        // Check the buffer is valid
         R_UNLESS(buffer != nullptr, ResultNullptrArgument);
 
-        /* Set buffer. */
+        // Set buffer
         this->SetReadOnlyBuffer(buffer);
 
-        /* Note that we're normalized. */
+        // Note that we're normalized
         this->SetNormalized();
 
         R_SUCCEED();
     }
 
     constexpr const char* GetString() const {
-        /* Check pre-conditions. */
+        // Check pre-conditions
         ASSERT(this->IsNormalized());
 
         return m_str;
@@ -164,69 +160,69 @@ public:
     }
 
     Result Initialize(const Path& rhs) {
-        /* Check the other path is normalized. */
+        // Check the other path is normalized
         const bool normalized = rhs.IsNormalized();
         R_UNLESS(normalized, ResultNotNormalized);
 
-        /* Allocate buffer for our path. */
+        // Allocate buffer for our path
         const auto len = rhs.GetLength();
         R_TRY(this->Preallocate(len + 1));
 
-        /* Copy the path. */
+        // Copy the path
         const size_t copied = Strlcpy<char>(m_write_buffer.Get(), rhs.GetString(), len + 1);
         R_UNLESS(copied == len, ResultUnexpectedInPathA);
 
-        /* Set normalized. */
+        // Set normalized
         this->SetNormalized();
         R_SUCCEED();
     }
 
     Result Initialize(const char* path, size_t len) {
-        /* Check the path is valid. */
+        // Check the path is valid
         R_UNLESS(path != nullptr, ResultNullptrArgument);
 
-        /* Initialize. */
+        // Initialize
         R_TRY(this->InitializeImpl(path, len));
 
-        /* Set not normalized. */
+        // Set not normalized
         this->SetNotNormalized();
 
         R_SUCCEED();
     }
 
     Result Initialize(const char* path) {
-        /* Check the path is valid. */
+        // Check the path is valid
         R_UNLESS(path != nullptr, ResultNullptrArgument);
 
         R_RETURN(this->Initialize(path, std::strlen(path)));
     }
 
     Result InitializeWithReplaceBackslash(const char* path) {
-        /* Check the path is valid. */
+        // Check the path is valid
         R_UNLESS(path != nullptr, ResultNullptrArgument);
 
-        /* Initialize. */
+        // Initialize
         R_TRY(this->InitializeImpl(path, std::strlen(path)));
 
-        /* Replace slashes as desired. */
+        // Replace slashes as desired
         if (const auto write_buffer_length = m_write_buffer.GetLength(); write_buffer_length > 1) {
             Replace(m_write_buffer.Get(), write_buffer_length - 1, '\\', '/');
         }
 
-        /* Set not normalized. */
+        // Set not normalized
         this->SetNotNormalized();
 
         R_SUCCEED();
     }
 
     Result InitializeWithReplaceForwardSlashes(const char* path) {
-        /* Check the path is valid. */
+        // Check the path is valid
         R_UNLESS(path != nullptr, ResultNullptrArgument);
 
-        /* Initialize. */
+        // Initialize
         R_TRY(this->InitializeImpl(path, std::strlen(path)));
 
-        /* Replace slashes as desired. */
+        // Replace slashes as desired
         if (m_write_buffer.GetLength() > 1) {
             if (auto* p = m_write_buffer.Get(); p[0] == '/' && p[1] == '/') {
                 p[0] = '\\';
@@ -234,23 +230,23 @@ public:
             }
         }
 
-        /* Set not normalized. */
+        // Set not normalized
         this->SetNotNormalized();
 
         R_SUCCEED();
     }
 
     Result InitializeWithNormalization(const char* path, size_t size) {
-        /* Check the path is valid. */
+        // Check the path is valid
         R_UNLESS(path != nullptr, ResultNullptrArgument);
 
-        /* Initialize. */
+        // Initialize
         R_TRY(this->InitializeImpl(path, size));
 
-        /* Set not normalized. */
+        // Set not normalized
         this->SetNotNormalized();
 
-        /* Perform normalization. */
+        // Perform normalization
         PathFlags path_flags;
         if (IsPathRelative(m_str)) {
             path_flags.AllowRelativePath();
@@ -269,7 +265,7 @@ public:
             R_SUCCEED();
         }
 
-        /* Normalize. */
+        // Normalize
         R_TRY(this->Normalize(path_flags));
 
         this->SetNormalized();
@@ -277,30 +273,30 @@ public:
     }
 
     Result InitializeWithNormalization(const char* path) {
-        /* Check the path is valid. */
+        // Check the path is valid
         R_UNLESS(path != nullptr, ResultNullptrArgument);
 
         R_RETURN(this->InitializeWithNormalization(path, std::strlen(path)));
     }
 
     Result InitializeAsEmpty() {
-        /* Clear our buffer. */
+        // Clear our buffer
         this->ClearBuffer();
 
-        /* Set normalized. */
+        // Set normalized
         this->SetNormalized();
 
         R_SUCCEED();
     }
 
     Result AppendChild(const char* child) {
-        /* Check the path is valid. */
+        // Check the path is valid
         R_UNLESS(child != nullptr, ResultNullptrArgument);
 
-        /* Basic checks. If we hvea a path and the child is empty, we have nothing to do. */
+        // Basic checks. If we have a path and the child is empty, we have nothing to do
         const char* c = child;
         if (m_str[0]) {
-            /* Skip an early separator. */
+            // Skip an early separator
             if (*c == '/') {
                 ++c;
             }
@@ -308,40 +304,40 @@ public:
             R_SUCCEED_IF(*c == '\x00');
         }
 
-        /* If we don't have a string, we can just initialize. */
+        // If we don't have a string, we can just initialize
         auto cur_len = std::strlen(m_str);
         if (cur_len == 0) {
             R_RETURN(this->Initialize(child));
         }
 
-        /* Remove a trailing separator. */
+        // Remove a trailing separator
         if (m_str[cur_len - 1] == '/' || m_str[cur_len - 1] == '\\') {
             --cur_len;
         }
 
-        /* Get the child path's length. */
+        // Get the child path's length
         auto child_len = std::strlen(c);
 
-        /* Reset our write buffer. */
+        // Reset our write buffer
         WriteBuffer old_write_buffer;
         if (m_write_buffer.Get() != nullptr) {
             old_write_buffer = std::move(m_write_buffer);
             this->ClearBuffer();
         }
 
-        /* Pre-allocate the new buffer. */
+        // Pre-allocate the new buffer
         R_TRY(this->Preallocate(cur_len + 1 + child_len + 1));
 
-        /* Get our write buffer. */
+        // Get our write buffer
         auto* dst = m_write_buffer.Get();
         if (old_write_buffer.Get() != nullptr && cur_len > 0) {
             Strlcpy<char>(dst, old_write_buffer.Get(), cur_len + 1);
         }
 
-        /* Add separator. */
+        // Add separator
         dst[cur_len] = '/';
 
-        /* Copy the child path. */
+        // Copy the child path
         const size_t copied = Strlcpy<char>(dst + cur_len + 1, c, child_len + 1);
         R_UNLESS(copied == child_len, ResultUnexpectedInPathA);
 
@@ -353,21 +349,21 @@ public:
     }
 
     Result Combine(const Path& parent, const Path& child) {
-        /* Get the lengths. */
+        // Get the lengths
         const auto p_len = parent.GetLength();
         const auto c_len = child.GetLength();
 
-        /* Allocate our buffer. */
+        // Allocate our buffer
         R_TRY(this->Preallocate(p_len + c_len + 1));
 
-        /* Initialize as parent. */
+        // Initialize as parent
         R_TRY(this->Initialize(parent));
 
-        /* If we're empty, we can just initialize as child. */
+        // If we're empty, we can just initialize as child
         if (this->IsEmpty()) {
             R_TRY(this->Initialize(child));
         } else {
-            /* Otherwise, we should append the child. */
+            // Otherwise, we should append the child
             R_TRY(this->AppendChild(child));
         }
 
@@ -375,7 +371,7 @@ public:
     }
 
     Result RemoveChild() {
-        /* If we don't have a write-buffer, ensure that we have one. */
+        // If we don't have a write-buffer, ensure that we have one
         if (m_write_buffer.Get() == nullptr) {
             if (const auto len = std::strlen(m_str); len > 0) {
                 R_TRY(this->Preallocate(len));
@@ -383,17 +379,17 @@ public:
             }
         }
 
-        /* Check that it's possible for us to remove a child. */
+        // Check that it's possible for us to remove a child
         auto* p = m_write_buffer.Get();
         s32 len = std::strlen(p);
         R_UNLESS(len != 1 || (p[0] != '/' && p[0] != '.'), ResultNotImplemented);
 
-        /* Handle a trailing separator. */
+        // Handle a trailing separator
         if (len > 0 && (p[len - 1] == '\\' || p[len - 1] == '/')) {
             --len;
         }
 
-        /* Remove the child path segment. */
+        // Remove the child path segment
         while ((--len) >= 0 && p[len]) {
             if (p[len] == '/' || p[len] == '\\') {
                 if (len > 0) {
@@ -406,25 +402,25 @@ public:
             }
         }
 
-        /* Check that length remains > 0. */
+        // Check that length remains > 0
         R_UNLESS(len > 0, ResultNotImplemented);
 
         R_SUCCEED();
     }
 
     Result Normalize(const PathFlags& flags) {
-        /* If we're already normalized, nothing to do. */
+        // If we're already normalized, nothing to do
         R_SUCCEED_IF(this->IsNormalized());
 
-        /* Check if we're normalized. */
+        // Check if we're normalized
         bool normalized;
         size_t dummy;
         R_TRY(PathFormatter::IsNormalized(std::addressof(normalized), std::addressof(dummy), m_str,
                                           flags));
 
-        /* If we're not normalized, normalize. */
+        // If we're not normalized, normalize
         if (!normalized) {
-            /* Determine necessary buffer length. */
+            // Determine necessary buffer length
             auto len = m_write_buffer.GetLength();
             if (flags.IsRelativePathAllowed() && IsPathRelative(m_str)) {
                 len += 2;
@@ -433,20 +429,20 @@ public:
                 len += 1;
             }
 
-            /* Allocate a new buffer. */
+            // Allocate a new buffer
             const size_t size = Common::AlignUp(len, WriteBufferAlignmentLength);
             auto buf = WriteBuffer::Make(size);
             R_UNLESS(buf.Get() != nullptr, ResultAllocationMemoryFailedMakeUnique);
 
-            /* Normalize into it. */
+            // Normalize into it
             R_TRY(PathFormatter::Normalize(buf.Get(), size, m_write_buffer.Get(),
                                            m_write_buffer.GetLength(), flags));
 
-            /* Set the normalized buffer as our buffer. */
+            // Set the normalized buffer as our buffer
             this->SetModifiableBuffer(std::move(buf));
         }
 
-        /* Set normalized. */
+        // Set normalized
         this->SetNormalized();
         R_SUCCEED();
     }
@@ -458,19 +454,19 @@ private:
     }
 
     void SetModifiableBuffer(WriteBuffer&& buffer) {
-        /* Check pre-conditions. */
+        // Check pre-conditions
         ASSERT(buffer.Get() != nullptr);
         ASSERT(buffer.GetLength() > 0);
         ASSERT(Common::IsAligned(buffer.GetLength(), WriteBufferAlignmentLength));
 
-        /* Get whether we're normalized. */
+        // Get whether we're normalized
         if (m_write_buffer.IsNormalized()) {
             buffer.SetNormalized();
         } else {
             buffer.SetNotNormalized();
         }
 
-        /* Set write buffer. */
+        // Set write buffer
         m_write_buffer = std::move(buffer);
         m_str = m_write_buffer.Get();
     }
@@ -481,14 +477,14 @@ private:
     }
 
     Result Preallocate(size_t length) {
-        /* Allocate additional space, if needed. */
+        // Allocate additional space, if needed
         if (length > m_write_buffer.GetLength()) {
-            /* Allocate buffer. */
+            // Allocate buffer
             const size_t size = Common::AlignUp(length, WriteBufferAlignmentLength);
             auto buf = WriteBuffer::Make(size);
             R_UNLESS(buf.Get() != nullptr, ResultAllocationMemoryFailedMakeUnique);
 
-            /* Set write buffer. */
+            // Set write buffer
             this->SetModifiableBuffer(std::move(buf));
         }
 
@@ -497,14 +493,14 @@ private:
 
     Result InitializeImpl(const char* path, size_t size) {
         if (size > 0 && path[0]) {
-            /* Pre allocate a buffer for the path. */
+            // Pre allocate a buffer for the path
             R_TRY(this->Preallocate(size + 1));
 
-            /* Copy the path. */
+            // Copy the path
             const size_t copied = Strlcpy<char>(m_write_buffer.Get(), path, size + 1);
             R_UNLESS(copied >= size, ResultUnexpectedInPathA);
         } else {
-            /* We can just clear the buffer. */
+            // We can just clear the buffer
             this->ClearBuffer();
         }
 
@@ -548,14 +544,14 @@ public:
 };
 
 inline Result SetUpFixedPath(FileSys::Path* out, const char* s) {
-    /* Verify the path is normalized. */
+    // Verify the path is normalized
     bool normalized;
     size_t dummy;
     R_TRY(PathNormalizer::IsNormalized(std::addressof(normalized), std::addressof(dummy), s));
 
     R_UNLESS(normalized, ResultInvalidPathFormat);
 
-    /* Set the fixed path. */
+    // Set the fixed path
     R_RETURN(out->SetShallowBuffer(s));
 }
 
diff --git a/src/core/file_sys/fs_path_utility.h b/src/core/file_sys/fs_path_utility.h
index 2764457073..e9011d0654 100644
--- a/src/core/file_sys/fs_path_utility.h
+++ b/src/core/file_sys/fs_path_utility.h
@@ -1,9 +1,10 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #pragma once
 
 #include "common/assert.h"
+#include "common/common_funcs.h"
 #include "common/common_types.h"
 #include "common/scope_exit.h"
 #include "core/file_sys/fs_directory.h"
@@ -14,7 +15,6 @@
 namespace FileSys {
 
 constexpr inline size_t MountNameLengthMax = 15;
-using Result = ::Result;
 
 namespace StringTraits {
 
@@ -57,15 +57,15 @@ constexpr bool IsInvalidCharacterImpl(char c) {
 } // namespace impl
 
 constexpr bool IsInvalidCharacter(char c) {
-    return impl::IsInvalidCharacterImpl<InvalidCharacters, size(InvalidCharacters)>(c);
+    return impl::IsInvalidCharacterImpl<InvalidCharacters, Common::Size(InvalidCharacters)>(c);
 }
 constexpr bool IsInvalidCharacterForHostName(char c) {
     return impl::IsInvalidCharacterImpl<InvalidCharactersForHostName,
-                                        size(InvalidCharactersForHostName)>(c);
+                                        Common::Size(InvalidCharactersForHostName)>(c);
 }
 constexpr bool IsInvalidCharacterForMountName(char c) {
     return impl::IsInvalidCharacterImpl<InvalidCharactersForMountName,
-                                        size(InvalidCharactersForMountName)>(c);
+                                        Common::Size(InvalidCharactersForMountName)>(c);
 }
 
 } // namespace StringTraits
@@ -177,14 +177,14 @@ constexpr inline bool IsPathStartWithCurrentDirectory(const char* path) {
 }
 
 constexpr inline bool IsSubPath(const char* lhs, const char* rhs) {
-    /* Check pre-conditions. */
+    // Check pre-conditions
     ASSERT(lhs != nullptr);
     ASSERT(rhs != nullptr);
 
-    /* Import StringTraits names for current scope. */
+    // Import StringTraits names for current scope
     using namespace StringTraits;
 
-    /* Special case certain paths. */
+    // Special case certain paths
     if (IsUncPath(lhs) && !IsUncPath(rhs)) {
         return false;
     }
@@ -201,7 +201,7 @@ constexpr inline bool IsSubPath(const char* lhs, const char* rhs) {
         return true;
     }
 
-    /* Check subpath. */
+    // Check subpath
     for (size_t i = 0; /* ... */; ++i) {
         if (lhs[i] == NullTerminator) {
             return rhs[i] == DirectorySeparator;
@@ -213,7 +213,7 @@ constexpr inline bool IsSubPath(const char* lhs, const char* rhs) {
     }
 }
 
-/* Path utilities. */
+// Path utilities
 constexpr inline void Replace(char* dst, size_t dst_size, char old_char, char new_char) {
     ASSERT(dst != nullptr);
     for (char* cur = dst; cur < dst + dst_size && *cur; ++cur) {
@@ -224,10 +224,10 @@ constexpr inline void Replace(char* dst, size_t dst_size, char old_char, char ne
 }
 
 constexpr inline Result CheckUtf8(const char* s) {
-    /* Check pre-conditions. */
+    // Check pre-conditions
     ASSERT(s != nullptr);
 
-    /* Iterate, checking for utf8-validity. */
+    // Iterate, checking for utf8-validity
     while (*s) {
         char utf8_buf[4] = {};
 
@@ -242,7 +242,7 @@ constexpr inline Result CheckUtf8(const char* s) {
     R_SUCCEED();
 }
 
-/* Path formatting. */
+// Path formatting
 class PathNormalizer {
 private:
     enum class PathState {
@@ -256,10 +256,10 @@ private:
 
 private:
     static constexpr void ReplaceParentDirectoryPath(char* dst, const char* src) {
-        /* Use StringTraits names for remainder of scope. */
+        // Use StringTraits names for remainder of scope
         using namespace StringTraits;
 
-        /* Start with a dir-separator. */
+        // Start with a dir-separator
         dst[0] = DirectorySeparator;
 
         auto i = 1;
@@ -292,14 +292,14 @@ private:
 
 public:
     static constexpr bool IsParentDirectoryPathReplacementNeeded(const char* path) {
-        /* Use StringTraits names for remainder of scope. */
+        // Use StringTraits names for remainder of scope
         using namespace StringTraits;
 
         if (path[0] != DirectorySeparator && path[0] != AlternateDirectorySeparator) {
             return false;
         }
 
-        /* Check to find a parent reference using alternate separators. */
+        // Check to find a parent reference using alternate separators
         if (path[0] != NullTerminator && path[1] != NullTerminator && path[2] != NullTerminator) {
             size_t i;
             for (i = 0; path[i + 3] != NullTerminator; ++path) {
@@ -333,24 +333,24 @@ public:
 
     static constexpr Result IsNormalized(bool* out, size_t* out_len, const char* path,
                                          bool allow_all_characters = false) {
-        /* Use StringTraits names for remainder of scope. */
+        // Use StringTraits names for remainder of scope
         using namespace StringTraits;
 
-        /* Parse the path. */
+        // Parse the path
         auto state = PathState::Start;
         size_t len = 0;
         while (path[len] != NullTerminator) {
-            /* Get the current character. */
+            // Get the current character
             const char c = path[len++];
 
-            /* Check the current character is valid. */
+            // Check the current character is valid
             if (!allow_all_characters && state != PathState::Start) {
                 R_UNLESS(!IsInvalidCharacter(c), ResultInvalidCharacter);
             }
 
-            /* Process depending on current state. */
+            // Process depending on current state
             switch (state) {
-                /* Import the PathState enums for convenience. */
+                // Import the PathState enums for convenience
                 using enum PathState;
 
             case Start:
@@ -401,9 +401,9 @@ public:
             }
         }
 
-        /* Check the final state. */
+        // Check the final state
         switch (state) {
-            /* Import the PathState enums for convenience. */
+            // Import the PathState enums for convenience
             using enum PathState;
         case Start:
             R_THROW(ResultInvalidPathFormat);
@@ -421,7 +421,7 @@ public:
             break;
         }
 
-        /* Set the output length. */
+        // Set the output length
         *out_len = len;
         R_SUCCEED();
     }
@@ -429,21 +429,21 @@ public:
     static Result Normalize(char* dst, size_t* out_len, const char* path, size_t max_out_size,
                             bool is_windows_path, bool is_drive_relative_path,
                             bool allow_all_characters = false) {
-        /* Use StringTraits names for remainder of scope. */
+        // Use StringTraits names for remainder of scope
         using namespace StringTraits;
 
-        /* Prepare to iterate. */
+        // Prepare to iterate
         const char* cur_path = path;
         size_t total_len = 0;
 
-        /* If path begins with a separator, check that we're not drive relative. */
+        // If path begins with a separator, check that we're not drive relative
         if (cur_path[0] != DirectorySeparator) {
             R_UNLESS(is_drive_relative_path, ResultInvalidPathFormat);
 
             dst[total_len++] = DirectorySeparator;
         }
 
-        /* We're going to need to do path replacement, potentially. */
+        // We're going to need to do path replacement, potentially
         char* replacement_path = nullptr;
         size_t replacement_path_size = 0;
 
@@ -457,7 +457,7 @@ public:
             }
         });
 
-        /* Perform path replacement, if necessary. */
+        // Perform path replacement, if necessary
         if (IsParentDirectoryPathReplacementNeeded(cur_path)) {
             if (std::is_constant_evaluated()) {
                 replacement_path_size = EntryNameLengthMax + 1;
@@ -472,25 +472,24 @@ public:
             cur_path = replacement_path;
         }
 
-        /* Iterate, normalizing path components. */
+        // Iterate, normalizing path components
         bool skip_next_sep = false;
         size_t i = 0;
 
         while (cur_path[i] != NullTerminator) {
-            /* Process a directory separator, if we run into one. */
+            // Process a directory separator, if we run into one
             if (cur_path[i] == DirectorySeparator) {
-                /* Swallow separators. */
+                // Swallow separators
                 do {
                     ++i;
                 } while (cur_path[i] == DirectorySeparator);
 
-                /* Check if we hit end of string. */
+                // Check if we hit end of string
                 if (cur_path[i] == NullTerminator) {
                     break;
                 }
 
-                /* If we aren't skipping the separator, write it, checking that we remain in bounds.
-                 */
+                // If we aren't skipping the separator, write it, checking that we remain in bounds.
                 if (!skip_next_sep) {
                     if (total_len + 1 == max_out_size) {
                         dst[total_len] = NullTerminator;
@@ -501,15 +500,15 @@ public:
                     dst[total_len++] = DirectorySeparator;
                 }
 
-                /* Don't skip the next separator. */
+                // Don't skip the next separator
                 skip_next_sep = false;
             }
 
-            /* Get the length of the current directory component. */
+            // Get the length of the current directory component
             size_t dir_len = 0;
             while (cur_path[i + dir_len] != DirectorySeparator &&
                    cur_path[i + dir_len] != NullTerminator) {
-                /* Check for validity. */
+                // Check for validity
                 if (!allow_all_characters) {
                     R_UNLESS(!IsInvalidCharacter(cur_path[i + dir_len]), ResultInvalidCharacter);
                 }
@@ -517,19 +516,19 @@ public:
                 ++dir_len;
             }
 
-            /* Handle the current dir component. */
+            // Handle the current dir component
             if (IsCurrentDirectory(cur_path + i)) {
                 skip_next_sep = true;
             } else if (IsParentDirectory(cur_path + i)) {
-                /* We should have just written a separator. */
+                // We should have just written a separator
                 ASSERT(dst[total_len - 1] == DirectorySeparator);
 
-                /* We should have started with a separator, for non-windows paths. */
+                // We should have started with a separator, for non-windows paths
                 if (!is_windows_path) {
                     ASSERT(dst[0] == DirectorySeparator);
                 }
 
-                /* Remove the previous component. */
+                // Remove the previous component
                 if (total_len == 1) {
                     R_UNLESS(is_windows_path, ResultDirectoryUnobtainable);
 
@@ -544,15 +543,15 @@ public:
                     } while ((--total_len) != 0);
                 }
 
-                /* We should be pointing to a directory separator, for non-windows paths. */
+                // We should be pointing to a directory separator, for non-windows paths
                 if (!is_windows_path) {
                     ASSERT(dst[total_len] == DirectorySeparator);
                 }
 
-                /* We should remain in bounds. */
+                // We should remain in bounds
                 ASSERT(total_len < max_out_size);
             } else {
-                /* Copy, possibly truncating. */
+                // Copy, possibly truncating
                 if (total_len + dir_len + 1 > max_out_size) {
                     const size_t copy_len = max_out_size - (total_len + 1);
 
@@ -570,7 +569,7 @@ public:
                 }
             }
 
-            /* Advance past the current directory component. */
+            // Advance past the current directory component
             i += dir_len;
         }
 
@@ -583,22 +582,22 @@ public:
             dst[0] = DirectorySeparator;
         }
 
-        /* NOTE: Probable nintendo bug, as max_out_size must be at least total_len + 1 for the null
-         * terminator. */
+        // NOTE: Probable nintendo bug, as max_out_size must be at least total_len + 1 for the null
+        // terminator.
         R_UNLESS(max_out_size >= total_len - 1, ResultTooLongPath);
 
         dst[total_len] = NullTerminator;
 
-        /* Check that the result path is normalized. */
+        // Check that the result path is normalized
         bool is_normalized;
         size_t dummy;
         R_TRY(IsNormalized(std::addressof(is_normalized), std::addressof(dummy), dst,
                            allow_all_characters));
 
-        /* Assert that the result path is normalized. */
+        // Assert that the result path is normalized
         ASSERT(is_normalized);
 
-        /* Set the output length. */
+        // Set the output length
         *out_len = total_len;
         R_SUCCEED();
     }
@@ -607,7 +606,7 @@ public:
 class PathFormatter {
 private:
     static constexpr Result CheckSharedName(const char* name, size_t len) {
-        /* Use StringTraits names for remainder of scope. */
+        // Use StringTraits names for remainder of scope
         using namespace StringTraits;
 
         if (len == 1) {
@@ -624,7 +623,7 @@ private:
     }
 
     static constexpr Result CheckHostName(const char* name, size_t len) {
-        /* Use StringTraits names for remainder of scope. */
+        // Use StringTraits names for remainder of scope
         using namespace StringTraits;
 
         if (len == 2) {
@@ -640,10 +639,10 @@ private:
 
     static constexpr Result CheckInvalidBackslash(bool* out_contains_backslash, const char* path,
                                                   bool allow_backslash) {
-        /* Use StringTraits names for remainder of scope. */
+        // Use StringTraits names for remainder of scope
         using namespace StringTraits;
 
-        /* Default to no backslashes, so we can just write if we see one. */
+        // Default to no backslashes, so we can just write if we see one
         *out_contains_backslash = false;
 
         while (*path != NullTerminator) {
@@ -670,34 +669,34 @@ public:
 
     static constexpr Result ParseMountName(const char** out, size_t* out_len, char* out_mount_name,
                                            size_t out_mount_name_buffer_size, const char* path) {
-        /* Check pre-conditions. */
+        // Check pre-conditions
         ASSERT(path != nullptr);
         ASSERT(out_len != nullptr);
         ASSERT(out != nullptr);
         ASSERT((out_mount_name == nullptr) == (out_mount_name_buffer_size == 0));
 
-        /* Use StringTraits names for remainder of scope. */
+        // Use StringTraits names for remainder of scope
         using namespace StringTraits;
 
-        /* Determine max mount length. */
+        // Determine max mount length
         const auto max_mount_len =
             out_mount_name_buffer_size == 0
                 ? MountNameLengthMax + 1
                 : std::min(MountNameLengthMax + 1, out_mount_name_buffer_size);
 
-        /* Parse the path until we see a drive separator. */
+        // Parse the path until we see a drive separator
         size_t mount_len = 0;
         for (/* ... */; mount_len < max_mount_len && path[mount_len]; ++mount_len) {
             const char c = path[mount_len];
 
-            /* If we see a drive separator, advance, then we're done with the pre-drive separator
-             * part of the mount. */
+            // If we see a drive separator, advance, then we're done with the pre-drive separator
+            // part of the mount.
             if (c == DriveSeparator) {
                 ++mount_len;
                 break;
             }
 
-            /* If we see a directory separator, we're not in a mount name. */
+            // If we see a directory separator, we're not in a mount name
             if (c == DirectorySeparator || c == AlternateDirectorySeparator) {
                 *out = path;
                 *out_len = 0;
@@ -705,19 +704,19 @@ public:
             }
         }
 
-        /* Check to be sure we're actually looking at a mount name. */
+        // Check to be sure we're actually looking at a mount name
         if (mount_len <= 2 || path[mount_len - 1] != DriveSeparator) {
             *out = path;
             *out_len = 0;
             R_SUCCEED();
         }
 
-        /* Check that all characters in the mount name are allowable. */
+        // Check that all characters in the mount name are allowable
         for (size_t i = 0; i < mount_len; ++i) {
             R_UNLESS(!IsInvalidCharacterForMountName(path[i]), ResultInvalidCharacter);
         }
 
-        /* Copy out the mount name. */
+        // Copy out the mount name
         if (out_mount_name_buffer_size > 0) {
             R_UNLESS(mount_len < out_mount_name_buffer_size, ResultTooLongPath);
 
@@ -727,7 +726,7 @@ public:
             out_mount_name[mount_len] = NullTerminator;
         }
 
-        /* Set the output. */
+        // Set the output
         *out = path + mount_len;
         *out_len = mount_len;
         R_SUCCEED();
@@ -742,21 +741,21 @@ public:
                                                  char* out_relative,
                                                  size_t out_relative_buffer_size,
                                                  const char* path) {
-        /* Check pre-conditions. */
+        // Check pre-conditions
         ASSERT(path != nullptr);
         ASSERT(out_len != nullptr);
         ASSERT(out != nullptr);
         ASSERT((out_relative == nullptr) == (out_relative_buffer_size == 0));
 
-        /* Use StringTraits names for remainder of scope. */
+        // Use StringTraits names for remainder of scope
         using namespace StringTraits;
 
-        /* Initialize the output buffer, if we have one. */
+        // Initialize the output buffer, if we have one
         if (out_relative_buffer_size > 0) {
             out_relative[0] = NullTerminator;
         }
 
-        /* Check if the path is relative. */
+        // Check if the path is relative
         if (path[0] == Dot && (path[1] == NullTerminator || path[1] == DirectorySeparator ||
                                path[1] == AlternateDirectorySeparator)) {
             if (out_relative_buffer_size > 0) {
@@ -771,10 +770,10 @@ public:
             R_SUCCEED();
         }
 
-        /* Ensure the path isn't a parent directory. */
+        // Ensure the path isn't a parent directory
         R_UNLESS(!(path[0] == Dot && path[1] == Dot), ResultDirectoryUnobtainable);
 
-        /* There was no relative dot path. */
+        // There was no relative dot path
         *out = path;
         *out_len = 0;
         R_SUCCEED();
@@ -782,7 +781,7 @@ public:
 
     static constexpr Result SkipWindowsPath(const char** out, size_t* out_len, bool* out_normalized,
                                             const char* path, bool has_mount_name) {
-        /* We're normalized if and only if the parsing doesn't throw ResultNotNormalized(). */
+        // We're normalized if and only if the parsing doesn't throw ResultNotNormalized()
         *out_normalized = true;
 
         R_TRY_CATCH(ParseWindowsPath(out, out_len, nullptr, 0, path, has_mount_name)) {
@@ -801,21 +800,21 @@ public:
     static constexpr Result ParseWindowsPath(const char** out, size_t* out_len, char* out_win,
                                              size_t out_win_buffer_size, const char* path,
                                              bool has_mount_name) {
-        /* Check pre-conditions. */
+        // Check pre-conditions
         ASSERT(path != nullptr);
         ASSERT(out_len != nullptr);
         ASSERT(out != nullptr);
         ASSERT((out_win == nullptr) == (out_win_buffer_size == 0));
 
-        /* Use StringTraits names for remainder of scope. */
+        // Use StringTraits names for remainder of scope
         using namespace StringTraits;
 
-        /* Initialize the output buffer, if we have one. */
+        // Initialize the output buffer, if we have one
         if (out_win_buffer_size > 0) {
             out_win[0] = NullTerminator;
         }
 
-        /* Handle path start. */
+        // Handle path start
         const char* cur_path = path;
         if (has_mount_name && path[0] == DirectorySeparator) {
             if (path[1] == AlternateDirectorySeparator && path[2] == AlternateDirectorySeparator) {
@@ -829,9 +828,9 @@ public:
             }
         }
 
-        /* Handle windows drive. */
+        // Handle windows drive
         if (IsWindowsDrive(cur_path)) {
-            /* Parse up to separator. */
+            // Parse up to separator
             size_t win_path_len = WindowsDriveLength;
             for (/* ... */; cur_path[win_path_len] != NullTerminator; ++win_path_len) {
                 R_UNLESS(!IsInvalidCharacter(cur_path[win_path_len]), ResultInvalidCharacter);
@@ -842,13 +841,13 @@ public:
                 }
             }
 
-            /* Ensure that we're normalized, if we're required to be. */
+            // Ensure that we're normalized, if we're required to be
             if (out_win_buffer_size == 0) {
                 for (size_t i = 0; i < win_path_len; ++i) {
                     R_UNLESS(cur_path[i] != AlternateDirectorySeparator, ResultNotNormalized);
                 }
             } else {
-                /* Ensure we can copy into the normalized buffer. */
+                // Ensure we can copy into the normalized buffer
                 R_UNLESS(win_path_len < out_win_buffer_size, ResultTooLongPath);
 
                 for (size_t i = 0; i < win_path_len; ++i) {
@@ -864,7 +863,7 @@ public:
             R_SUCCEED();
         }
 
-        /* Handle DOS device. */
+        // Handle DOS device
         if (IsDosDevicePath(cur_path)) {
             size_t dos_prefix_len = DosDevicePathPrefixLength;
 
@@ -875,7 +874,7 @@ public:
             }
 
             if (out_win_buffer_size > 0) {
-                /* Ensure we can copy into the normalized buffer. */
+                // Ensure we can copy into the normalized buffer
                 R_UNLESS(dos_prefix_len < out_win_buffer_size, ResultTooLongPath);
 
                 for (size_t i = 0; i < dos_prefix_len; ++i) {
@@ -891,7 +890,7 @@ public:
             R_SUCCEED();
         }
 
-        /* Handle UNC path. */
+        // Handle UNC path
         if (IsUncPath(cur_path, false, true)) {
             const char* final_path = cur_path;
 
@@ -932,13 +931,13 @@ public:
 
             size_t unc_prefix_len = final_path - cur_path;
 
-            /* Ensure that we're normalized, if we're required to be. */
+            // Ensure that we're normalized, if we're required to be
             if (out_win_buffer_size == 0) {
                 for (size_t i = 0; i < unc_prefix_len; ++i) {
                     R_UNLESS(cur_path[i] != DirectorySeparator, ResultNotNormalized);
                 }
             } else {
-                /* Ensure we can copy into the normalized buffer. */
+                // Ensure we can copy into the normalized buffer
                 R_UNLESS(unc_prefix_len < out_win_buffer_size, ResultTooLongPath);
 
                 for (size_t i = 0; i < unc_prefix_len; ++i) {
@@ -954,7 +953,7 @@ public:
             R_SUCCEED();
         }
 
-        /* There's no windows path to parse. */
+        // There's no windows path to parse
         *out = path;
         *out_len = 0;
         R_SUCCEED();
@@ -962,18 +961,18 @@ public:
 
     static constexpr Result IsNormalized(bool* out, size_t* out_len, const char* path,
                                          const PathFlags& flags = {}) {
-        /* Ensure nothing is null. */
+        // Ensure nothing is null
         R_UNLESS(out != nullptr, ResultNullptrArgument);
         R_UNLESS(out_len != nullptr, ResultNullptrArgument);
         R_UNLESS(path != nullptr, ResultNullptrArgument);
 
-        /* Verify that the path is valid utf-8. */
+        // Verify that the path is valid utf-8
         R_TRY(CheckUtf8(path));
 
-        /* Use StringTraits names for remainder of scope. */
+        // Use StringTraits names for remainder of scope
         using namespace StringTraits;
 
-        /* Handle the case where the path is empty. */
+        // Handle the case where the path is empty
         if (path[0] == NullTerminator) {
             R_UNLESS(flags.IsEmptyPathAllowed(), ResultInvalidPathFormat);
 
@@ -982,32 +981,32 @@ public:
             R_SUCCEED();
         }
 
-        /* All normalized paths start with a directory separator...unless they're windows paths,
-         * relative paths, or have mount names. */
+        // All normalized paths start with a directory separator...unless they're windows paths,
+        // relative paths, or have mount names.
         if (path[0] != DirectorySeparator) {
             R_UNLESS(flags.IsWindowsPathAllowed() || flags.IsRelativePathAllowed() ||
                          flags.IsMountNameAllowed(),
                      ResultInvalidPathFormat);
         }
 
-        /* Check that the path is allowed to be a windows path, if it is. */
+        // Check that the path is allowed to be a windows path, if it is
         if (IsWindowsPath(path, false)) {
             R_UNLESS(flags.IsWindowsPathAllowed(), ResultInvalidPathFormat);
         }
 
-        /* Skip past the mount name, if one is present. */
+        // Skip past the mount name, if one is present
         size_t total_len = 0;
         size_t mount_name_len = 0;
         R_TRY(SkipMountName(std::addressof(path), std::addressof(mount_name_len), path));
 
-        /* If we had a mount name, check that that was allowed. */
+        // If we had a mount name, check that that was allowed
         if (mount_name_len > 0) {
             R_UNLESS(flags.IsMountNameAllowed(), ResultInvalidPathFormat);
 
             total_len += mount_name_len;
         }
 
-        /* Check that the path starts as a normalized path should. */
+        // Check that the path starts as a normalized path should
         if (path[0] != DirectorySeparator && !IsPathStartWithCurrentDirectory(path) &&
             !IsWindowsPath(path, false)) {
             R_UNLESS(flags.IsRelativePathAllowed(), ResultInvalidPathFormat);
@@ -1017,11 +1016,11 @@ public:
             R_SUCCEED();
         }
 
-        /* Process relative path. */
+        // Process relative path
         size_t relative_len = 0;
         R_TRY(SkipRelativeDotPath(std::addressof(path), std::addressof(relative_len), path));
 
-        /* If we have a relative path, check that was allowed. */
+        // If we have a relative path, check that was allowed
         if (relative_len > 0) {
             R_UNLESS(flags.IsRelativePathAllowed(), ResultInvalidPathFormat);
 
@@ -1034,13 +1033,13 @@ public:
             }
         }
 
-        /* Process windows path. */
+        // Process windows path
         size_t windows_len = 0;
         bool normalized_win = false;
         R_TRY(SkipWindowsPath(std::addressof(path), std::addressof(windows_len),
                               std::addressof(normalized_win), path, mount_name_len > 0));
 
-        /* If the windows path wasn't normalized, we're not normalized. */
+        // If the windows path wasn't normalized, we're not normalized
         if (!normalized_win) {
             R_UNLESS(flags.IsWindowsPathAllowed(), ResultInvalidPathFormat);
 
@@ -1048,22 +1047,22 @@ public:
             R_SUCCEED();
         }
 
-        /* If we had a windows path, check that was allowed. */
+        // If we had a windows path, check that was allowed
         if (windows_len > 0) {
             R_UNLESS(flags.IsWindowsPathAllowed(), ResultInvalidPathFormat);
 
             total_len += windows_len;
 
-            /* We can't have both a relative path and a windows path. */
+            // We can't have both a relative path and a windows path
             R_UNLESS(relative_len == 0, ResultInvalidPathFormat);
 
-            /* A path ending in a windows path isn't normalized. */
+            // A path ending in a windows path isn't normalized
             if (path[0] == NullTerminator) {
                 *out = false;
                 R_SUCCEED();
             }
 
-            /* Check that there are no windows directory separators in the path. */
+            // Check that there are no windows directory separators in the path
             for (size_t i = 0; path[i] != NullTerminator; ++i) {
                 if (path[i] == AlternateDirectorySeparator) {
                     *out = false;
@@ -1072,48 +1071,48 @@ public:
             }
         }
 
-        /* Check that parent directory replacement is not needed if backslashes are allowed. */
+        // Check that parent directory replacement is not needed if backslashes are allowed
         if (flags.IsBackslashAllowed() &&
             PathNormalizer::IsParentDirectoryPathReplacementNeeded(path)) {
             *out = false;
             R_SUCCEED();
         }
 
-        /* Check that the backslash state is valid. */
+        // Check that the backslash state is valid
         bool is_backslash_contained = false;
         R_TRY(CheckInvalidBackslash(std::addressof(is_backslash_contained), path,
                                     flags.IsWindowsPathAllowed() || flags.IsBackslashAllowed()));
 
-        /* Check that backslashes are contained only if allowed. */
+        // Check that backslashes are contained only if allowed
         if (is_backslash_contained && !flags.IsBackslashAllowed()) {
             *out = false;
             R_SUCCEED();
         }
 
-        /* Check that the final result path is normalized. */
+        // Check that the final result path is normalized
         size_t normal_len = 0;
         R_TRY(PathNormalizer::IsNormalized(out, std::addressof(normal_len), path,
                                            flags.IsAllCharactersAllowed()));
 
-        /* Add the normal length. */
+        // Add the normal length
         total_len += normal_len;
 
-        /* Set the output length. */
+        // Set the output length
         *out_len = total_len;
         R_SUCCEED();
     }
 
     static Result Normalize(char* dst, size_t dst_size, const char* path, size_t path_len,
                             const PathFlags& flags) {
-        /* Use StringTraits names for remainder of scope. */
+        // Use StringTraits names for remainder of scope
         using namespace StringTraits;
 
-        /* Prepare to iterate. */
+        // Prepare to iterate
         const char* src = path;
         size_t cur_pos = 0;
         bool is_windows_path = false;
 
-        /* Check if the path is empty. */
+        // Check if the path is empty
         if (src[0] == NullTerminator) {
             if (dst_size != 0) {
                 dst[0] = NullTerminator;
@@ -1124,7 +1123,7 @@ public:
             R_SUCCEED();
         }
 
-        /* Handle a mount name. */
+        // Handle a mount name
         size_t mount_name_len = 0;
         if (flags.IsMountNameAllowed()) {
             R_TRY(ParseMountName(std::addressof(src), std::addressof(mount_name_len), dst + cur_pos,
@@ -1133,7 +1132,7 @@ public:
             cur_pos += mount_name_len;
         }
 
-        /* Handle a drive-relative prefix. */
+        // Handle a drive-relative prefix
         bool is_drive_relative = false;
         if (src[0] != DirectorySeparator && !IsPathStartWithCurrentDirectory(src) &&
             !IsWindowsPath(src, false)) {
@@ -1161,7 +1160,7 @@ public:
             }
         }
 
-        /* Handle a windows path. */
+        // Handle a windows path
         if (flags.IsWindowsPathAllowed()) {
             const char* const orig = src;
 
@@ -1187,16 +1186,16 @@ public:
             }
         }
 
-        /* Check for invalid backslash. */
+        // Check for invalid backslash
         bool backslash_contained = false;
         R_TRY(CheckInvalidBackslash(std::addressof(backslash_contained), src,
                                     flags.IsWindowsPathAllowed() || flags.IsBackslashAllowed()));
 
-        /* Handle backslash replacement as necessary. */
+        // Handle backslash replacement as necessary
         if (backslash_contained && flags.IsWindowsPathAllowed()) {
-            /* Create a temporary buffer holding a slash-replaced version of the path. */
-            /* NOTE: Nintendo unnecessarily allocates and replaces here a fully copy of the path,
-             * despite having skipped some of it already. */
+            // Create a temporary buffer holding a slash-replaced version of the path.
+            // NOTE: Nintendo unnecessarily allocates and replaces here a fully copy of the path,
+            // despite having skipped some of it already.
             const size_t replaced_src_len = path_len - (src - path);
 
             char* replaced_src = nullptr;
@@ -1226,7 +1225,7 @@ public:
                                             dst_size - cur_pos, is_windows_path, is_drive_relative,
                                             flags.IsAllCharactersAllowed()));
         } else {
-            /* We can just do normalization. */
+            // We can just do normalization
             size_t dummy;
             R_TRY(PathNormalizer::Normalize(dst + cur_pos, std::addressof(dummy), src,
                                             dst_size - cur_pos, is_windows_path, is_drive_relative,
diff --git a/src/core/file_sys/fs_string_util.h b/src/core/file_sys/fs_string_util.h
index 68114e72cc..874e090540 100644
--- a/src/core/file_sys/fs_string_util.h
+++ b/src/core/file_sys/fs_string_util.h
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #pragma once
@@ -71,21 +71,6 @@ static constexpr int Strlcpy(T* dst, const T* src, int count) {
     return static_cast<int>(cur - src);
 }
 
-/* std::size() does not support zero-size C arrays. We're fixing that. */
-template <class C>
-constexpr auto size(const C& c) -> decltype(c.size()) {
-    return std::size(c);
-}
-
-template <class C>
-constexpr std::size_t size(const C& c) {
-    if constexpr (sizeof(C) == 0) {
-        return 0;
-    } else {
-        return std::size(c);
-    }
-}
-
 enum CharacterEncodingResult {
     CharacterEncodingResult_Success = 0,
     CharacterEncodingResult_InsufficientLength = 1,
@@ -116,11 +101,11 @@ public:
 } // namespace impl
 
 constexpr inline CharacterEncodingResult ConvertCharacterUtf8ToUtf32(u32* dst, const char* src) {
-    /* Check pre-conditions. */
+    // Check pre-conditions
     ASSERT(dst != nullptr);
     ASSERT(src != nullptr);
 
-    /* Perform the conversion. */
+    // Perform the conversion
     const auto* p = src;
     switch (impl::CharacterEncodingHelper::GetUtf8NBytes(static_cast<unsigned char>(p[0]))) {
     case 1:
@@ -164,24 +149,24 @@ constexpr inline CharacterEncodingResult ConvertCharacterUtf8ToUtf32(u32* dst, c
         break;
     }
 
-    /* We failed to convert. */
+    // We failed to convert
     return CharacterEncodingResult_InvalidFormat;
 }
 
 constexpr inline CharacterEncodingResult PickOutCharacterFromUtf8String(char* dst,
                                                                         const char** str) {
-    /* Check pre-conditions. */
+    // Check pre-conditions
     ASSERT(dst != nullptr);
     ASSERT(str != nullptr);
     ASSERT(*str != nullptr);
 
-    /* Clear the output. */
+    // Clear the output
     dst[0] = 0;
     dst[1] = 0;
     dst[2] = 0;
     dst[3] = 0;
 
-    /* Perform the conversion. */
+    // Perform the conversion
     const auto* p = *str;
     u32 c = static_cast<u32>(*p);
     switch (impl::CharacterEncodingHelper::GetUtf8NBytes(c)) {
diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h
index 2413cdb5c8..718500385b 100644
--- a/src/core/hle/service/filesystem/filesystem.h
+++ b/src/core/hle/service/filesystem/filesystem.h
@@ -4,6 +4,7 @@
 #pragma once
 
 #include <memory>
+#include <mutex>
 #include "common/common_types.h"
 #include "core/file_sys/fs_directory.h"
 #include "core/file_sys/fs_filesystem.h"
diff --git a/src/core/hle/service/glue/time/manager.cpp b/src/core/hle/service/glue/time/manager.cpp
index 6423e5089f..b567629411 100644
--- a/src/core/hle/service/glue/time/manager.cpp
+++ b/src/core/hle/service/glue/time/manager.cpp
@@ -8,7 +8,7 @@
 
 #include "common/settings.h"
 #include "common/time_zone.h"
-#include "core/file_sys/vfs.h"
+#include "core/file_sys/vfs/vfs.h"
 #include "core/hle/kernel/svc.h"
 #include "core/hle/service/glue/time/manager.h"
 #include "core/hle/service/glue/time/time_zone_binary.h"
diff --git a/src/core/hle/service/glue/time/manager.h b/src/core/hle/service/glue/time/manager.h
index a46ec6364d..1de93f8f9b 100644
--- a/src/core/hle/service/glue/time/manager.h
+++ b/src/core/hle/service/glue/time/manager.h
@@ -7,7 +7,7 @@
 #include <string>
 
 #include "common/common_types.h"
-#include "core/file_sys/vfs_types.h"
+#include "core/file_sys/vfs/vfs_types.h"
 #include "core/hle/service/glue/time/file_timestamp_worker.h"
 #include "core/hle/service/glue/time/standard_steady_clock_resource.h"
 #include "core/hle/service/glue/time/worker.h"
diff --git a/src/core/hle/service/glue/time/time_zone_binary.cpp b/src/core/hle/service/glue/time/time_zone_binary.cpp
index 67969aa3fe..d33f784c05 100644
--- a/src/core/hle/service/glue/time/time_zone_binary.cpp
+++ b/src/core/hle/service/glue/time/time_zone_binary.cpp
@@ -7,7 +7,7 @@
 #include "core/file_sys/registered_cache.h"
 #include "core/file_sys/romfs.h"
 #include "core/file_sys/system_archive/system_archive.h"
-#include "core/file_sys/vfs.h"
+#include "core/file_sys/vfs/vfs.h"
 #include "core/hle/service/filesystem/filesystem.h"
 #include "core/hle/service/glue/time/time_zone_binary.h"
 
diff --git a/src/frontend_common/content_manager.h b/src/frontend_common/content_manager.h
index fc359b494a..f3efe34652 100644
--- a/src/frontend_common/content_manager.h
+++ b/src/frontend_common/content_manager.h
@@ -159,7 +159,7 @@ inline InstallResult InstallNSP(Core::System& system, FileSys::VfsFilesystem& vf
     };
 
     std::shared_ptr<FileSys::NSP> nsp;
-    FileSys::VirtualFile file = vfs.OpenFile(filename, FileSys::Mode::Read);
+    FileSys::VirtualFile file = vfs.OpenFile(filename, FileSys::OpenMode::Read);
     if (boost::to_lower_copy(file->GetName()).ends_with(std::string("nsp"))) {
         nsp = std::make_shared<FileSys::NSP>(file);
         if (nsp->IsExtractedType()) {
@@ -224,7 +224,8 @@ inline InstallResult InstallNCA(FileSys::VfsFilesystem& vfs, const std::string&
         return true;
     };
 
-    const auto nca = std::make_shared<FileSys::NCA>(vfs.OpenFile(filename, FileSys::Mode::Read));
+    const auto nca =
+        std::make_shared<FileSys::NCA>(vfs.OpenFile(filename, FileSys::OpenMode::Read));
     const auto id = nca->GetStatus();
 
     // Game updates necessary are missing base RomFS
@@ -345,8 +346,8 @@ inline std::vector<std::string> VerifyInstalledContents(
 inline GameVerificationResult VerifyGameContents(
     Core::System& system, const std::string& game_path,
     const std::function<bool(size_t, size_t)>& callback) {
-    const auto loader =
-        Loader::GetLoader(system, system.GetFilesystem()->OpenFile(game_path, FileSys::Mode::Read));
+    const auto loader = Loader::GetLoader(
+        system, system.GetFilesystem()->OpenFile(game_path, FileSys::OpenMode::Read));
     if (loader == nullptr) {
         return GameVerificationResult::NotImplemented;
     }