diff options
| author | Admiral H. Curtiss <pikachu025@gmail.com> | 2021-10-23 02:03:11 +0200 |
|---|---|---|
| committer | Admiral H. Curtiss <pikachu025@gmail.com> | 2021-10-24 00:09:09 +0200 |
| commit | 0efff5167d8da31f4233a4bf9999c3970517040a (patch) | |
| tree | 1ac3b7b0a3ac9004f6f1bc509ac58d0140a03150 /Source | |
| parent | fe7f3a6f26a1e9fc14e97d98d8db1aa07819861d (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.cpp | 29 |
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. |
