Add support for mounting and unmounting CELL_FS_SIMPLEFS

This commit is contained in:
brian218 2022-10-31 21:59:02 +08:00 committed by Ivan
parent ecc194cb62
commit c7ced46707
4 changed files with 72 additions and 22 deletions

View file

@ -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;

View file

@ -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{};

View file

@ -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>();

View file

@ -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);