1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-26 04:32:35 +01:00

sys_fs: Prevented duplicate device mounting

This commit is contained in:
brian218 2024-01-08 07:52:28 +08:00 committed by Megamouse
parent 862295d9f3
commit a269ae7e30
2 changed files with 21 additions and 32 deletions

View File

@ -193,38 +193,30 @@ u64 lv2_fs_mount_info_map::get_all(CellFsMountInfo* info, u64 len) const
if (!info)
return map.size();
struct mount_info
{
const std::string_view path, filesystem, dev_name;
const be_t<u32> unk1 = 0, unk2 = 0, unk3 = 0, unk4 = 0, unk5 = 0;
};
u64 count = 0;
auto push_info = [&](mount_info&& data)
for (const auto& [path, mount_info] : map)
{
if (count >= len)
return;
break;
strcpy_trunc(info->mount_path, data.path);
strcpy_trunc(info->filesystem, data.filesystem);
strcpy_trunc(info->dev_name, data.dev_name);
std::memcpy(&info->unk1, &data.unk1, sizeof(be_t<u32>) * 5);
strcpy_trunc(info[count].mount_path, path);
strcpy_trunc(info[count].filesystem, mount_info.file_system);
strcpy_trunc(info[count].dev_name, mount_info.device);
if (mount_info.read_only)
info[count].unk[4] |= 0x10000000;
info++, count++;
};
for (const auto& [path, mi] : map)
{
if (mi == &g_mp_sys_dev_root || mi == &g_mp_sys_dev_flash)
push_info(mount_info{.path = path, .filesystem = mi.file_system, .dev_name = mi.device, .unk5 = 0x10000000});
else
push_info(mount_info{.path = path, .filesystem = mi.file_system, .dev_name = mi.device});
count++;
}
return count;
}
bool lv2_fs_mount_info_map::is_device_mounted(std::string_view device_name) const
{
return std::any_of(map.begin(), map.end(), [&](const decltype(map)::value_type& info) { return info.second.device == device_name; });
}
bool lv2_fs_mount_info_map::vfs_unmount(std::string_view vpath, bool remove_from_map)
{
const std::string local_path = vfs::get(vpath);
@ -3151,7 +3143,7 @@ error_code sys_fs_newfs(ppu_thread& ppu, vm::cptr<char> dev_name, vm::cptr<char>
if (mp == &g_mp_sys_no_device)
return {CELL_ENXIO, device_name};
if (mp == &g_mp_sys_dev_root || !lock.try_lock())
if (g_fxo->get<lv2_fs_mount_info_map>().is_device_mounted(device_name) || !lock.try_lock())
return {CELL_EBUSY, device_name};
if (vfs_path.empty())
@ -3215,7 +3207,7 @@ error_code sys_fs_mount(ppu_thread& ppu, vm::cptr<char> dev_name, vm::cptr<char>
if (mp == &g_mp_sys_no_device)
return {CELL_ENXIO, device_name};
if (mp == &g_mp_sys_dev_root || !lock.try_lock())
if (g_fxo->get<lv2_fs_mount_info_map>().is_device_mounted(device_name) || !lock.try_lock())
return {CELL_EBUSY, device_name};
if (vfs_path.empty())
@ -3279,11 +3271,11 @@ error_code sys_fs_mount(ppu_thread& ppu, vm::cptr<char> dev_name, vm::cptr<char>
return CELL_OK;
}
error_code sys_fs_unmount(ppu_thread& ppu, vm::cptr<char> path, s32 unk1, s32 unk2)
error_code sys_fs_unmount(ppu_thread& ppu, vm::cptr<char> path, s32 unk1, s32 force)
{
ppu.state += cpu_flag::wait;
sys_fs.warning("sys_fs_unmount(path=%s, unk1=0x%x, unk2=0x%x)", path, unk1, unk2);
sys_fs.warning("sys_fs_unmount(path=%s, unk1=0x%x, force=%d)", path, unk1, force);
const auto [path_error, vpath] = translate_to_str(path);
@ -3301,7 +3293,7 @@ error_code sys_fs_unmount(ppu_thread& ppu, vm::cptr<char> path, s32 unk1, s32 un
if (mp == &g_mp_sys_no_device)
return {CELL_EINVAL, vpath};
if (mp == &g_mp_sys_dev_root || !lock.try_lock())
if (mp == &g_mp_sys_dev_root || (!lock.try_lock() && !force))
return {CELL_EBUSY, vpath};
if (!lv2_fs_mount_info_map::vfs_unmount(vpath))

View File

@ -215,6 +215,7 @@ public:
bool remove(std::string_view path);
const lv2_fs_mount_info& lookup(std::string_view path, bool no_cell_fs_path = false, std::string* mount_path = nullptr) const;
u64 get_all(CellFsMountInfo* info = nullptr, u64 len = 0) const;
bool is_device_mounted(std::string_view device_name) const;
static bool vfs_unmount(std::string_view vpath, bool remove_from_map = true);
@ -620,11 +621,7 @@ struct CellFsMountInfo
char mount_path[0x20]; // 0x0
char filesystem[0x20]; // 0x20
char dev_name[0x40]; // 0x40
be_t<u32> unk1; // 0x80
be_t<u32> unk2; // 0x84
be_t<u32> unk3; // 0x88
be_t<u32> unk4; // 0x8C
be_t<u32> unk5; // 0x90
be_t<u32> unk[5]; // 0x80, probably attributes
};
CHECK_SIZE(CellFsMountInfo, 0x94);
@ -682,6 +679,6 @@ error_code sys_fs_mapped_free(ppu_thread& ppu, u32 fd, vm::ptr<void> ptr);
error_code sys_fs_truncate2(ppu_thread& ppu, u32 fd, u64 size);
error_code sys_fs_newfs(ppu_thread& ppu, vm::cptr<char> dev_name, vm::cptr<char> file_system, s32 unk1, vm::cptr<char> str1);
error_code sys_fs_mount(ppu_thread& ppu, vm::cptr<char> dev_name, vm::cptr<char> file_system, vm::cptr<char> path, s32 unk1, s32 prot, s32 unk3, vm::cptr<char> str1, u32 str_len);
error_code sys_fs_unmount(ppu_thread& ppu, vm::cptr<char> path, s32 unk1, s32 unk2);
error_code sys_fs_unmount(ppu_thread& ppu, vm::cptr<char> path, s32 unk1, s32 force);
error_code sys_fs_get_mount_info_size(ppu_thread& ppu, vm::ptr<u64> len);
error_code sys_fs_get_mount_info(ppu_thread& ppu, vm::ptr<CellFsMountInfo> info, u64 len, vm::ptr<u64> out_len);