From 9736773c04c319f53cf8963f5b4354ef5f534814 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sun, 7 Apr 2019 12:58:08 +0300 Subject: [PATCH] Implement vfs::host::rename With spurious access error workaround --- rpcs3/Emu/Cell/Modules/cellGame.cpp | 2 +- rpcs3/Emu/Cell/Modules/cellSaveData.cpp | 11 ++++------- rpcs3/Emu/Cell/lv2/sys_fs.cpp | 2 +- rpcs3/Emu/VFS.cpp | 15 +++++++++++++++ rpcs3/Emu/VFS.h | 7 +++++++ 5 files changed, 28 insertions(+), 9 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellGame.cpp b/rpcs3/Emu/Cell/Modules/cellGame.cpp index 774dccdd45..10009f4ae3 100644 --- a/rpcs3/Emu/Cell/Modules/cellGame.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGame.cpp @@ -453,7 +453,7 @@ error_code cellGameContentPermit(vm::ptr contentInfoPa // Make temporary directory persistent const auto vdir = vfs::get(dir); - if (fs::rename(prm->temp, vdir, false)) + if (vfs::host::rename(prm->temp, vdir, false)) { cellGame.success("cellGameContentPermit(): directory '%s' has been created", dir); } diff --git a/rpcs3/Emu/Cell/Modules/cellSaveData.cpp b/rpcs3/Emu/Cell/Modules/cellSaveData.cpp index 1804267027..91b96f78e2 100644 --- a/rpcs3/Emu/Cell/Modules/cellSaveData.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSaveData.cpp @@ -934,19 +934,16 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v fs::remove_all(old_path, false); // Backup old savedata - while (!fs::rename(dir_path, old_path, true)) + if (!vfs::host::rename(dir_path, old_path, true)) { - // Try to ignore access error in order to prevent spurious failure - if (Emu.IsStopped() || fs::g_tls_error != fs::error::acces) - fmt::throw_exception("Failed to move directory %s (%s)", dir_path, fs::g_tls_error); + fmt::throw_exception("Failed to move directory %s (%s)", dir_path, fs::g_tls_error); } // Commit new savedata - while (!fs::rename(new_path, dir_path, false)) + if (!vfs::host::rename(new_path, dir_path, false)) { // TODO: handle the case when only commit failed at the next save load - if (Emu.IsStopped() || fs::g_tls_error != fs::error::acces) - fmt::throw_exception("Failed to move directory %s (%s)", new_path, fs::g_tls_error); + fmt::throw_exception("Failed to move directory %s (%s)", new_path, fs::g_tls_error); } // Remove backup again (TODO: may be changed to persistent backup implementation) diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.cpp b/rpcs3/Emu/Cell/lv2/sys_fs.cpp index 475aa3155c..02054e0504 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_fs.cpp @@ -774,7 +774,7 @@ error_code sys_fs_rename(vm::cptr from, vm::cptr to) return CELL_ENOTMOUNTED; } - if (!fs::rename(local_from, local_to, false)) + if (!vfs::host::rename(local_from, local_to, false)) { switch (auto error = fs::g_tls_error) { diff --git a/rpcs3/Emu/VFS.cpp b/rpcs3/Emu/VFS.cpp index d8ae90cf2e..4535a3158d 100644 --- a/rpcs3/Emu/VFS.cpp +++ b/rpcs3/Emu/VFS.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "IdManager.h" +#include "System.h" #include "VFS.h" #include "Utilities/mutex.h" @@ -447,3 +448,17 @@ std::string vfs::unescape(std::string_view path) return result; } + +bool vfs::host::rename(const std::string& from, const std::string& to, bool overwrite) +{ + while (!fs::rename(from, to, overwrite)) + { + // Try to ignore access error in order to prevent spurious failure + if (Emu.IsStopped() || fs::g_tls_error != fs::error::acces) + { + return false; + } + } + + return true; +} diff --git a/rpcs3/Emu/VFS.h b/rpcs3/Emu/VFS.h index b4dc298e55..bb546c097b 100644 --- a/rpcs3/Emu/VFS.h +++ b/rpcs3/Emu/VFS.h @@ -17,4 +17,11 @@ namespace vfs // Invert escape operation std::string unescape(std::string_view path); + + // Functions in this namespace operate on host filepaths, similar to fs:: + namespace host + { + // Call fs::rename with retry on access error + bool rename(const std::string& from, const std::string& to, bool overwrite); + } }