summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorAdmiral H. Curtiss <pikachu025@gmail.com>2021-10-23 02:03:11 +0200
committerAdmiral H. Curtiss <pikachu025@gmail.com>2021-10-24 00:09:09 +0200
commit0efff5167d8da31f4233a4bf9999c3970517040a (patch)
tree1ac3b7b0a3ac9004f6f1bc509ac58d0140a03150 /Source
parentfe7f3a6f26a1e9fc14e97d98d8db1aa07819861d (diff)
IOS/FS: On NAND redirected files, the source and target of a Rename operation may be on different partitions or devices. Implement a fallback for that.
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/IOS/FS/HostBackend/FS.cpp29
1 files changed, 25 insertions, 4 deletions
diff --git a/Source/Core/Core/IOS/FS/HostBackend/FS.cpp b/Source/Core/Core/IOS/FS/HostBackend/FS.cpp
index 8ca81558cd..7bdb785e7f 100644
--- a/Source/Core/Core/IOS/FS/HostBackend/FS.cpp
+++ b/Source/Core/Core/IOS/FS/HostBackend/FS.cpp
@@ -506,8 +506,10 @@ ResultCode HostFileSystem::Rename(Uid uid, Gid gid, const std::string& old_path,
return ResultCode::InUse;
}
- const std::string host_old_path = BuildFilename(old_path).host_path;
- const std::string host_new_path = BuildFilename(new_path).host_path;
+ const auto host_old_info = BuildFilename(old_path);
+ const auto host_new_info = BuildFilename(new_path);
+ const std::string& host_old_path = host_old_info.host_path;
+ const std::string& host_new_path = host_new_info.host_path;
// If there is already something of the same type at the new path, delete it.
if (File::Exists(host_new_path))
@@ -524,8 +526,27 @@ ResultCode HostFileSystem::Rename(Uid uid, Gid gid, const std::string& old_path,
if (!File::Rename(host_old_path, host_new_path))
{
- ERROR_LOG_FMT(IOS_FS, "Rename {} to {} - failed", host_old_path, host_new_path);
- return ResultCode::NotFound;
+ if (host_old_info.is_redirect || host_new_info.is_redirect)
+ {
+ // If either path is a redirect, the source and target may be on a different partition or
+ // device, so a simple rename may not work. Fall back to Copy & Delete and see if that works.
+ if (!File::Copy(host_old_path, host_new_path))
+ {
+ ERROR_LOG_FMT(IOS_FS, "Copying {} to {} in Rename fallback failed", host_old_path,
+ host_new_path);
+ return ResultCode::NotFound;
+ }
+ if (!File::Delete(host_old_path))
+ {
+ ERROR_LOG_FMT(IOS_FS, "Deleting {} in Rename fallback failed", host_old_path);
+ return ResultCode::Invalid;
+ }
+ }
+ else
+ {
+ ERROR_LOG_FMT(IOS_FS, "Rename {} to {} - failed", host_old_path, host_new_path);
+ return ResultCode::NotFound;
+ }
}
// Finally, remove the child from the old parent and move it to the new parent.