Prepared Directory for normal and PFS

Removed Quasi Logger (recoded for shad's)
Fixed QFS::Op::Truncate segfaulting
This commit is contained in:
Marek Ledworowski 2025-10-26 16:57:54 +01:00
parent c328815591
commit cd49b6b1e1
29 changed files with 170 additions and 112 deletions

View File

@ -666,9 +666,9 @@ set(DEV_TOOLS src/core/devtools/layer.cpp
set(QUASIFS src/core/file_sys/quasifs/src/quasifs.cpp
src/core/file_sys/quasifs/src/quasifs_vdriver.cpp
src/core/file_sys/quasifs/src/quasifs_inode_device.cpp
src/core/file_sys/quasifs/src/quasifs_inode_directory.cpp
src/core/file_sys/quasifs/src/quasifs_inode_regularfile.cpp
src/core/file_sys/quasifs/src/quasifs_inode_quasi_device.cpp
src/core/file_sys/quasifs/src/quasifs_inode_quasi_directory.cpp
src/core/file_sys/quasifs/src/quasifs_inode_quasi_file.cpp
src/core/file_sys/quasifs/src/quasifs_inode_virtualfile.cpp
src/core/file_sys/quasifs/src/quasifs_inode_symlink.cpp
src/core/file_sys/quasifs/src/quasifs_partition.cpp

View File

@ -3,7 +3,15 @@
#pragma once
#include "core/file_sys/quasifs/quasifs_inode_device.h"
#include "common/logging/log.h"
#include "core/file_sys/quasifs/quasifs_inode_quasi_device.h"
#define DEVICE_STUB() \
{ \
LOG_ERROR(Kernel_Fs, "(STUBBED) called"); \
return -QUASI_ENOSYS; \
}
namespace Core::Devices {

View File

@ -4,7 +4,15 @@
#pragma once
#include <memory>
#include "core/file_sys/quasifs/quasifs_inode_device.h"
#include "common/logging/log.h"
#include "core/file_sys/quasifs/quasifs_inode_quasi_device.h"
#define DEVICE_STUB() \
{ \
LOG_ERROR(Kernel_Fs, "(STUBBED) called"); \
return -QUASI_ENOSYS; \
}
namespace Core::Devices {

View File

@ -7,7 +7,15 @@
#include <string>
#include <vector>
#include "core/file_sys/quasifs/quasifs_inode_device.h"
#include "common/logging/log.h"
#include "core/file_sys/quasifs/quasifs_inode_quasi_device.h"
#define DEVICE_STUB() \
{ \
LOG_ERROR(Kernel_Fs, "(STUBBED) called"); \
return -QUASI_ENOSYS; \
}
namespace Core::Devices {

View File

@ -3,7 +3,15 @@
#pragma once
#include "core/file_sys/quasifs/quasifs_inode_device.h"
#include "common/logging/log.h"
#include "core/file_sys/quasifs/quasifs_inode_quasi_device.h"
#define DEVICE_STUB() \
{ \
LOG_ERROR(Kernel_Fs, "(STUBBED) called"); \
return -QUASI_ENOSYS; \
}
namespace Core::Devices {

View File

@ -5,7 +5,15 @@
#include <cstring>
#include "core/file_sys/quasifs/quasifs_inode_device.h"
#include "common/logging/log.h"
#include "core/file_sys/quasifs/quasifs_inode_quasi_device.h"
#define DEVICE_STUB() \
{ \
LOG_ERROR(Kernel_Fs, "(STUBBED) called"); \
return -QUASI_ENOSYS; \
}
namespace Core::Devices {

View File

@ -27,15 +27,11 @@ s64 RandomDevice::write(const void* buf, u64 count) {
}
s64 RandomDevice::pread(void* buf, u64 count, u64 offset) {
auto rbuf = static_cast<char*>(buf);
for (size_t i = 0; i < count; i++) {
rbuf[i] = std::rand() & 0xFF;
}
return count;
return read(buf, count);
}
s64 RandomDevice::pwrite(const void* buf, u64 count, u64 offset) {
return count;
return write(buf, count);
}
} // namespace Core::Devices

View File

@ -5,7 +5,15 @@
#include <memory>
#include "core/file_sys/quasifs/quasifs_inode_device.h"
#include "common/logging/log.h"
#include "core/file_sys/quasifs/quasifs_inode_quasi_device.h"
#define DEVICE_STUB() \
{ \
LOG_ERROR(Kernel_Fs, "(STUBBED) called"); \
return -QUASI_ENOSYS; \
}
namespace Core::Devices {
@ -15,9 +23,9 @@ public:
~RandomDevice();
s64 read(void* buf, u64 count) override;
s64 write(const void* buf, u64 count) override ;
s64 write(const void* buf, u64 count) override;
s64 pread(void* buf, size_t count, u64 offset) override;
s64 pwrite(const void* buf, size_t count, u64 offset) override ;
s64 pwrite(const void* buf, size_t count, u64 offset) override;
// clang-format off
s32 ioctl(u64 cmd, Common::VaCtx* args) override { DEVICE_STUB(); }

View File

@ -5,7 +5,15 @@
#include <memory>
#include "core/file_sys/quasifs/quasifs_inode_device.h"
#include "common/logging/log.h"
#include "core/file_sys/quasifs/quasifs_inode_quasi_device.h"
#define DEVICE_STUB() \
{ \
LOG_ERROR(Kernel_Fs, "(STUBBED) called"); \
return -QUASI_ENOSYS; \
}
namespace Core::Devices {

View File

@ -20,12 +20,11 @@ s64 ZeroDevice::write(const void* buf, u64 count) {
}
s64 ZeroDevice::pread(void* buf, size_t count, u64 offset) {
memset(buf, 0, count);
return count;
return read(buf, count);
}
s64 ZeroDevice::pwrite(const void* buf, size_t count, u64 offset) {
return count;
return write(buf, count);
}
} // namespace Core::Devices

View File

@ -3,9 +3,15 @@
#pragma once
#include <cstring>
#include "common/logging/log.h"
#include "core/file_sys/quasifs/quasifs_inode_device.h"
#include "core/file_sys/quasifs/quasifs_inode_quasi_device.h"
#define DEVICE_STUB() \
{ \
LOG_ERROR(Kernel_Fs, "(STUBBED) called"); \
return -QUASI_ENOSYS; \
}
namespace Core::Devices {

View File

@ -10,9 +10,9 @@
#include "../../quasifs/quasi_types.h"
#include "../../quasifs/quasifs_inode_device.h"
#include "../../quasifs/quasifs_inode_directory.h"
#include "../../quasifs/quasifs_inode_regularfile.h"
#include "../../quasifs/quasifs_inode_quasi_device.h"
#include "../../quasifs/quasifs_inode_quasi_directory.h"
#include "../../quasifs/quasifs_inode_quasi_file.h"
#include "../../quasifs/quasifs_inode_symlink.h"
#include "../../quasifs/quasifs_partition.h"

View File

@ -8,9 +8,9 @@
#include "../../quasifs/quasi_errno.h"
#include "../../quasifs/quasi_types.h"
#include "../../quasifs/quasifs_inode_device.h"
#include "../../quasifs/quasifs_inode_directory.h"
#include "../../quasifs/quasifs_inode_regularfile.h"
#include "../../quasifs/quasifs_inode_quasi_device.h"
#include "../../quasifs/quasifs_inode_quasi_directory.h"
#include "../../quasifs/quasifs_inode_quasi_file.h"
#include "../../quasifs/quasifs_inode_symlink.h"
#include "../../quasifs/quasifs_inode_virtualfile.h"
#include "../../quasifs/quasifs_partition.h"
@ -169,7 +169,7 @@ int HostIO_Virtual::Truncate(const fs::path& path, u64 size) {
if (!node->is_file())
return -QUASI_EINVAL;
return handle->node->ftruncate(size);
return node->ftruncate(size);
}
int HostIO_Virtual::FTruncate(const int fd, u64 size) {
@ -201,9 +201,9 @@ u64 HostIO_Virtual::LSeek(const int fd, u64 offset, QuasiFS::SeekOrigin origin)
auto ptr = &handle->pos;
u64 new_ptr = (SeekOrigin::ORIGIN == origin) * offset +
(SeekOrigin::CURRENT == origin) * (*(ptr) + offset) +
(SeekOrigin::END == origin) * (node->st.st_size + offset);
u64 new_ptr = ((SeekOrigin::ORIGIN == origin) * offset) +
((SeekOrigin::CURRENT == origin) * (*(ptr) + offset)) +
((SeekOrigin::END == origin) * (node->st.st_size + offset));
if (new_ptr < 0)
return -QUASI_EINVAL;

View File

@ -0,0 +1,8 @@
### Quick rundown
quasifs_inode_quasi_* - standalones/prototypes for more complex objects, i.e. turning regular directory into PFS directory or Partition into patchable partition
quasifs_inode_* - complex types, inode based
quasi_* - not interacting with FS directly
quasifs_vdriver - virtual driver for QFS, interfacing with HostIO

View File

@ -31,10 +31,12 @@ using inode_ptr = std::shared_ptr<Inode>;
class Partition;
using partition_ptr = std::shared_ptr<Partition>;
class QuasiFile;
using file_ptr = std::shared_ptr<QuasiFile>;
using RegularFile = QuasiFile;
using file_ptr = std::shared_ptr<RegularFile>;
class Symlink;
using symlink_ptr = std::shared_ptr<Symlink>;
class Directory;
class QuasiDirectory;
using Directory = QuasiDirectory;
using dir_ptr = std::shared_ptr<Directory>;
class Device;
using dev_ptr = std::shared_ptr<Device>;

View File

@ -9,7 +9,7 @@
#include "quasi_errno.h"
#include "quasi_types.h"
#include "quasifs_inode.h"
#include "quasifs_inode_directory.h"
#include "quasifs_inode_quasi_directory.h"
#include "quasifs_inode_symlink.h"
#include "../hostio/host_io.h"

View File

@ -3,17 +3,10 @@
#pragma once
#include "common/assert.h"
#include "common/logging/log.h"
#include "quasi_types.h"
#include "quasifs_inode.h"
#define DEVICE_STUB() \
{ \
LOG_ERROR(Kernel_Fs, "(STUBBED) called"); \
return -QUASI_ENOSYS; \
}
namespace QuasiFS {
class Device : public Inode {

View File

@ -5,22 +5,31 @@
#include <map>
#include <string>
#include "common/assert.h"
#include "quasi_types.h"
#include "quasifs_inode.h"
namespace QuasiFS {
// Directory
class Directory : public Inode {
class QuasiDirectory : public Inode {
public:
std::map<std::string, inode_ptr> entries{};
dir_ptr mounted_root = nullptr;
Directory();
~Directory() = default;
QuasiDirectory();
~QuasiDirectory() = default;
static dir_ptr Create(void) {
return std::make_shared<Directory>();
return std::make_shared<QuasiDirectory>();
}
template <typename T, typename... Args>
static file_ptr Create(Args&&... args) {
if constexpr (std::is_base_of_v<QuasiFile, T>)
return std::make_shared<T>(std::forward<Args>(args)...);
UNREACHABLE();
}
//

View File

@ -24,6 +24,12 @@ public:
return std::make_shared<T>(std::forward<Args>(args)...);
UNREACHABLE();
}
s64 read(void* buf, size_t count) override;
s64 write(const void* buf, size_t count) override;
s64 pread(void* buf, size_t count, u64 offset) override;
s64 pwrite(const void* buf, size_t count, u64 offset) override;
s32 ftruncate(s64 length) override;
};
} // namespace QuasiFS

View File

@ -1,26 +0,0 @@
// INAA License @marecl 2025
#pragma once
#include "quasi_types.h"
#include "quasifs_inode_file.h"
namespace QuasiFS {
class RegularFile final : public QuasiFile {
public:
RegularFile() = default;
~RegularFile() = default;
//
// Working functions
//
s64 read(void* buf, size_t count) override;
s64 write(const void* buf, size_t count) override;
s64 pread(void* buf, size_t count, u64 offset) override;
s64 pwrite(const void* buf, size_t count, u64 offset) override;
s32 ftruncate(s64 length) override;
};
} // namespace QuasiFS

View File

@ -5,7 +5,7 @@
#include "common/assert.h"
#include "quasi_types.h"
#include "quasifs_inode_file.h"
#include "quasifs_inode_quasi_file.h"
namespace QuasiFS {

View File

@ -5,8 +5,8 @@
#include "core/file_sys/quasifs/quasifs.h"
#include "core/file_sys/quasifs/quasifs_inode_directory.h"
#include "core/file_sys/quasifs/quasifs_inode_regularfile.h"
#include "core/file_sys/quasifs/quasifs_inode_quasi_directory.h"
#include "core/file_sys/quasifs/quasifs_inode_quasi_file.h"
#include "core/file_sys/quasifs/quasifs_inode_symlink.h"
#include "core/file_sys/quasifs/quasifs_inode_virtualfile.h"
#include "core/file_sys/quasifs/quasifs_partition.h"
@ -233,7 +233,7 @@ int QFS::Resolve(const fs::path& path, Resolved& res) {
if (path.empty())
return -QUASI_EINVAL;
if (path.is_relative())
return -QUASI_EBADF;
return -QUASI_EINVAL;
// on return:
// node - last element of the path (if exists)

View File

@ -1,6 +1,6 @@
// INAA License @marecl 2025
#include "core/file_sys/quasifs/quasifs_inode_device.h"
#include "core/file_sys/quasifs/quasifs_inode_quasi_device.h"
namespace QuasiFS {

View File

@ -4,22 +4,22 @@
#include <string>
#include "../quasi_errno.h"
#include "core/file_sys/quasifs/quasifs_inode_directory.h"
#include "core/file_sys/quasifs/quasifs_inode_quasi_directory.h"
namespace QuasiFS {
Directory::Directory() {
QuasiDirectory::QuasiDirectory() {
st.st_mode |= QUASI_S_IFDIR;
}
inode_ptr Directory::lookup(const std::string& name) {
inode_ptr QuasiDirectory::lookup(const std::string& name) {
auto it = entries.find(name);
if (it == entries.end())
return nullptr;
return it->second;
}
int Directory::link(const std::string& name, inode_ptr child) {
int QuasiDirectory::link(const std::string& name, inode_ptr child) {
if (name.empty())
return -QUASI_ENOENT;
if (entries.count(name))
@ -30,7 +30,7 @@ int Directory::link(const std::string& name, inode_ptr child) {
return 0;
}
int Directory::unlink(const std::string& name) {
int QuasiDirectory::unlink(const std::string& name) {
auto it = entries.find(name);
if (it == entries.end())
return -QUASI_ENOENT;
@ -38,7 +38,7 @@ int Directory::unlink(const std::string& name) {
inode_ptr target = it->second;
// if directory and not empty -> EBUSY or ENOTEMPTY
if (target->is_dir()) {
dir_ptr dir = std::static_pointer_cast<Directory>(target);
dir_ptr dir = std::static_pointer_cast<QuasiDirectory>(target);
auto children = dir->list();
children.erase(std::remove(children.begin(), children.end(), "."), children.end());
children.erase(std::remove(children.begin(), children.end(), ".."), children.end());
@ -57,7 +57,7 @@ int Directory::unlink(const std::string& name) {
return 0;
}
std::vector<std::string> Directory::list() {
std::vector<std::string> QuasiDirectory::list() {
std::vector<std::string> r;
for (auto& p : entries)
r.push_back(p.first);

View File

@ -3,26 +3,26 @@
#include <vector>
#include "../quasi_errno.h"
#include "core/file_sys/quasifs/quasifs_inode_regularfile.h"
#include "core/file_sys/quasifs/quasifs_inode_quasi_file.h"
namespace QuasiFS {
s64 RegularFile::read(void* buf, size_t count) {
s64 QuasiFile::read(void* buf, size_t count) {
return pread(buf, count, 0);
}
s64 RegularFile::write(const void* buf, size_t count) {
s64 QuasiFile::write(const void* buf, size_t count) {
return pwrite(buf, count, 0);
}
s64 RegularFile::pread(void* buf, size_t count, u64 offset) {
s64 QuasiFile::pread(void* buf, size_t count, u64 offset) {
auto size = &this->st.st_size;
auto end_pos = offset + count;
return end_pos > *size ? *size - offset : count;
}
s64 RegularFile::pwrite(const void* buf, size_t count, u64 offset) {
s64 QuasiFile::pwrite(const void* buf, size_t count, u64 offset) {
auto size = &this->st.st_size;
auto end_pos = offset + count;
@ -31,7 +31,7 @@ s64 RegularFile::pwrite(const void* buf, size_t count, u64 offset) {
return count;
}
s32 RegularFile::ftruncate(s64 length) {
s32 QuasiFile::ftruncate(s64 length) {
if (length < 0)
return -QUASI_EINVAL;
this->st.st_size = length;

View File

@ -3,8 +3,8 @@
#include "../quasi_errno.h"
#include "../quasi_types.h"
#include "core/file_sys/quasifs/quasifs_inode_directory.h"
#include "core/file_sys/quasifs/quasifs_inode_regularfile.h"
#include "core/file_sys/quasifs/quasifs_inode_quasi_directory.h"
#include "core/file_sys/quasifs/quasifs_inode_quasi_file.h"
#include "core/file_sys/quasifs/quasifs_inode_symlink.h"
#include "core/file_sys/quasifs/quasifs_partition.h"
@ -16,8 +16,8 @@ Partition::Partition() : Partition("", 0755, 512, 4096) {}
Partition::Partition(const fs::path& host_root, const int root_permissions, const u32 blocks_per_io,
const u32 ioblock_size)
: block_id(next_block_id++), host_root(host_root.lexically_normal()),
block_size(block_size), ioblock_size(ioblock_size) {
: block_id(next_block_id++), host_root(host_root.lexically_normal()), block_size(block_size),
ioblock_size(ioblock_size) {
this->root = Directory::Create();
// clear defaults, write
chmod(this->root, root_permissions);

View File

@ -7,8 +7,8 @@
#include "../quasi_types.h"
#include "core/file_sys/quasifs/quasifs.h"
#include "core/file_sys/quasifs/quasifs_inode_directory.h"
#include "core/file_sys/quasifs/quasifs_inode_regularfile.h"
#include "core/file_sys/quasifs/quasifs_inode_quasi_directory.h"
#include "core/file_sys/quasifs/quasifs_inode_quasi_file.h"
#include "core/file_sys/quasifs/quasifs_inode_symlink.h"
#include "core/file_sys/quasifs/quasifs_partition.h"
@ -36,12 +36,13 @@ int QFS::OperationImpl::Open(const fs::path& path, int flags, u16 mode) {
bool request_append = flags & QUASI_O_APPEND;
//
// Prioritize QFS permissions
// Host is (usually) more lenient
// Orbis-specific checks
// Universal checks are embedded into QFS
// Some of those are universal, but order matters (a lot)
//
if ((request_write || request_append) && qfs.IsPartitionRO(part))
return -QUASI_EROFS;
if ((flags & (QUASI_O_WRONLY | QUASI_O_RDWR)) == (QUASI_O_WRONLY | QUASI_O_RDWR))
return -QUASI_EINVAL;
// if it doesn't exist, check the parent
inode_ptr checked_node = nullptr == res.node ? parent_node : res.node;
@ -49,8 +50,11 @@ int QFS::OperationImpl::Open(const fs::path& path, int flags, u16 mode) {
if ((request_read && !checked_node->CanRead()) || (request_write && !checked_node->CanWrite()))
return -QUASI_EACCES;
if ((flags & (QUASI_O_WRONLY | QUASI_O_RDWR)) == (QUASI_O_WRONLY | QUASI_O_RDWR))
return -QUASI_EINVAL;
if ((request_write || request_append) && qfs.IsPartitionRO(part))
return -QUASI_EROFS;
if (flags & QUASI_O_DIRECTORY && flags & QUASI_O_CREAT)
return -QUASI_ENOTDIR;
//
// Proceed
@ -706,9 +710,12 @@ int QFS::OperationImpl::Stat(const fs::path& path, Libraries::Kernel::OrbisKerne
vio_stat.st_size = hio_stat.st_size;
vio_stat.st_blksize = hio_stat.st_blksize;
vio_stat.st_blocks = hio_stat.st_blocks;
vio_stat.st_atim = hio_stat.st_atim;
vio_stat.st_mtim = hio_stat.st_mtim;
vio_stat.st_ctim = hio_stat.st_ctim;
vio_stat.st_atim.tv_sec = hio_stat.st_atim.tv_sec;
vio_stat.st_atim.tv_nsec = hio_stat.st_atim.tv_nsec;
vio_stat.st_mtim.tv_sec = hio_stat.st_mtim.tv_sec;
vio_stat.st_mtim.tv_nsec = hio_stat.st_mtim.tv_nsec;
vio_stat.st_ctim.tv_sec = hio_stat.st_ctim.tv_sec;
vio_stat.st_ctim.tv_nsec = hio_stat.st_ctim.tv_nsec;
}
memcpy(statbuf, &vio_stat, sizeof(Libraries::Kernel::OrbisKernelStat));
@ -746,9 +753,12 @@ int QFS::OperationImpl::FStat(const s32 fd, Libraries::Kernel::OrbisKernelStat*
vio_stat.st_size = hio_stat.st_size;
vio_stat.st_blksize = hio_stat.st_blksize;
vio_stat.st_blocks = hio_stat.st_blocks;
vio_stat.st_atim = hio_stat.st_atim;
vio_stat.st_mtim = hio_stat.st_mtim;
vio_stat.st_ctim = hio_stat.st_ctim;
vio_stat.st_atim.tv_sec = hio_stat.st_atim.tv_sec;
vio_stat.st_atim.tv_nsec = hio_stat.st_atim.tv_nsec;
vio_stat.st_mtim.tv_sec = hio_stat.st_mtim.tv_sec;
vio_stat.st_mtim.tv_nsec = hio_stat.st_mtim.tv_nsec;
vio_stat.st_ctim.tv_sec = hio_stat.st_ctim.tv_sec;
vio_stat.st_ctim.tv_nsec = hio_stat.st_ctim.tv_nsec;
}
memcpy(statbuf, &vio_stat, sizeof(Libraries::Kernel::OrbisKernelStat));

View File

@ -1064,6 +1064,7 @@ void RegisterFileSystem(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("mqQMh1zPPT8", "libScePosix", 1, "libkernel", posix_fstat);
LIB_FUNCTION("mqQMh1zPPT8", "libkernel", 1, "libkernel", posix_fstat);
LIB_FUNCTION("kBwCPsYX-m4", "libkernel", 1, "libkernel", sceKernelFstat);
LIB_FUNCTION("ih4CD9-gghM", "libScePosix", 1, "libkernel", posix_ftruncate);
LIB_FUNCTION("ih4CD9-gghM", "libkernel", 1, "libkernel", posix_ftruncate);
LIB_FUNCTION("VW3TVZiM4-E", "libkernel", 1, "libkernel", sceKernelFtruncate);
LIB_FUNCTION("WlyEA-sLDf0", "libkernel", 1, "libkernel", sceKernelTruncate);

View File

@ -45,7 +45,7 @@
#include "core/file_sys/quasifs/quasi_sys_fcntl.h"
#include "core/file_sys/quasifs/quasifs.h"
#include "core/file_sys/quasifs/quasifs_inode_device.h"
#include "core/file_sys/quasifs/quasifs_inode_quasi_device.h"
#include "core/file_sys/quasifs/quasifs_partition.h"
#include "core/file_sys/devices/console_device.h"
@ -323,8 +323,6 @@ void Emulator::Run(std::filesystem::path file, const std::vector<std::string> ar
}
}
// Create stdin/stdout/stderr
Common::Singleton<FileSys::HandleTable>::Instance()->CreateStdHandles();
this->LoadFilesystem(game_folder, id);
// Initialize components