mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-07 07:21:25 +12:00
Add support for mounting and unmounting CELL_FS_SIMPLEFS
This commit is contained in:
parent
ecc194cb62
commit
c7ced46707
4 changed files with 72 additions and 22 deletions
|
@ -22,15 +22,15 @@ LOG_CHANNEL(sys_fs);
|
||||||
|
|
||||||
lv2_fs_mount_point g_mp_sys_dev_root;
|
lv2_fs_mount_point g_mp_sys_dev_root;
|
||||||
lv2_fs_mount_point g_mp_sys_no_device;
|
lv2_fs_mount_point g_mp_sys_no_device;
|
||||||
lv2_fs_mount_point g_mp_sys_dev_hdd0{"/dev_hdd0"};
|
lv2_fs_mount_point g_mp_sys_dev_hdd0{"/dev_hdd0", 512, 0x24FAEA98};
|
||||||
lv2_fs_mount_point g_mp_sys_dev_hdd1{"/dev_hdd1", 512, 32768, lv2_mp_flag::no_uid_gid + lv2_mp_flag::cache};
|
lv2_fs_mount_point g_mp_sys_dev_hdd1{"/dev_hdd1", 512, 0x3FFFF8, 32768, lv2_mp_flag::no_uid_gid + lv2_mp_flag::cache};
|
||||||
lv2_fs_mount_point g_mp_sys_dev_usb{"", 512, 4096, lv2_mp_flag::no_uid_gid};
|
lv2_fs_mount_point g_mp_sys_dev_usb{"", 512, 0x100, 4096, lv2_mp_flag::no_uid_gid};
|
||||||
lv2_fs_mount_point g_mp_sys_dev_bdvd{"", 2048, 65536, lv2_mp_flag::read_only + lv2_mp_flag::no_uid_gid};
|
lv2_fs_mount_point g_mp_sys_dev_bdvd{"", 2048, 0x4D955, 65536, lv2_mp_flag::read_only + lv2_mp_flag::no_uid_gid};
|
||||||
lv2_fs_mount_point g_mp_sys_dev_dvd{"", 2048, 32768, lv2_mp_flag::read_only + lv2_mp_flag::no_uid_gid};
|
lv2_fs_mount_point g_mp_sys_dev_dvd{"", 2048, 0x100, 32768, lv2_mp_flag::read_only + lv2_mp_flag::no_uid_gid};
|
||||||
lv2_fs_mount_point g_mp_sys_host_root{"", 512, 512, lv2_mp_flag::strict_get_block_size + lv2_mp_flag::no_uid_gid};
|
lv2_fs_mount_point g_mp_sys_host_root{"", 512, 0x100, 512, lv2_mp_flag::strict_get_block_size + lv2_mp_flag::no_uid_gid};
|
||||||
lv2_fs_mount_point g_mp_sys_dev_flash{"", 512, 8192, lv2_mp_flag::read_only + lv2_mp_flag::no_uid_gid};
|
lv2_fs_mount_point g_mp_sys_dev_flash{"", 512, 0x63E00, 8192, lv2_mp_flag::read_only + lv2_mp_flag::no_uid_gid};
|
||||||
lv2_fs_mount_point g_mp_sys_dev_flash2{ "", 512, 8192, lv2_mp_flag::no_uid_gid }; // TODO confirm
|
lv2_fs_mount_point g_mp_sys_dev_flash2{"", 512, 0x8000, 8192, lv2_mp_flag::no_uid_gid}; // TODO confirm
|
||||||
lv2_fs_mount_point g_mp_sys_dev_flash3{ "", 512, 8192, lv2_mp_flag::read_only + lv2_mp_flag::no_uid_gid }; // TODO confirm
|
lv2_fs_mount_point g_mp_sys_dev_flash3{"", 512, 0x400, 8192, lv2_mp_flag::read_only + lv2_mp_flag::no_uid_gid}; // TODO confirm
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void fmt_class_string<lv2_file_type>::format(std::string& out, u64 arg)
|
void fmt_class_string<lv2_file_type>::format(std::string& out, u64 arg)
|
||||||
|
@ -524,7 +524,7 @@ fs::file lv2_file::make_view(const std::shared_ptr<lv2_file>& _file, u64 offset)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<CellError, std::string_view> translate_to_sv(vm::cptr<char> ptr)
|
std::pair<CellError, std::string_view> translate_to_sv(vm::cptr<char> ptr, bool is_path = true)
|
||||||
{
|
{
|
||||||
const u32 addr = ptr.addr();
|
const u32 addr = ptr.addr();
|
||||||
|
|
||||||
|
@ -553,7 +553,7 @@ std::pair<CellError, std::string_view> translate_to_sv(vm::cptr<char> ptr)
|
||||||
return {CELL_EFAULT, path};
|
return {CELL_EFAULT, path};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!path.starts_with("/"sv))
|
if (is_path && !path.starts_with("/"sv))
|
||||||
{
|
{
|
||||||
return {CELL_ENOENT, path};
|
return {CELL_ENOENT, path};
|
||||||
}
|
}
|
||||||
|
@ -3008,17 +3008,52 @@ error_code sys_fs_mount(ppu_thread&, vm::cptr<char> dev_name, vm::cptr<char> fil
|
||||||
return { path_error, vpath };
|
return { path_error, vpath };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto [fs_error, filesystem] = translate_to_sv(file_system, false);
|
||||||
|
|
||||||
|
if (fs_error)
|
||||||
|
{
|
||||||
|
return { fs_error, filesystem };
|
||||||
|
}
|
||||||
|
|
||||||
const auto mp = lv2_fs_object::get_mp(vpath);
|
const auto mp = lv2_fs_object::get_mp(vpath);
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
|
||||||
|
auto vfs_mount = [&](std::string mount_path)
|
||||||
|
{
|
||||||
|
const u64 file_size = filesystem == "CELL_FS_SIMPLEFS" ? mp->sector_size * mp->sector_count : 0;
|
||||||
|
if (!mount_path.ends_with('/'))
|
||||||
|
mount_path += '/';
|
||||||
|
if (!fs::is_dir(mount_path) && !fs::create_dir(mount_path))
|
||||||
|
{
|
||||||
|
sys_fs.error("Failed to create directory \"%s\"", mount_path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (file_size > 0)
|
||||||
|
{
|
||||||
|
mount_path += "loop.tmp";
|
||||||
|
fs::file loop_file;
|
||||||
|
if (loop_file.open(mount_path, fs::create + fs::read + fs::write + fs::trunc + fs::lock))
|
||||||
|
{
|
||||||
|
loop_file.trunc(file_size);
|
||||||
|
sys_fs.notice("Created a loop file of size %d at \"%s\"", file_size, mount_path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sys_fs.error("Failed to create loop file \"%s\"", mount_path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vfs::mount(vpath, mount_path, file_size == 0);
|
||||||
|
};
|
||||||
|
|
||||||
if (mp == &g_mp_sys_dev_hdd1)
|
if (mp == &g_mp_sys_dev_hdd1)
|
||||||
{
|
{
|
||||||
const std::string_view appname = g_ps3_process_info.get_cellos_appname();
|
const std::string_view appname = g_ps3_process_info.get_cellos_appname();
|
||||||
success = vfs::mount(vpath, fmt::format("%s/caches/%s", lv2_fs_object::get_vfs(vpath), appname.substr(0, appname.find_last_of('.'))), true);
|
success = vfs_mount(fmt::format("%s/caches/%s", lv2_fs_object::get_vfs(vpath), appname.substr(0, appname.find_last_of('.'))));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//success = vfs::mount(vpath, lv2_fs_object::get_vfs(vpath)); // We are not supporting mounting devices other than /dev_hdd1 via this syscall currently
|
//success = vfs_mount(lv2_fs_object::get_vfs(vpath)); // We are not supporting mounting devices other than /dev_hdd1 via this syscall currently
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
|
@ -3043,9 +3078,29 @@ error_code sys_fs_unmount(ppu_thread&, vm::cptr<char> path, s32 unk1, s32 unk2)
|
||||||
return { path_error, vpath };
|
return { path_error, vpath };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto mp = lv2_fs_object::get_mp(vpath);
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
|
||||||
//success = vfs::unmount(vpath); // Not really unmounting it at the moment
|
auto vfs_unmount = [&]()
|
||||||
|
{
|
||||||
|
const std::string local_path = vfs::get(vpath);
|
||||||
|
if (fs::is_file(local_path))
|
||||||
|
{
|
||||||
|
if (fs::remove_file(local_path))
|
||||||
|
{
|
||||||
|
sys_fs.notice("Removed loop file \"%s\"", local_path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sys_fs.error("Failed to remove loop file \"%s\"", local_path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vfs::unmount(vpath);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (mp == &g_mp_sys_dev_hdd1) // We are not supporting unmounting devices other than /dev_hdd1 via this syscall currently
|
||||||
|
success = vfs_unmount();
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
return CELL_EIO;
|
return CELL_EIO;
|
||||||
|
|
|
@ -149,6 +149,7 @@ struct lv2_fs_mount_point
|
||||||
{
|
{
|
||||||
const std::string_view root;
|
const std::string_view root;
|
||||||
const u32 sector_size = 512;
|
const u32 sector_size = 512;
|
||||||
|
const u64 sector_count = 256;
|
||||||
const u32 block_size = 4096;
|
const u32 block_size = 4096;
|
||||||
const bs_t<lv2_mp_flag> flags{};
|
const bs_t<lv2_mp_flag> flags{};
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ struct vfs_manager
|
||||||
vfs_directory root{};
|
vfs_directory root{};
|
||||||
};
|
};
|
||||||
|
|
||||||
bool vfs::mount(std::string_view vpath, std::string_view path, bool create_dir, bool is_dir)
|
bool vfs::mount(std::string_view vpath, std::string_view path, bool is_dir)
|
||||||
{
|
{
|
||||||
if (vpath.empty())
|
if (vpath.empty())
|
||||||
{
|
{
|
||||||
|
@ -42,12 +42,6 @@ bool vfs::mount(std::string_view vpath, std::string_view path, bool create_dir,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (create_dir && !fs::is_dir(std::string(path)) && !fs::create_dir(std::string(path)))
|
|
||||||
{
|
|
||||||
vfs_log.error("Cannot create directory \"%s\"", path);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Workaround
|
// Workaround
|
||||||
g_fxo->need<vfs_manager>();
|
g_fxo->need<vfs_manager>();
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ struct vfs_directory;
|
||||||
namespace vfs
|
namespace vfs
|
||||||
{
|
{
|
||||||
// Mount VFS device
|
// Mount VFS device
|
||||||
bool mount(std::string_view vpath, std::string_view path, bool create_dir = false, bool is_dir = true);
|
bool mount(std::string_view vpath, std::string_view path, bool is_dir = true);
|
||||||
|
|
||||||
// Unmount VFS device
|
// Unmount VFS device
|
||||||
bool unmount(std::string_view vpath);
|
bool unmount(std::string_view vpath);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue