From 42983c0bd3e65b6c6284059a3b007cf08ac45258 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Thu, 29 Mar 2018 18:57:07 +0200 Subject: [PATCH] IOS/FS: Emulate superblock write timing --- Source/Core/Core/IOS/FS/FileSystemProxy.cpp | 25 ++++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/Source/Core/Core/IOS/FS/FileSystemProxy.cpp b/Source/Core/Core/IOS/FS/FileSystemProxy.cpp index e03e2af196..0b47595aa6 100644 --- a/Source/Core/Core/IOS/FS/FileSystemProxy.cpp +++ b/Source/Core/Core/IOS/FS/FileSystemProxy.cpp @@ -36,6 +36,9 @@ static IPCCommandResult GetFSReply(s32 return_value, u64 extra_tb_ticks = 0) return {return_value, true, (2700 + extra_tb_ticks) * SystemTimers::TIMER_RATIO}; } +/// Amount of TB ticks required for a superblock write to complete. +constexpr u64 SUPERBLOCK_WRITE_TICKS = 3370000; + FS::FS(Kernel& ios, const std::string& device_name) : Device(ios, device_name) { } @@ -80,6 +83,16 @@ static u64 EstimateFileLookupTicks(const std::string& path, FileLookupMode mode) return 1000 + 340 * number_of_path_components; } +/// Get a reply with the correct timing for operations that modify the superblock. +/// +/// A superblock flush takes a very large amount of time, so other delays are ignored +/// to simplify the implementation as they are insignificant. +static IPCCommandResult GetReplyForSuperblockOperation(ResultCode result) +{ + const u64 ticks = result == ResultCode::Success ? SUPERBLOCK_WRITE_TICKS : 0; + return GetFSReply(ConvertResult(result), ticks); +} + IPCCommandResult FS::Open(const OpenRequest& request) { if (m_fd_map.size() >= 16) @@ -271,7 +284,7 @@ IPCCommandResult FS::Format(const Handle& handle, const IOCtlRequest& request) return GetFSReply(ConvertResult(ResultCode::AccessDenied)); const ResultCode result = m_ios.GetFS()->Format(handle.uid); - return GetFSReply(ConvertResult(result)); + return GetReplyForSuperblockOperation(result); } IPCCommandResult FS::GetStats(const Handle& handle, const IOCtlRequest& request) @@ -306,7 +319,7 @@ IPCCommandResult FS::CreateDirectory(const Handle& handle, const IOCtlRequest& r m_ios.GetFS()->CreateDirectory(handle.uid, handle.gid, params->path, params->attribute, params->owner_mode, params->group_mode, params->other_mode); LogResult(StringFromFormat("CreateDirectory(%s)", params->path), result); - return GetFSReply(ConvertResult(result)); + return GetReplyForSuperblockOperation(result); } IPCCommandResult FS::ReadDirectory(const Handle& handle, const IOCtlVRequest& request) @@ -371,7 +384,7 @@ IPCCommandResult FS::SetAttribute(const Handle& handle, const IOCtlRequest& requ handle.uid, params->path, params->uid, params->gid, params->attribute, params->owner_mode, params->group_mode, params->other_mode); LogResult(StringFromFormat("SetMetadata(%s)", params->path), result); - return GetFSReply(ConvertResult(result)); + return GetReplyForSuperblockOperation(result); } IPCCommandResult FS::GetAttribute(const Handle& handle, const IOCtlRequest& request) @@ -408,7 +421,7 @@ IPCCommandResult FS::DeleteFile(const Handle& handle, const IOCtlRequest& reques const std::string path = Memory::GetString(request.buffer_in, 64); const ResultCode result = m_ios.GetFS()->Delete(handle.uid, handle.gid, path); LogResult(StringFromFormat("Delete(%s)", path.c_str()), result); - return GetFSReply(ConvertResult(result)); + return GetReplyForSuperblockOperation(result); } IPCCommandResult FS::RenameFile(const Handle& handle, const IOCtlRequest& request) @@ -420,7 +433,7 @@ IPCCommandResult FS::RenameFile(const Handle& handle, const IOCtlRequest& reques const std::string new_path = Memory::GetString(request.buffer_in + 64, 64); const ResultCode result = m_ios.GetFS()->Rename(handle.uid, handle.gid, old_path, new_path); LogResult(StringFromFormat("Rename(%s, %s)", old_path.c_str(), new_path.c_str()), result); - return GetFSReply(ConvertResult(result)); + return GetReplyForSuperblockOperation(result); } IPCCommandResult FS::CreateFile(const Handle& handle, const IOCtlRequest& request) @@ -433,7 +446,7 @@ IPCCommandResult FS::CreateFile(const Handle& handle, const IOCtlRequest& reques m_ios.GetFS()->CreateFile(handle.uid, handle.gid, params->path, params->attribute, params->owner_mode, params->group_mode, params->other_mode); LogResult(StringFromFormat("CreateFile(%s)", params->path), result); - return GetFSReply(ConvertResult(result)); + return GetReplyForSuperblockOperation(result); } IPCCommandResult FS::SetFileVersionControl(const Handle& handle, const IOCtlRequest& request)