Implement lv2_fs_mount_point with mount point flags

Implement some actual mount points
Implement lv2_mp_flag::no_uid_gid
This commit is contained in:
Nekotekina 2020-01-04 23:12:46 +03:00
parent 7f09def94e
commit d5f0957558
2 changed files with 54 additions and 33 deletions

View file

@ -2,8 +2,6 @@
#include "sys_sync.h" #include "sys_sync.h"
#include "sys_fs.h" #include "sys_fs.h"
#include <mutex>
#include "Emu/Cell/PPUThread.h" #include "Emu/Cell/PPUThread.h"
#include "Crypto/unedat.h" #include "Crypto/unedat.h"
#include "Emu/VFS.h" #include "Emu/VFS.h"
@ -14,15 +12,17 @@ LOG_CHANNEL(sys_fs);
struct lv2_fs_mount_point struct lv2_fs_mount_point
{ {
std::mutex mutex; const bs_t<lv2_mp_flag> flags{};
shared_mutex mutex;
}; };
lv2_fs_mount_point g_mp_sys_dev_hdd0; 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_hdd1{lv2_mp_flag::no_uid_gid};
lv2_fs_mount_point g_mp_sys_dev_usb; 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_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_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) 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; 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; return &g_mp_sys_dev_hdd0;
} }
@ -370,7 +388,7 @@ error_code sys_fs_open(ppu_thread& ppu, vm::cptr<char> path, s32 flags, vm::ptr<
} }
} }
if (const u32 id = idm::make<lv2_fs_object, lv2_file>(processed_path.c_str(), std::move(file), mode, flags)) if (const u32 id = idm::make<lv2_fs_object, lv2_file>(processed_path, std::move(file), mode, flags))
{ {
*fd = id; *fd = id;
return CELL_OK; return CELL_OK;
@ -572,7 +590,7 @@ error_code sys_fs_opendir(ppu_thread& ppu, vm::cptr<char> path, vm::ptr<u32> fd)
data.erase(last, data.end()); data.erase(last, data.end());
if (const u32 id = idm::make<lv2_fs_object, lv2_dir>(processed_path.c_str(), std::move(data))) if (const u32 id = idm::make<lv2_fs_object, lv2_dir>(processed_path, std::move(data)))
{ {
*fd = id; *fd = id;
return CELL_OK; return CELL_OK;
@ -695,10 +713,11 @@ error_code sys_fs_stat(ppu_thread& ppu, vm::cptr<char> path, vm::ptr<CellFsStat>
} }
} }
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->mode = info.is_directory ? CELL_FS_S_IFDIR | 0777 : CELL_FS_S_IFREG | 0666;
sb->uid = supports_id ? 0 : -1; sb->uid = mp->flags & lv2_mp_flag::no_uid_gid ? -1 : 0;
sb->gid = supports_id ? 0 : -1; sb->gid = mp->flags & lv2_mp_flag::no_uid_gid ? -1 : 0;
sb->atime = info.atime; sb->atime = info.atime;
sb->mtime = info.mtime; sb->mtime = info.mtime;
sb->ctime = info.ctime; sb->ctime = info.ctime;
@ -730,10 +749,9 @@ error_code sys_fs_fstat(ppu_thread& ppu, u32 fd, vm::ptr<CellFsStat> sb)
const fs::stat_t& info = file->file.stat(); 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->mode = info.is_directory ? CELL_FS_S_IFDIR | 0777 : CELL_FS_S_IFREG | 0666;
sb->uid = supports_id ? 0 : -1; sb->uid = file->mp->flags & lv2_mp_flag::no_uid_gid ? -1 : 0;
sb->gid = supports_id ? 0 : -1; sb->gid = file->mp->flags & lv2_mp_flag::no_uid_gid ? -1 : 0;
sb->atime = info.atime; sb->atime = info.atime;
sb->mtime = info.mtime; sb->mtime = info.mtime;
sb->ctime = info.ctime; // ctime may be incorrect 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<void> _arg, u32
{ {
auto& entry = arg->ptr[arg->_size++]; 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.mode = info->is_directory ? CELL_FS_S_IFDIR | 0777 : CELL_FS_S_IFREG | 0666;
entry.attribute.uid = supports_id ? 0 : -1; entry.attribute.uid = directory->mp->flags & lv2_mp_flag::no_uid_gid ? -1 : 0;
entry.attribute.gid = supports_id ? 0 : -1; entry.attribute.gid = directory->mp->flags & lv2_mp_flag::no_uid_gid ? -1 : 0;
entry.attribute.atime = info->atime; entry.attribute.atime = info->atime;
entry.attribute.mtime = info->mtime; entry.attribute.mtime = info->mtime;
entry.attribute.ctime = info->ctime; entry.attribute.ctime = info->ctime;

View file

@ -121,6 +121,14 @@ struct FsMselfEntry
struct lv2_fs_mount_point; struct lv2_fs_mount_point;
enum class lv2_mp_flag
{
read_only,
no_uid_gid,
__bitset_enum_max
};
struct lv2_fs_object struct lv2_fs_object
{ {
using id_type = lv2_fs_object; using id_type = lv2_fs_object;
@ -135,29 +143,25 @@ struct lv2_fs_object
// File Name (max 1055) // File Name (max 1055)
const std::array<char, 0x420> name; const std::array<char, 0x420> 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) : mp(mp)
, name(get_name(filename)) , 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<char, 0x420> get_name(const char* filename) static std::array<char, 0x420> get_name(std::string_view filename)
{ {
std::array<char, 0x420> name; std::array<char, 0x420> name;
for (auto& c : name) if (filename.size() >= 0x420)
{ {
c = *filename++; filename = filename.substr(0, 0x420 - 1);
if (!c)
{
return name;
}
} }
name.back() = 0; filename.copy(name.data(), filename.size());
name[filename.size()] = 0;
return name; return name;
} }
}; };
@ -171,7 +175,7 @@ struct lv2_file final : lv2_fs_object
// Stream lock // Stream lock
atomic_t<u32> lock{0}; atomic_t<u32> 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) : lv2_fs_object(lv2_fs_object::get_mp(filename), filename)
, file(std::move(file)) , file(std::move(file))
, mode(mode) , mode(mode)
@ -207,7 +211,7 @@ struct lv2_dir final : lv2_fs_object
// Current reading position // Current reading position
atomic_t<u64> pos{0}; atomic_t<u64> pos{0};
lv2_dir(const char* filename, std::vector<fs::dir_entry>&& entries) lv2_dir(std::string_view filename, std::vector<fs::dir_entry>&& entries)
: lv2_fs_object(lv2_fs_object::get_mp(filename), filename) : lv2_fs_object(lv2_fs_object::get_mp(filename), filename)
, entries(std::move(entries)) , entries(std::move(entries))
{ {