From 3c614d95b86fc617118aef5cc11797205181c217 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sun, 20 Jun 2021 14:45:33 +0300 Subject: [PATCH] fs: alternative fs::pending_file implementation (Win32) Use MOVEFILE_WRITE_THROUGH instead of sync() on commit(). --- Utilities/File.cpp | 16 ++++++++++++++++ Utilities/File.h | 2 ++ rpcs3/Emu/Cell/Modules/cellSaveData.cpp | 4 +++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/Utilities/File.cpp b/Utilities/File.cpp index dc6ea3681b..9eea88c43e 100644 --- a/Utilities/File.cpp +++ b/Utilities/File.cpp @@ -1984,15 +1984,31 @@ bool fs::pending_file::commit(bool overwrite) } // The temporary file's contents must be on disk before rename +#ifndef _WIN32 file.sync(); +#endif file.close(); +#ifdef _WIN32 + const auto ws1 = to_wchar(m_path); + const auto ws2 = to_wchar(m_dest); + + if (MoveFileExW(ws1.get(), ws2.get(), overwrite ? MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH : MOVEFILE_WRITE_THROUGH)) + { + // Disable the destructor + m_path.clear(); + return true; + } + + g_tls_error = to_error(GetLastError()); +#else if (fs::rename(m_path, m_dest, overwrite)) { // Disable the destructor m_path.clear(); return true; } +#endif return false; } diff --git a/Utilities/File.h b/Utilities/File.h index d97931bfd5..20ed7760a2 100644 --- a/Utilities/File.h +++ b/Utilities/File.h @@ -649,6 +649,8 @@ namespace fs bool commit(bool overwrite = true); pending_file(const std::string& path); + pending_file(const pending_file&) = delete; + pending_file& operator=(const pending_file&) = delete; ~pending_file(); private: diff --git a/rpcs3/Emu/Cell/Modules/cellSaveData.cpp b/rpcs3/Emu/Cell/Modules/cellSaveData.cpp index dc427e1f1d..bb757aba7e 100644 --- a/rpcs3/Emu/Cell/Modules/cellSaveData.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSaveData.cpp @@ -1946,7 +1946,9 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v if (auto file = pair.second.release()) { auto&& fvec = static_cast>&>(*file); - ensure(fs::write_file(new_path + vfs::escape(pair.first), fs::rewrite, fvec.obj)); + fs::pending_file f(new_path + vfs::escape(pair.first)); + f.file.write(fvec.obj); + ensure(f.commit()); } }