summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorJosJuice <josjuice@gmail.com>2026-08-30 10:19:48 +0200
committerJosJuice <josjuice@gmail.com>2026-09-20 11:56:57 +0200
commit4fcd61620f27df04bbecfda705252ce720ea5a46 (patch)
tree7792863a23fcf40e52a57aba03dab1d727f65fef /Source/Core
parentee018d00e60b9eb727489908a8daec5c537f44a8 (diff)
IOS/FS: Fix loading savestate while TASing, part 1
When TASing, we savestate not just /tmp but also /. The code that was added in d35fe1b didn't handle recreating / correctly. This commit fixes the problem by skipping recreating /, which is fine since it always exists.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/IOS/FS/FileSystemCommon.cpp69
1 files changed, 54 insertions, 15 deletions
diff --git a/Source/Core/Core/IOS/FS/FileSystemCommon.cpp b/Source/Core/Core/IOS/FS/FileSystemCommon.cpp
index 0e13192c5b..1d88e51f46 100644
--- a/Source/Core/Core/IOS/FS/FileSystemCommon.cpp
+++ b/Source/Core/Core/IOS/FS/FileSystemCommon.cpp
@@ -139,12 +139,45 @@ ResultCode FileSystem::CreateFullPath(Uid uid, Gid gid, const std::string& path,
void FileSystem::DoStateRead(PointerWrap& p, const std::string& directory_path)
{
- const ResultCode delete_result = Delete(0, 0, directory_path);
- if (delete_result != ResultCode::Success && delete_result != ResultCode::NotFound)
+ const auto delete_ = [this](const std::string& directory_path_) {
+ const ResultCode delete_result = Delete(0, 0, directory_path_);
+ if (delete_result != ResultCode::Success && delete_result != ResultCode::NotFound)
+ {
+ ERROR_LOG_FMT(IOS_FS, "DoStateRead failed to call Delete for {}: {}", directory_path_,
+ delete_result);
+ return false;
+ }
+ return true;
+ };
+
+ if (directory_path != "/")
{
- ERROR_LOG_FMT(IOS_FS, "DoStateRead failed to call Delete: {}", delete_result);
- p.SetVerifyMode();
- return;
+ if (!delete_(directory_path))
+ {
+ p.SetVerifyMode();
+ return;
+ }
+ }
+ else
+ {
+ // Calling Delete for the root would return Invalid. Let's delete all children instead.
+ auto children = ReadDirectory(0, 0, directory_path);
+ if (!children)
+ {
+ ERROR_LOG_FMT(IOS_FS, "DoStateRead failed to call ReadDirectory for {}: {}", directory_path,
+ children.error());
+ p.SetVerifyMode();
+ return;
+ }
+
+ for (const std::string& child_name : children.value())
+ {
+ if (!delete_(directory_path + child_name))
+ {
+ p.SetVerifyMode();
+ return;
+ }
+ }
}
Metadata metadata{};
@@ -156,14 +189,19 @@ void FileSystem::DoStateRead(PointerWrap& p, const std::string& directory_path)
p.Do(metadata.size);
p.Do(metadata.fst_index);
- const ResultCode create_directory_result = CreateDirectory(
- metadata.uid, metadata.gid, directory_path, metadata.attribute, metadata.modes);
- if (create_directory_result != ResultCode::Success)
+ // Again here, calling CreateDirectory for the root would return Invalid.
+ // The root always exists, so we can skip creating it.
+ if (directory_path != "/")
{
- ERROR_LOG_FMT(IOS_FS, "DoStateRead failed to call CreateDirectory: {}",
- create_directory_result);
- p.SetVerifyMode();
- return;
+ const ResultCode create_directory_result = CreateDirectory(
+ metadata.uid, metadata.gid, directory_path, metadata.attribute, metadata.modes);
+ if (create_directory_result != ResultCode::Success)
+ {
+ ERROR_LOG_FMT(IOS_FS, "DoStateRead failed to call CreateDirectory for {}: {}", directory_path,
+ create_directory_result);
+ p.SetVerifyMode();
+ return;
+ }
}
// Now restore from the stream
@@ -241,7 +279,8 @@ void FileSystem::DoStateWriteOrMeasure(PointerWrap& p, const std::string& direct
const Result<Metadata> metadata = GetMetadata(0, 0, directory_path);
if (!metadata)
{
- ERROR_LOG_FMT(IOS_FS, "DoStateWriteOrMeasure failed to call GetMetadata: {}", metadata.error());
+ ERROR_LOG_FMT(IOS_FS, "DoStateWriteOrMeasure failed to call GetMetadata for {}: {}",
+ directory_path, metadata.error());
p.SetVerifyMode();
return;
}
@@ -256,8 +295,8 @@ void FileSystem::DoStateWriteOrMeasure(PointerWrap& p, const std::string& direct
auto children = ReadDirectory(0, 0, directory_path);
if (!children)
{
- ERROR_LOG_FMT(IOS_FS, "DoStateWriteOrMeasure failed to call ReadDirectory: {}",
- children.error());
+ ERROR_LOG_FMT(IOS_FS, "DoStateWriteOrMeasure failed to call ReadDirectory for {}: {}",
+ directory_path, children.error());
p.SetVerifyMode();
return;
}