mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-17 08:11:51 +00:00
Improve vfs::host::unlink on Windows (for sys_fs_rmdir)
Possibly fixes sys_fs_rmdir and other cases of directory removal. Make sure the directory with deleted files always becomes empty. For this purpose, temp files are moved to the root of the device.
This commit is contained in:
parent
cd843bda6e
commit
ccf9543b44
@ -862,7 +862,9 @@ error_code sys_fs_unlink(ppu_thread& ppu, vm::cptr<char> path)
|
|||||||
const std::string_view vpath = path.get_ptr();
|
const std::string_view vpath = path.get_ptr();
|
||||||
const std::string local_path = vfs::get(vpath);
|
const std::string local_path = vfs::get(vpath);
|
||||||
|
|
||||||
if (vpath.find_first_not_of('/') == -1)
|
const std::size_t dev_start = vpath.find_first_not_of('/');
|
||||||
|
|
||||||
|
if (dev_start == -1)
|
||||||
{
|
{
|
||||||
return {CELL_EISDIR, path};
|
return {CELL_EISDIR, path};
|
||||||
}
|
}
|
||||||
@ -877,7 +879,10 @@ error_code sys_fs_unlink(ppu_thread& ppu, vm::cptr<char> path)
|
|||||||
return {CELL_EISDIR, path};
|
return {CELL_EISDIR, path};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vfs::host::unlink(local_path))
|
// Size of "/dev_hdd0"-alike substring
|
||||||
|
const std::size_t dev_size = vpath.find_first_of('/', dev_start);
|
||||||
|
|
||||||
|
if (!vfs::host::unlink(local_path, vfs::get(vpath.substr(0, dev_size))))
|
||||||
{
|
{
|
||||||
switch (auto error = fs::g_tls_error)
|
switch (auto error = fs::g_tls_error)
|
||||||
{
|
{
|
||||||
|
@ -33,6 +33,8 @@ bool vfs::mount(std::string_view vpath, std::string_view path)
|
|||||||
|
|
||||||
const auto table = g_fxo->get<vfs_manager>();
|
const auto table = g_fxo->get<vfs_manager>();
|
||||||
|
|
||||||
|
// TODO: scan roots of mounted devices for undeleted vfs::host::unlink remnants, and try to delete them (_WIN32 only)
|
||||||
|
|
||||||
std::lock_guard lock(table->mutex);
|
std::lock_guard lock(table->mutex);
|
||||||
|
|
||||||
if (vpath.empty())
|
if (vpath.empty())
|
||||||
@ -566,13 +568,13 @@ bool vfs::host::rename(const std::string& from, const std::string& to, bool over
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vfs::host::unlink(const std::string& path)
|
bool vfs::host::unlink(const std::string& path, const std::string& dev_root)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (path.size() < 2 || reinterpret_cast<const u16&>(path.front()) != "//"_u16)
|
if (path.size() < 2 || reinterpret_cast<const u16&>(path.front()) != "//"_u16)
|
||||||
{
|
{
|
||||||
// Rename to special dummy name which will be ignored by VFS (but opened file handles can still read or write it)
|
// Rename to special dummy name which will be ignored by VFS (but opened file handles can still read or write it)
|
||||||
const std::string dummy = fmt::format(u8"%s/$%s%s", fs::get_parent_dir(path), fmt::base57(std::hash<std::string>()(path)), fmt::base57(__rdtsc()));
|
const std::string dummy = fmt::format(u8"%s/$%s%s", dev_root, fmt::base57(std::hash<std::string>()(path)), fmt::base57(__rdtsc()));
|
||||||
|
|
||||||
if (!fs::rename(path, dummy, true))
|
if (!fs::rename(path, dummy, true))
|
||||||
{
|
{
|
||||||
|
@ -25,6 +25,6 @@ namespace vfs
|
|||||||
bool rename(const std::string& from, const std::string& to, bool overwrite);
|
bool rename(const std::string& from, const std::string& to, bool overwrite);
|
||||||
|
|
||||||
// Delete file without deleting its contents, emulated with MoveFileEx on Windows
|
// Delete file without deleting its contents, emulated with MoveFileEx on Windows
|
||||||
bool unlink(const std::string&);
|
bool unlink(const std::string& path, const std::string& dev_root);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user