From d5f095755872afb2a49c49ced419e7d1fb6eebe5 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sat, 4 Jan 2020 23:12:46 +0300 Subject: [PATCH] Implement lv2_fs_mount_point with mount point flags Implement some actual mount points Implement lv2_mp_flag::no_uid_gid --- rpcs3/Emu/Cell/lv2/sys_fs.cpp | 57 +++++++++++++++++++++++------------ rpcs3/Emu/Cell/lv2/sys_fs.h | 30 ++++++++++-------- 2 files changed, 54 insertions(+), 33 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.cpp b/rpcs3/Emu/Cell/lv2/sys_fs.cpp index 9b4732174d..a7b39ef1c2 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_fs.cpp @@ -2,8 +2,6 @@ #include "sys_sync.h" #include "sys_fs.h" -#include - #include "Emu/Cell/PPUThread.h" #include "Crypto/unedat.h" #include "Emu/VFS.h" @@ -14,15 +12,17 @@ LOG_CHANNEL(sys_fs); struct lv2_fs_mount_point { - std::mutex mutex; + const bs_t flags{}; + + shared_mutex mutex; }; lv2_fs_mount_point g_mp_sys_dev_hdd0; -lv2_fs_mount_point g_mp_sys_dev_hdd1; -lv2_fs_mount_point g_mp_sys_dev_usb; -lv2_fs_mount_point g_mp_sys_dev_bdvd; +lv2_fs_mount_point g_mp_sys_dev_hdd1{lv2_mp_flag::no_uid_gid}; +lv2_fs_mount_point g_mp_sys_dev_usb{lv2_mp_flag::no_uid_gid}; +lv2_fs_mount_point g_mp_sys_dev_bdvd{lv2_mp_flag::read_only + lv2_mp_flag::no_uid_gid}; lv2_fs_mount_point g_mp_sys_app_home; -lv2_fs_mount_point g_mp_sys_host_root; +lv2_fs_mount_point g_mp_sys_host_root{lv2_mp_flag::no_uid_gid}; bool verify_mself(u32 fd, fs::file const& mself_file) { @@ -57,9 +57,27 @@ bool verify_mself(u32 fd, fs::file const& mself_file) return true; } -lv2_fs_mount_point* lv2_fs_object::get_mp(const char* filename) +lv2_fs_mount_point* lv2_fs_object::get_mp(std::string_view filename) { - // TODO + const auto mp_begin = filename.find_first_not_of('/'); + + if (mp_begin + 1) + { + const auto mp_name = filename.substr(mp_begin, filename.find_first_of('/', mp_begin)); + + if (mp_name == "dev_hdd1"sv) + return &g_mp_sys_dev_hdd1; + if (mp_name.substr(0, 7) == "dev_usb"sv) + return &g_mp_sys_dev_usb; + if (mp_name == "dev_bdvd"sv) + return &g_mp_sys_dev_bdvd; + if (mp_name == "app_home"sv) + return &g_mp_sys_app_home; + if (mp_name == "host_root"sv) + return &g_mp_sys_host_root; + } + + // Default return &g_mp_sys_dev_hdd0; } @@ -370,7 +388,7 @@ error_code sys_fs_open(ppu_thread& ppu, vm::cptr path, s32 flags, vm::ptr< } } - if (const u32 id = idm::make(processed_path.c_str(), std::move(file), mode, flags)) + if (const u32 id = idm::make(processed_path, std::move(file), mode, flags)) { *fd = id; return CELL_OK; @@ -572,7 +590,7 @@ error_code sys_fs_opendir(ppu_thread& ppu, vm::cptr path, vm::ptr fd) data.erase(last, data.end()); - if (const u32 id = idm::make(processed_path.c_str(), std::move(data))) + if (const u32 id = idm::make(processed_path, std::move(data))) { *fd = id; return CELL_OK; @@ -695,10 +713,11 @@ error_code sys_fs_stat(ppu_thread& ppu, vm::cptr path, vm::ptr } } - const bool supports_id = vpath.size() < (first_name_ch + 8) || !vpath.compare(first_name_ch, 8, "dev_hdd1"sv); // TODO + const auto mp = lv2_fs_object::get_mp(vpath); + sb->mode = info.is_directory ? CELL_FS_S_IFDIR | 0777 : CELL_FS_S_IFREG | 0666; - sb->uid = supports_id ? 0 : -1; - sb->gid = supports_id ? 0 : -1; + sb->uid = mp->flags & lv2_mp_flag::no_uid_gid ? -1 : 0; + sb->gid = mp->flags & lv2_mp_flag::no_uid_gid ? -1 : 0; sb->atime = info.atime; sb->mtime = info.mtime; sb->ctime = info.ctime; @@ -730,10 +749,9 @@ error_code sys_fs_fstat(ppu_thread& ppu, u32 fd, vm::ptr sb) const fs::stat_t& info = file->file.stat(); - const bool supports_id = std::memcmp("/dev_hdd1", file->name.data(), 9) != 0; // TODO sb->mode = info.is_directory ? CELL_FS_S_IFDIR | 0777 : CELL_FS_S_IFREG | 0666; - sb->uid = supports_id ? 0 : -1; - sb->gid = supports_id ? 0 : -1; + sb->uid = file->mp->flags & lv2_mp_flag::no_uid_gid ? -1 : 0; + sb->gid = file->mp->flags & lv2_mp_flag::no_uid_gid ? -1 : 0; sb->atime = info.atime; sb->mtime = info.mtime; sb->ctime = info.ctime; // ctime may be incorrect @@ -1233,10 +1251,9 @@ error_code sys_fs_fcntl(ppu_thread& ppu, u32 fd, u32 op, vm::ptr _arg, u32 { auto& entry = arg->ptr[arg->_size++]; - const bool supports_id = std::memcmp("/dev_hdd1", directory->name.data(), 9) != 0; // TODO entry.attribute.mode = info->is_directory ? CELL_FS_S_IFDIR | 0777 : CELL_FS_S_IFREG | 0666; - entry.attribute.uid = supports_id ? 0 : -1; - entry.attribute.gid = supports_id ? 0 : -1; + entry.attribute.uid = directory->mp->flags & lv2_mp_flag::no_uid_gid ? -1 : 0; + entry.attribute.gid = directory->mp->flags & lv2_mp_flag::no_uid_gid ? -1 : 0; entry.attribute.atime = info->atime; entry.attribute.mtime = info->mtime; entry.attribute.ctime = info->ctime; diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.h b/rpcs3/Emu/Cell/lv2/sys_fs.h index 951740f36c..0794203e72 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.h +++ b/rpcs3/Emu/Cell/lv2/sys_fs.h @@ -121,6 +121,14 @@ struct FsMselfEntry struct lv2_fs_mount_point; +enum class lv2_mp_flag +{ + read_only, + no_uid_gid, + + __bitset_enum_max +}; + struct lv2_fs_object { using id_type = lv2_fs_object; @@ -135,29 +143,25 @@ struct lv2_fs_object // File Name (max 1055) const std::array name; - lv2_fs_object(lv2_fs_mount_point* mp, const char* filename) + lv2_fs_object(lv2_fs_mount_point* mp, std::string_view filename) : mp(mp) , name(get_name(filename)) { } - static lv2_fs_mount_point* get_mp(const char* filename); + static lv2_fs_mount_point* get_mp(std::string_view filename); - static std::array get_name(const char* filename) + static std::array get_name(std::string_view filename) { std::array name; - for (auto& c : name) + if (filename.size() >= 0x420) { - c = *filename++; - - if (!c) - { - return name; - } + filename = filename.substr(0, 0x420 - 1); } - name.back() = 0; + filename.copy(name.data(), filename.size()); + name[filename.size()] = 0; return name; } }; @@ -171,7 +175,7 @@ struct lv2_file final : lv2_fs_object // Stream lock atomic_t lock{0}; - lv2_file(const char* filename, fs::file&& file, s32 mode, s32 flags) + lv2_file(std::string_view filename, fs::file&& file, s32 mode, s32 flags) : lv2_fs_object(lv2_fs_object::get_mp(filename), filename) , file(std::move(file)) , mode(mode) @@ -207,7 +211,7 @@ struct lv2_dir final : lv2_fs_object // Current reading position atomic_t pos{0}; - lv2_dir(const char* filename, std::vector&& entries) + lv2_dir(std::string_view filename, std::vector&& entries) : lv2_fs_object(lv2_fs_object::get_mp(filename), filename) , entries(std::move(entries)) {