From 7df5d494dde3621514da5074c6061efa9e9d8b98 Mon Sep 17 00:00:00 2001 From: Marek Ledworowski Date: Tue, 11 Nov 2025 00:45:34 +0100 Subject: [PATCH] Added PFS dirents (WIP, throws nullptr exception on some tests) Delegated lseek to inode Corrected offset types Directories can spawn one of their own kind --- CMakeLists.txt | 6 -- src/core/file_sys/devices/console_device.h | 6 +- src/core/file_sys/devices/deci_tty6_device.h | 6 +- src/core/file_sys/devices/logger.h | 6 +- src/core/file_sys/devices/nop_device.h | 6 +- src/core/file_sys/devices/null_device.h | 6 +- src/core/file_sys/devices/random_device.h | 6 +- src/core/file_sys/devices/rng_device.h | 6 +- src/core/file_sys/devices/srandom_device.h | 6 +- src/core/file_sys/devices/zero_device.h | 6 +- src/core/file_sys/hostio/host_io_posix.h | 10 +- src/core/file_sys/hostio/host_io_virtual.h | 6 +- src/core/file_sys/hostio/host_io_win32.h | 2 +- src/core/file_sys/hostio/src/host_io_base.cpp | 6 +- src/core/file_sys/hostio/src/host_io_base.h | 6 +- .../file_sys/hostio/src/host_io_posix.cpp | 8 +- .../file_sys/hostio/src/host_io_virtual.cpp | 24 ++--- .../file_sys/hostio/src/host_io_win32.cpp | 2 +- src/core/file_sys/quasifs/quasi_types.h | 4 +- src/core/file_sys/quasifs/quasifs.h | 6 +- src/core/file_sys/quasifs/quasifs_inode.h | 2 +- .../quasifs/quasifs_inode_quasi_device.h | 7 +- .../quasifs/quasifs_inode_quasi_directory.h | 19 ++-- .../quasifs_inode_quasi_directory_pfs.h | 17 +++- .../quasifs/quasifs_inode_quasi_file.h | 9 +- .../quasifs_inode_quasi_file_virtual.h | 4 + .../quasifs/quasifs_inode_quasi_socket.h | 7 +- src/core/file_sys/quasifs/quasifs_partition.h | 26 +++-- src/core/file_sys/quasifs/src/quasifs.cpp | 11 +-- .../src/quasifs_inode_quasi_directory.cpp | 16 +-- .../src/quasifs_inode_quasi_directory_pfs.cpp | 97 ++++++++++++++----- .../quasifs/src/quasifs_inode_quasi_file.cpp | 6 ++ .../quasifs/src/quasifs_partition.cpp | 25 ++--- .../file_sys/quasifs/src/quasifs_vdriver.cpp | 11 ++- .../libraries/app_content/app_content.cpp | 5 +- src/core/libraries/kernel/file_system.cpp | 2 +- .../libraries/save_data/save_instance.cpp | 3 +- src/emulator.cpp | 27 +++--- 38 files changed, 257 insertions(+), 171 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 705d61c14..67d754e4b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -783,12 +783,6 @@ set(CORE src/core/aerolib/stubs.cpp src/core/aerolib/aerolib.h src/core/address_space.cpp src/core/address_space.h - src/core/file_sys/directories/base_directory.cpp - src/core/file_sys/directories/base_directory.h - src/core/file_sys/directories/normal_directory.cpp - src/core/file_sys/directories/normal_directory.h - src/core/file_sys/directories/pfs_directory.cpp - src/core/file_sys/directories/pfs_directory.h src/core/file_format/pfs.h src/core/file_format/psf.cpp src/core/file_format/psf.h diff --git a/src/core/file_sys/devices/console_device.h b/src/core/file_sys/devices/console_device.h index e83aa59a6..d1be2e9a2 100644 --- a/src/core/file_sys/devices/console_device.h +++ b/src/core/file_sys/devices/console_device.h @@ -22,11 +22,15 @@ public: ConsoleDevice(); ~ConsoleDevice(); + static QuasiFS::dev_ptr Create() { + return std::make_shared(); + } + // clang-format off s64 read(void* buf, u64 count) override { DEVICE_STUB(); }; s64 write(const void* buf, u64 count) override { DEVICE_STUB(); }; s32 ioctl(u64 cmd, Common::VaCtx* args) override { DEVICE_STUB(); }; - s64 lseek(s64 offset, int whence) override { DEVICE_STUB(); }; + s64 lseek(s64 current, s64 offset, s32 whence) override { DEVICE_STUB(); }; s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) override { DEVICE_STUB(); }; s32 fsync() override { DEVICE_STUB(); }; s32 ftruncate(s64 length) override { DEVICE_STUB(); }; diff --git a/src/core/file_sys/devices/deci_tty6_device.h b/src/core/file_sys/devices/deci_tty6_device.h index c488be716..7bbe5b955 100644 --- a/src/core/file_sys/devices/deci_tty6_device.h +++ b/src/core/file_sys/devices/deci_tty6_device.h @@ -22,11 +22,15 @@ public: DeciTty6Device(); ~DeciTty6Device(); + static QuasiFS::dev_ptr Create() { + return std::make_shared(); + } + // clang-format off s64 read(void* buf, u64 count) override { DEVICE_STUB(); }; s64 write(const void* buf, u64 count) override { DEVICE_STUB(); }; s32 ioctl(u64 cmd, Common::VaCtx* args) override { DEVICE_STUB(); }; - s64 lseek(s64 offset, int whence) override { DEVICE_STUB(); }; + s64 lseek(s64 current, s64 offset, s32 whence) override { DEVICE_STUB(); }; s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) override { DEVICE_STUB(); }; s32 fsync() override { DEVICE_STUB(); }; s32 ftruncate(s64 length) override { DEVICE_STUB(); }; diff --git a/src/core/file_sys/devices/logger.h b/src/core/file_sys/devices/logger.h index cf0d3dca7..3815e66ce 100644 --- a/src/core/file_sys/devices/logger.h +++ b/src/core/file_sys/devices/logger.h @@ -30,13 +30,17 @@ public: explicit Logger(std::string prefix, bool is_err); ~Logger(); + static QuasiFS::dev_ptr Create(std::string prefix, bool is_err) { + return std::make_shared(prefix, is_err); + } + s64 write(const void* buf, u64 nbytes) override; s32 fsync() override; // clang-format off s64 read(void* buf, u64 count) override { DEVICE_STUB(); }; s32 ioctl(u64 cmd, Common::VaCtx* args) override { DEVICE_STUB(); } - s64 lseek(s64 offset, int whence) override { DEVICE_STUB(); } + s64 lseek(s64 current, s64 offset, s32 whence) override { DEVICE_STUB(); } s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) override { DEVICE_STUB(); } s32 ftruncate(s64 length) override { DEVICE_STUB(); } s64 getdents(void* buf, u32 nbytes, s64 offset, s64* basep) override { DEVICE_STUB(); } diff --git a/src/core/file_sys/devices/nop_device.h b/src/core/file_sys/devices/nop_device.h index d43050457..d3a61c4d3 100644 --- a/src/core/file_sys/devices/nop_device.h +++ b/src/core/file_sys/devices/nop_device.h @@ -15,11 +15,15 @@ public: NopDevice() = default; ~NopDevice() = default; + static QuasiFS::dev_ptr Create() { + return std::make_shared(); + } + // clang-format off s64 read(void* buf, u64 count) override { return 0; }; s64 write(const void* buf, u64 count) override { return 0; }; s32 ioctl(u64 cmd, Common::VaCtx* args) override { return 0; }; - s64 lseek(s64 offset, int whence) override { return 0; }; + s64 lseek(s64 current, s64 offset, s32 whence) override { return 0; }; s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) override { return 0; }; s32 fsync() override { return 0; }; s32 ftruncate(s64 length) override { return 0; }; diff --git a/src/core/file_sys/devices/null_device.h b/src/core/file_sys/devices/null_device.h index cde48a13c..114a60dfa 100644 --- a/src/core/file_sys/devices/null_device.h +++ b/src/core/file_sys/devices/null_device.h @@ -21,12 +21,16 @@ public: NullDevice(); ~NullDevice(); + static QuasiFS::dev_ptr Create() { + return std::make_shared(); + } + s64 read(void* buf, u64 count) override; s64 write(const void* buf, u64 count) override; // clang-format off s32 ioctl(u64 cmd, Common::VaCtx* args) override { DEVICE_STUB(); } - s64 lseek(s64 offset, int whence) override { DEVICE_STUB(); } + s64 lseek(s64 current, s64 offset, s32 whence) override { DEVICE_STUB(); } s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) override { DEVICE_STUB(); } s32 fsync() override { DEVICE_STUB(); } s32 ftruncate(s64 length) override { DEVICE_STUB(); } diff --git a/src/core/file_sys/devices/random_device.h b/src/core/file_sys/devices/random_device.h index efe8ed804..87c1fb45f 100644 --- a/src/core/file_sys/devices/random_device.h +++ b/src/core/file_sys/devices/random_device.h @@ -20,12 +20,16 @@ public: RandomDevice(); ~RandomDevice(); + static QuasiFS::dev_ptr Create() { + return std::make_shared(); + } + s64 read(void* buf, u64 count) override; s64 write(const void* buf, u64 count) override; // clang-format off s32 ioctl(u64 cmd, Common::VaCtx* args) override { DEVICE_STUB(); } - s64 lseek(s64 offset, int whence) override { DEVICE_STUB(); } + s64 lseek(s64 current, s64 offset, s32 whence) override { DEVICE_STUB(); } s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) override { DEVICE_STUB(); } s32 fsync() override { DEVICE_STUB(); } s32 ftruncate(s64 length) override { DEVICE_STUB(); } diff --git a/src/core/file_sys/devices/rng_device.h b/src/core/file_sys/devices/rng_device.h index edaf69c2a..97b73fefb 100644 --- a/src/core/file_sys/devices/rng_device.h +++ b/src/core/file_sys/devices/rng_device.h @@ -21,12 +21,16 @@ public: RngDevice(); ~RngDevice(); + static QuasiFS::dev_ptr Create() { + return std::make_shared(); + } + s32 ioctl(u64 cmd, Common::VaCtx* args) override; // clang-format off s64 read(void* buf, u64 count) override { DEVICE_STUB(); } s64 write(const void* buf, u64 count) override { DEVICE_STUB(); } - s64 lseek(s64 offset, int whence) override { DEVICE_STUB(); } + s64 lseek(s64 current, s64 offset, s32 whence) override { DEVICE_STUB(); } s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) override { DEVICE_STUB(); } s32 fsync() override { DEVICE_STUB(); } s32 ftruncate(s64 length) override { DEVICE_STUB(); } diff --git a/src/core/file_sys/devices/srandom_device.h b/src/core/file_sys/devices/srandom_device.h index a4b72abe1..87956f7af 100644 --- a/src/core/file_sys/devices/srandom_device.h +++ b/src/core/file_sys/devices/srandom_device.h @@ -21,12 +21,16 @@ public: SRandomDevice(); ~SRandomDevice(); + static QuasiFS::dev_ptr Create() { + return std::make_shared(); + } + s64 read(void* buf, u64 count) override; s64 write(const void* buf, u64 count) override; // clang-format off s32 ioctl(u64 cmd, Common::VaCtx* args) override { DEVICE_STUB(); } - s64 lseek(s64 offset, int whence) override { DEVICE_STUB(); } + s64 lseek(s64 current, s64 offset, s32 whence) override { DEVICE_STUB(); } s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) override { DEVICE_STUB(); } s32 fsync() override { DEVICE_STUB(); } s32 ftruncate(s64 length) override { DEVICE_STUB(); } diff --git a/src/core/file_sys/devices/zero_device.h b/src/core/file_sys/devices/zero_device.h index 1eb9031e7..529de06d6 100644 --- a/src/core/file_sys/devices/zero_device.h +++ b/src/core/file_sys/devices/zero_device.h @@ -21,12 +21,16 @@ public: ZeroDevice(); ~ZeroDevice(); + static QuasiFS::dev_ptr Create() { + return std::make_shared(); + } + s64 read(void* buf, u64 count) override; s64 write(const void* buf, u64 count) override; // clang-format off s32 ioctl(u64 cmd, Common::VaCtx* args) override { DEVICE_STUB(); } - s64 lseek(s64 offset, int whence) override { DEVICE_STUB(); } + s64 lseek(s64 current, s64 offset, s32 whence) override { DEVICE_STUB(); } s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) override { DEVICE_STUB(); } s32 fsync() override { DEVICE_STUB(); } s32 ftruncate(s64 length) override { DEVICE_STUB(); } diff --git a/src/core/file_sys/hostio/host_io_posix.h b/src/core/file_sys/hostio/host_io_posix.h index 0294f784c..a187e1a88 100644 --- a/src/core/file_sys/hostio/host_io_posix.h +++ b/src/core/file_sys/hostio/host_io_posix.h @@ -31,8 +31,8 @@ public: // Conversion helpers // - static constexpr s32 ToPOSIXSeekOrigin(QuasiFS::SeekOrigin origin) { - switch (origin) { + static constexpr s32 ToPOSIXSeekOrigin(s32 whence) { + switch (whence) { case QuasiFS::SeekOrigin::ORIGIN: return SEEK_SET; case QuasiFS::SeekOrigin::CURRENT: @@ -94,19 +94,19 @@ public: s32 Flush(const s32 fd) override; s32 FSync(const s32 fd) override; - s64 LSeek(const s32 fd, u64 offset, QuasiFS::SeekOrigin origin) override; + s64 LSeek(const s32 fd, s64 offset, s32 whence) override; s64 Tell(const s32 fd) override; s32 Truncate(const fs::path& path, u64 size) override; s32 FTruncate(const s32 fd, u64 size) override; s64 Read(const s32 fd, void* buf, u64 count) override; - s64 PRead(const s32 fd, void* buf, u64 count, u64 offset) override; + s64 PRead(const s32 fd, void* buf, u64 count, s64 offset) override; s64 ReadV(const s32 fd, OrbisKernelIovec* iov, u32 iovcnt) override; s64 PReadV(const s32 fd, OrbisKernelIovec* iov, u32 iovcnt, s64 offset) override; s64 Write(const s32 fd, const void* buf, u64 count) override; - s64 PWrite(const s32 fd, const void* buf, u64 count, u64 offset) override; + s64 PWrite(const s32 fd, const void* buf, u64 count, s64 offset) override; s64 WriteV(const s32 fd, const OrbisKernelIovec* iov, u32 iovcnt) override; s64 PWriteV(const s32 fd, const OrbisKernelIovec* iov, u32 iovcnt, s64 offset) override; diff --git a/src/core/file_sys/hostio/host_io_virtual.h b/src/core/file_sys/hostio/host_io_virtual.h index c725d66dd..f88380343 100644 --- a/src/core/file_sys/hostio/host_io_virtual.h +++ b/src/core/file_sys/hostio/host_io_virtual.h @@ -55,19 +55,19 @@ public: s32 Flush(const s32 fd) override; s32 FSync(const s32 fd) override; - s64 LSeek(const s32 fd, u64 offset, QuasiFS::SeekOrigin origin) override; + s64 LSeek(const s32 fd, s64 offset, s32 whence) override; s64 Tell(const s32 fd) override; s32 Truncate(const fs::path& path, u64 size) override; s32 FTruncate(const s32 fd, u64 size) override; s64 Read(const s32 fd, void* buf, u64 count) override; - s64 PRead(const s32 fd, void* buf, u64 count, u64 offset) override; + s64 PRead(const s32 fd, void* buf, u64 count, s64 offset) override; s64 ReadV(const s32 fd, OrbisKernelIovec* iov, u32 iovcnt) override; s64 PReadV(const s32 fd, OrbisKernelIovec* iov, u32 iovcnt, s64 offset) override; s64 Write(const s32 fd, const void* buf, u64 count) override; - s64 PWrite(const s32 fd, const void* buf, u64 count, u64 offset) override; + s64 PWrite(const s32 fd, const void* buf, u64 count, s64 offset) override; s64 WriteV(const s32 fd, const OrbisKernelIovec* iov, u32 iovcnt) override; s64 PWriteV(const s32 fd, const OrbisKernelIovec* iov, u32 iovcnt, s64 offset) override; diff --git a/src/core/file_sys/hostio/host_io_win32.h b/src/core/file_sys/hostio/host_io_win32.h index 7150eff23..b8ca70cc5 100644 --- a/src/core/file_sys/hostio/host_io_win32.h +++ b/src/core/file_sys/hostio/host_io_win32.h @@ -85,7 +85,7 @@ public: s32 Flush(const s32 fd) override; s32 FSync(const s32 fd) override; - s64 LSeek(const s32 fd, u64 offset, QuasiFS::SeekOrigin origin) override; + s64 LSeek(const s32 fd, u64 offset, s32 whence) override; s64 Tell(const s32 fd) override; s32 Truncate(const fs::path& path, u64 size) override; diff --git a/src/core/file_sys/hostio/src/host_io_base.cpp b/src/core/file_sys/hostio/src/host_io_base.cpp index 02b6092e6..a8396e39a 100644 --- a/src/core/file_sys/hostio/src/host_io_base.cpp +++ b/src/core/file_sys/hostio/src/host_io_base.cpp @@ -26,20 +26,20 @@ s32 HostIO_Base::LinkSymbolic(const fs::path& src, const fs::path& dst) { STUB() s32 HostIO_Base::Flush(const s32 fd) { STUB(); } s32 HostIO_Base::FSync(const s32 fd) { STUB(); } -s64 HostIO_Base::LSeek(const s32 fd, u64 offset, QuasiFS::SeekOrigin origin) { STUB(); } +s64 HostIO_Base::LSeek(const s32 fd, s64 offset, s32 whence) { STUB(); } s64 HostIO_Base::Tell(const s32 fd) { STUB(); } s32 HostIO_Base::Truncate(const fs::path& path, u64 size) { STUB(); } s32 HostIO_Base::FTruncate(const s32 fd, u64 size) { STUB(); } s64 HostIO_Base::Read(const s32 fd, void* buf, u64 count) { STUB(); } -s64 HostIO_Base::PRead(const s32 fd, void* buf, u64 count, u64 offset) { STUB(); } +s64 HostIO_Base::PRead(const s32 fd, void* buf, u64 count, s64 offset) { STUB(); } s64 HostIO_Base::ReadV(const s32 fd, OrbisKernelIovec* iov, u32 iovcnt) { STUB(); } s64 HostIO_Base::PReadV(const s32 fd, OrbisKernelIovec* iov, u32 iovcnt, s64 offset) { STUB(); } s64 HostIO_Base::Write(const s32 fd, const void* buf, u64 count) { STUB(); } -s64 HostIO_Base::PWrite(const s32 fd, const void* buf, u64 count, u64 offset) { STUB(); } +s64 HostIO_Base::PWrite(const s32 fd, const void* buf, u64 count, s64 offset) { STUB(); } s64 HostIO_Base::WriteV(const s32 fd, const OrbisKernelIovec* iov, u32 iovcnt) { STUB(); } s64 HostIO_Base::PWriteV(const s32 fd, const OrbisKernelIovec* iov, u32 iovcnt, s64 offset) { STUB(); } diff --git a/src/core/file_sys/hostio/src/host_io_base.h b/src/core/file_sys/hostio/src/host_io_base.h index 639e1a93d..34ca4679c 100644 --- a/src/core/file_sys/hostio/src/host_io_base.h +++ b/src/core/file_sys/hostio/src/host_io_base.h @@ -34,16 +34,16 @@ public: virtual s32 FSync(const s32 fd); virtual s32 Truncate(const fs::path& path, u64 size); virtual s32 FTruncate(const s32 fd, u64 size); - virtual s64 LSeek(const s32 fd, u64 offset, QuasiFS::SeekOrigin origin); + virtual s64 LSeek(const s32 fd, s64 offset, s32 whence); virtual s64 Tell(const s32 fd); virtual s64 Read(const s32 fd, void* buf, u64 count); - virtual s64 PRead(const s32 fd, void* buf, u64 count, u64 offset); + virtual s64 PRead(const s32 fd, void* buf, u64 count, s64 offset); virtual s64 ReadV(const s32 fd, OrbisKernelIovec* iov, u32 iovcnt); virtual s64 PReadV(const s32 fd, OrbisKernelIovec* iov, u32 iovcnt, s64 offset); virtual s64 Write(const s32 fd, const void* buf, u64 count); - virtual s64 PWrite(const s32 fd, const void* buf, u64 count, u64 offset); + virtual s64 PWrite(const s32 fd, const void* buf, u64 count, s64 offset); virtual s64 WriteV(const s32 fd, const OrbisKernelIovec* iov, u32 iovcnt); virtual s64 PWriteV(const s32 fd, const OrbisKernelIovec* iov, u32 iovcnt, s64 offset); diff --git a/src/core/file_sys/hostio/src/host_io_posix.cpp b/src/core/file_sys/hostio/src/host_io_posix.cpp index 71aab581e..5aa45765f 100644 --- a/src/core/file_sys/hostio/src/host_io_posix.cpp +++ b/src/core/file_sys/hostio/src/host_io_posix.cpp @@ -68,9 +68,9 @@ s32 HostIO_POSIX::FSync(const s32 fd) { return 0 == status ? status : -errno; } -s64 HostIO_POSIX::LSeek(const s32 fd, u64 offset, QuasiFS::SeekOrigin origin) { +s64 HostIO_POSIX::LSeek(const s32 fd, s64 offset, s32 whence) { errno = 0; - s32 status = lseek(fd, offset, ToPOSIXSeekOrigin(origin)); + s32 status = lseek(fd, offset, ToPOSIXSeekOrigin(whence)); return status >= 0 ? status : -errno; } @@ -96,7 +96,7 @@ s64 HostIO_POSIX::Read(const s32 fd, void* buf, u64 count) { return status >= 0 ? status : -errno; } -s64 HostIO_POSIX::PRead(const s32 fd, void* buf, u64 count, u64 offset) { +s64 HostIO_POSIX::PRead(const s32 fd, void* buf, u64 count, s64 offset) { errno = 0; s32 status = pread(fd, buf, count, offset); return status >= 0 ? status : -errno; @@ -134,7 +134,7 @@ s64 HostIO_POSIX::Write(const s32 fd, const void* buf, u64 count) { return status >= 0 ? status : -errno; } -s64 HostIO_POSIX::PWrite(const s32 fd, const void* buf, u64 count, u64 offset) { +s64 HostIO_POSIX::PWrite(const s32 fd, const void* buf, u64 count, s64 offset) { errno = 0; s32 status = pwrite(fd, buf, count, offset); return status >= 0 ? status : -errno; diff --git a/src/core/file_sys/hostio/src/host_io_virtual.cpp b/src/core/file_sys/hostio/src/host_io_virtual.cpp index 47108f894..337a86489 100644 --- a/src/core/file_sys/hostio/src/host_io_virtual.cpp +++ b/src/core/file_sys/hostio/src/host_io_virtual.cpp @@ -43,8 +43,7 @@ s32 HostIO_Virtual::Open(const fs::path& path, s32 flags, u16 mode) { if ((flags & QUASI_O_CREAT) == 0) return -QUASI_ENOENT; - target = - this->host_bound ? QuasiFile::Create() : QuasiFile::Create(); + target = this->host_bound ? RegularFile::Create() : VirtualFile::Create(); target->chmod(mode); if (0 != part->touch(parent, this->res->leaf, target)) // touch failed in target directory, issue with resolve() is most likely @@ -147,7 +146,7 @@ s32 HostIO_Virtual::FSync(const s32 fd) { return handle->node->fsync(); } -s64 HostIO_Virtual::LSeek(const s32 fd, u64 offset, QuasiFS::SeekOrigin origin) { +s64 HostIO_Virtual::LSeek(const s32 fd, s64 offset, s32 whence) { if (nullptr == handle) return -QUASI_EINVAL; @@ -156,17 +155,13 @@ s64 HostIO_Virtual::LSeek(const s32 fd, u64 offset, QuasiFS::SeekOrigin origin) if (nullptr == node) return -QUASI_EBADF; - auto ptr = &handle->pos; + s64 new_position = node->lseek(handle->pos, offset, whence); - u64 new_ptr = ((SeekOrigin::ORIGIN == origin) * offset) + - ((SeekOrigin::CURRENT == origin) * (*(ptr) + offset)) + - ((SeekOrigin::END == origin) * (node->st.st_size + offset)); - - if (new_ptr < 0) + if (new_position < 0) return -QUASI_EINVAL; - *ptr = new_ptr; - return *ptr; + handle->pos = new_position; + return handle->pos; } s64 HostIO_Virtual::Tell(const s32 fd) { @@ -212,7 +207,7 @@ s64 HostIO_Virtual::Read(const s32 fd, void* buf, u64 count) { return br; } -s64 HostIO_Virtual::PRead(const s32 fd, void* buf, u64 count, u64 offset) { +s64 HostIO_Virtual::PRead(const s32 fd, void* buf, u64 count, s64 offset) { if (nullptr == handle) return -QUASI_EINVAL; @@ -257,7 +252,7 @@ s64 HostIO_Virtual::Write(const s32 fd, const void* buf, u64 count) { return bw; } -s64 HostIO_Virtual::PWrite(const s32 fd, const void* buf, u64 count, u64 offset) { +s64 HostIO_Virtual::PWrite(const s32 fd, const void* buf, u64 count, s64 offset) { if (nullptr == handle) return -QUASI_EBADF; @@ -300,8 +295,7 @@ s32 HostIO_Virtual::MKDir(const fs::path& path, u16 mode) { if (nullptr == this->res) return -QUASI_EINVAL; - dir_ptr new_dir = Directory::Create(); - return this->res->mountpoint->mkdir(this->res->parent, this->res->leaf, new_dir); + return this->res->mountpoint->mkdir(this->res->parent, this->res->leaf); } s32 HostIO_Virtual::RMDir(const fs::path& path) { diff --git a/src/core/file_sys/hostio/src/host_io_win32.cpp b/src/core/file_sys/hostio/src/host_io_win32.cpp index df8b91c7e..5cb1835ec 100644 --- a/src/core/file_sys/hostio/src/host_io_win32.cpp +++ b/src/core/file_sys/hostio/src/host_io_win32.cpp @@ -58,7 +58,7 @@ s32 HostIO_Win32::FSync(const s32 fd) { return 0 == status ? 0 : -errno; } -s64 HostIO_Win32::LSeek(const s32 fd, u64 offset, QuasiFS::SeekOrigin origin) { +s64 HostIO_Win32::LSeek(const s32 fd, u64 offset, s32 whence) { errno = 0; s32 status = _lseeki64(fd, offset, ToWIN32SeekOrigin(origin)); return status >= 0 ? status : -errno; diff --git a/src/core/file_sys/quasifs/quasi_types.h b/src/core/file_sys/quasifs/quasi_types.h index 0faa524f1..64b9b7008 100644 --- a/src/core/file_sys/quasifs/quasi_types.h +++ b/src/core/file_sys/quasifs/quasi_types.h @@ -78,7 +78,9 @@ struct File { } }; -enum class SeekOrigin : uint8_t { ORIGIN, CURRENT, END }; +namespace SeekOrigin { +enum { ORIGIN = 0, CURRENT, END }; +} // // Access diff --git a/src/core/file_sys/quasifs/quasifs.h b/src/core/file_sys/quasifs/quasifs.h index 0b4c21c8b..35b1850b8 100644 --- a/src/core/file_sys/quasifs/quasifs.h +++ b/src/core/file_sys/quasifs/quasifs.h @@ -71,17 +71,17 @@ private: s32 FSync(const s32 fd) override; s32 Truncate(const fs::path& path, u64 size) override; s32 FTruncate(const s32 fd, u64 size) override; - s64 LSeek(const s32 fd, u64 offset, SeekOrigin origin) override; + s64 LSeek(const s32 fd, s64 offset, s32 whence) override; s64 Tell(const s32 fd) override; s64 Read(const s32 fd, void* buf, u64 count) override; - s64 PRead(const s32 fd, void* buf, u64 count, u64 offset) override; + s64 PRead(const s32 fd, void* buf, u64 count, s64 offset) override; s64 ReadV(const s32 fd, Libraries::Kernel::OrbisKernelIovec* iov, u32 iovcnt) override; s64 PReadV(const s32 fd, Libraries::Kernel::OrbisKernelIovec* iov, u32 iovcnt, s64 offset) override; s64 Write(const s32 fd, const void* buf, u64 count) override; - s64 PWrite(const s32 fd, const void* buf, u64 count, u64 offset) override; + s64 PWrite(const s32 fd, const void* buf, u64 count, s64 offset) override; s64 WriteV(const s32 fd, const Libraries::Kernel::OrbisKernelIovec* iov, u32 iovcnt) override; s64 PWriteV(const s32 fd, const Libraries::Kernel::OrbisKernelIovec* iov, u32 iovcnt, diff --git a/src/core/file_sys/quasifs/quasifs_inode.h b/src/core/file_sys/quasifs/quasifs_inode.h index a0f41f0e3..a954e5c82 100644 --- a/src/core/file_sys/quasifs/quasifs_inode.h +++ b/src/core/file_sys/quasifs/quasifs_inode.h @@ -72,7 +72,7 @@ public: return tb; } - virtual s64 lseek(s64 offset, int whence) { + virtual s64 lseek(s64 current, s64 offset, s32 whence) { return -QUASI_EBADF; } diff --git a/src/core/file_sys/quasifs/quasifs_inode_quasi_device.h b/src/core/file_sys/quasifs/quasifs_inode_quasi_device.h index 6e04a4cb4..fcdae686a 100644 --- a/src/core/file_sys/quasifs/quasifs_inode_quasi_device.h +++ b/src/core/file_sys/quasifs/quasifs_inode_quasi_device.h @@ -15,11 +15,8 @@ public: Device(); ~Device(); - template - static dev_ptr Create(Args&&... args) { - if constexpr (std::is_base_of_v) - return std::make_shared(std::forward(args)...); - UNREACHABLE(); + static dev_ptr Create() { + return std::make_shared(); } virtual s64 read(void* buf, u64 count); diff --git a/src/core/file_sys/quasifs/quasifs_inode_quasi_directory.h b/src/core/file_sys/quasifs/quasifs_inode_quasi_directory.h index 8ca6d98e6..7633105a7 100644 --- a/src/core/file_sys/quasifs/quasifs_inode_quasi_directory.h +++ b/src/core/file_sys/quasifs/quasifs_inode_quasi_directory.h @@ -46,24 +46,27 @@ public: return out; } - template - static dir_ptr Create(Args&&... args) { - if constexpr (std::is_base_of_v) - return std::make_shared(std::forward(args)...); - UNREACHABLE(); + // Create out of thin air + static dir_ptr Create() { + return std::make_shared(); + } + + // Allow "inheriting" type of directory + virtual dir_ptr Spawn() const { + return std::make_shared(); } // // Inode overrides // - s64 pread(void* buf, u64 count, s64 offset) override; + virtual s64 pread(void* buf, u64 count, s64 offset) override; // s64 pwrite(const void* buf, size_t count, u64 offset) override; - s32 ftruncate(s64 length) final override; s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) override; + s32 ftruncate(s64 length) final override; - s64 getdents(void* buf, u32 count, s64 offset, s64* basep) override; + virtual s64 getdents(void* buf, u32 count, s64 offset, s64* basep) override; // // Dir-specific diff --git a/src/core/file_sys/quasifs/quasifs_inode_quasi_directory_pfs.h b/src/core/file_sys/quasifs/quasifs_inode_quasi_directory_pfs.h index 68c49765b..e8669f7b9 100644 --- a/src/core/file_sys/quasifs/quasifs_inode_quasi_directory_pfs.h +++ b/src/core/file_sys/quasifs/quasifs_inode_quasi_directory_pfs.h @@ -29,16 +29,25 @@ protected: #pragma pack(pop) private: - // void RebuildDirents(void); + void RebuildDirents(void); + s64 dirents_size{}; public: DirectoryPFS(); ~DirectoryPFS(); - s64 pread(void* buf, u64 count, s64 offset) override; - - s64 getdents(void* buf, u32 count, s64 offset, s64* basep) override; + static dir_ptr Create() { + return std::make_shared(); + } + virtual dir_ptr Spawn() const override { + return std::make_shared(); + } + + s64 pread(void* buf, u64 count, s64 offset) override; + + s64 lseek(s64 current, s64 offset, s32 whence) override; + s64 getdents(void* buf, u32 count, s64 offset, s64* basep) override; }; } // namespace QuasiFS \ No newline at end of file diff --git a/src/core/file_sys/quasifs/quasifs_inode_quasi_file.h b/src/core/file_sys/quasifs/quasifs_inode_quasi_file.h index 4daab4e2a..f1eda818b 100644 --- a/src/core/file_sys/quasifs/quasifs_inode_quasi_file.h +++ b/src/core/file_sys/quasifs/quasifs_inode_quasi_file.h @@ -18,16 +18,15 @@ public: }; ~QuasiFile() = default; - template - static file_ptr Create(Args&&... args) { - if constexpr (std::is_base_of_v) - return std::make_shared(std::forward(args)...); - UNREACHABLE(); + static file_ptr Create() { + return std::make_shared(); } s64 pread(void* buf, size_t count, s64 offset) override; s64 pwrite(const void* buf, size_t count, s64 offset) override; + s64 lseek(s64 current, s64 offset, s32 whence) override; + s32 ftruncate(s64 length) override; }; diff --git a/src/core/file_sys/quasifs/quasifs_inode_quasi_file_virtual.h b/src/core/file_sys/quasifs/quasifs_inode_quasi_file_virtual.h index afc863f69..6c723db88 100644 --- a/src/core/file_sys/quasifs/quasifs_inode_quasi_file_virtual.h +++ b/src/core/file_sys/quasifs/quasifs_inode_quasi_file_virtual.h @@ -16,6 +16,10 @@ public: VirtualFile() = default; ~VirtualFile() = default; + static std::shared_ptr Create() { + return std::make_shared(); + } + // // Working functions // diff --git a/src/core/file_sys/quasifs/quasifs_inode_quasi_socket.h b/src/core/file_sys/quasifs/quasifs_inode_quasi_socket.h index a7e4ae21e..777b6ee02 100644 --- a/src/core/file_sys/quasifs/quasifs_inode_quasi_socket.h +++ b/src/core/file_sys/quasifs/quasifs_inode_quasi_socket.h @@ -15,11 +15,8 @@ public: Socket(); ~Socket(); - template - static dev_ptr Create(Args&&... args) { - if constexpr (std::is_base_of_v) - return std::make_shared(std::forward(args)...); - UNREACHABLE(); + static socket_ptr Create() { + return std::make_shared(); } }; diff --git a/src/core/file_sys/quasifs/quasifs_partition.h b/src/core/file_sys/quasifs/quasifs_partition.h index 47da55a4b..ad80326e8 100644 --- a/src/core/file_sys/quasifs/quasifs_partition.h +++ b/src/core/file_sys/quasifs/quasifs_partition.h @@ -40,14 +40,21 @@ public: Partition(); Partition(const fs::path& host_root = "", const int root_permissions = 0755, const u32 ioblock_size = 4096); - Partition(dir_ptr root_directory = Directory::Create(), - const fs::path& host_root = "", const int root_permissions = 0755, - const u32 ioblock_size = 4096); + Partition(dir_ptr root_directory = Directory::Create(), const fs::path& host_root = "", + const int root_permissions = 0755, const u32 ioblock_size = 4096); ~Partition() = default; - template - static partition_ptr Create(Args&&... args) { - return std::make_shared(std::forward(args)...); + static partition_ptr Create(const fs::path& host_root = "", const int root_permissions = 0755, + const u32 ioblock_size = 4096) { + return std::make_shared(Directory::Create(), host_root, root_permissions, + ioblock_size); + } + + static partition_ptr Create(dir_ptr root_directory = Directory::Create(), + const fs::path& host_root = "", const int root_permissions = 0755, + const u32 ioblock_size = 4096) { + return std::make_shared(root_directory, host_root, root_permissions, + ioblock_size); } // empty - invalid, not empty - safe @@ -71,17 +78,16 @@ public: // create file at path (creates entry in parent dir). returns 0 or negative errno template int touch(dir_ptr parent, const std::string& name) { - if constexpr (!std::is_base_of_v) + if constexpr (std::is_base_of_v) return touch(parent, name, T::Create()); + UNREACHABLE_MSG(" QuasiFS:Partition:Touch Created element must derive from Inode"); static_assert(std::is_base_of_v, " QuasiFS:Partition:Touch Created element must derive from Inode"); + return -666; } int touch(dir_ptr parent, const std::string& name, inode_ptr child); int mkdir(dir_ptr parent, const std::string& name); - int mkdir(dir_ptr parent, const std::string& name, dir_ptr child); - - int rmdir(fs::path path); int rmdir(dir_ptr parent, const std::string& name); int link(inode_ptr source, dir_ptr destination_parent, const std::string& name); diff --git a/src/core/file_sys/quasifs/src/quasifs.cpp b/src/core/file_sys/quasifs/src/quasifs.cpp index 04053b760..d306fff24 100644 --- a/src/core/file_sys/quasifs/src/quasifs.cpp +++ b/src/core/file_sys/quasifs/src/quasifs.cpp @@ -114,7 +114,7 @@ void printTree(const dir_ptr& node, const std::string& name, int depth) { } QFS::QFS(const fs::path& host_path) { - this->rootfs = Partition::Create(Directory::Create(), host_path); + this->rootfs = Partition::Create(Directory::Create(), host_path); this->root = rootfs->GetRoot(); mount_t mount_options = { @@ -416,19 +416,18 @@ void QFS::SyncHostImpl(partition_ptr part) { dir_ptr parent_dir = res.node->is_dir() ? std::static_pointer_cast(res.node) : nullptr; - inode_ptr new_inode{}; if (entry->is_directory()) { - new_inode = Directory::Create(); - part->mkdir(parent_dir, leaf, std::static_pointer_cast(new_inode)); + part->mkdir(parent_dir, leaf); } else if (entry->is_regular_file()) { - new_inode = QuasiFile::Create(); - part->touch(parent_dir, leaf, std::static_pointer_cast(new_inode)); + part->touch(parent_dir, leaf); } else { LOG_ERROR(Kernel_Fs, "Unsupported host file type: {}", entry_path.string()); continue; } + inode_ptr new_inode = parent_dir->lookup(leaf); + // this should populate **everything** immediately // this is a note to self TODO: if (0 != this->hio_driver.Stat(entry_path, &new_inode->st)) { diff --git a/src/core/file_sys/quasifs/src/quasifs_inode_quasi_directory.cpp b/src/core/file_sys/quasifs/src/quasifs_inode_quasi_directory.cpp index af2098c6a..4f51e17fa 100644 --- a/src/core/file_sys/quasifs/src/quasifs_inode_quasi_directory.cpp +++ b/src/core/file_sys/quasifs/src/quasifs_inode_quasi_directory.cpp @@ -17,16 +17,16 @@ s64 QuasiDirectory::pread(void* buf, u64 count, s64 offset) { return getdents(buf, count, offset, nullptr); } -s32 QuasiDirectory::ftruncate(s64 length) { - return -QUASI_EISDIR; -} - s32 QuasiDirectory::fstat(Libraries::Kernel::OrbisKernelStat* sb) { RebuildDirents(); *sb = st; return 0; } +s32 QuasiDirectory::ftruncate(s64 length) { + return -QUASI_EISDIR; +} + s64 QuasiDirectory::getdents(void* buf, u32 count, s64 offset, s64* basep) { RebuildDirents(); @@ -123,6 +123,9 @@ void QuasiDirectory::RebuildDirents(void) { return; this->last_dirent_rebuild_time = this->st.st_mtim.tv_sec; + constexpr u32 dirent_meta_size = sizeof(dirent_t::d_fileno) + sizeof(dirent_t::d_type) + + sizeof(dirent_t::d_namlen) + sizeof(dirent_t::d_reclen); + u64 dirent_size = 0; this->dirent_cache.clear(); @@ -135,10 +138,7 @@ void QuasiDirectory::RebuildDirents(void) { tmp.d_namlen = name.size(); strncpy(tmp.d_name, name.data(), tmp.d_namlen + 1); tmp.d_type = node->type() >> 12; - tmp.d_reclen = - Common::AlignUp(sizeof(tmp.d_fileno) + sizeof(tmp.d_type) + sizeof(tmp.d_namlen) + - sizeof(tmp.d_reclen) + (tmp.d_namlen + 1), - 4); + tmp.d_reclen = Common::AlignUp(dirent_meta_size + tmp.d_namlen + 1, 4); dirent_cache[dirent_size] = tmp; dirent_size += tmp.d_reclen; diff --git a/src/core/file_sys/quasifs/src/quasifs_inode_quasi_directory_pfs.cpp b/src/core/file_sys/quasifs/src/quasifs_inode_quasi_directory_pfs.cpp index 0a3555e61..6d1524ab7 100644 --- a/src/core/file_sys/quasifs/src/quasifs_inode_quasi_directory_pfs.cpp +++ b/src/core/file_sys/quasifs/src/quasifs_inode_quasi_directory_pfs.cpp @@ -23,30 +23,57 @@ s64 DirectoryPFS::pread(void* buf, u64 count, s64 offset) { if (it == dirent_cache.end()) return 0; + memset(buf, 0, count); u64 cumulative_offset = 0; - u16 last_reclen = 0; + u32* reclen_location = nullptr; for (; it != dirent_cache.end(); it++) { auto dirent = it->second; - if (dirent.d_reclen + cumulative_offset > count) break; - memcpy(static_cast(buf) + cumulative_offset, &dirent, dirent.d_reclen); - last_reclen = dirent.d_reclen; - cumulative_offset += last_reclen; + auto partial_base = static_cast(buf) + cumulative_offset; + auto _fileno = reinterpret_cast(partial_base); + auto _type = reinterpret_cast(partial_base) + 1; + auto _namlen = reinterpret_cast(partial_base) + 2; + reclen_location = reinterpret_cast(partial_base) + 3; + + *_fileno = dirent.d_fileno; + *_type = dirent.d_type; + *_namlen = dirent.d_namlen; + *reclen_location = dirent.d_reclen; + + memcpy(reinterpret_cast(reclen_location + 1), &dirent.d_name, dirent.d_namlen); + cumulative_offset += dirent.d_reclen; } - // offset of the last reclen - auto _val = cumulative_offset - last_reclen + 4; - // pointer to last reclen in buffer - u8* placement = static_cast(buf) + _val; - // casting buffer to u16 to write whole value at once (2 bytes) - u16* pos = reinterpret_cast(placement); - *pos += Common::AlignUp(cumulative_offset, count) - cumulative_offset; + *reclen_location += Common::AlignUp(cumulative_offset, count) - cumulative_offset; return count; } +s64 DirectoryPFS::lseek(s64 current, s64 offset, s32 whence) { + switch (whence) { + case 0: + return offset; + break; + case 1: + if ((current + offset) >= dirents_size) + return current + offset; + { + auto _tmp = dirent_cache.lower_bound(current + offset); + if (_tmp == dirent_cache.end()) + return -QUASI_EINVAL; + return _tmp->first; + } + break; + case 2: + return dirents_size + offset; + break; + } + UNREACHABLE_MSG("lseek with unknown whence {}", whence); + return -QUASI_ENOSYS; +} + s64 DirectoryPFS::getdents(void* buf, u32 count, s64 offset, s64* basep) { RebuildDirents(); @@ -56,7 +83,6 @@ s64 DirectoryPFS::getdents(void* buf, u32 count, s64 offset, s64* basep) { return 0; u64 cumulative_offset = 0; - u16 last_reclen = 0; for (; it != dirent_cache.end(); it++) { auto dirent = it->second; @@ -64,21 +90,46 @@ s64 DirectoryPFS::getdents(void* buf, u32 count, s64 offset, s64* basep) { break; memcpy(static_cast(buf) + cumulative_offset, &dirent, dirent.d_reclen); - last_reclen = dirent.d_reclen; - cumulative_offset += last_reclen; + cumulative_offset += dirent.d_reclen; } if (basep) *basep = cumulative_offset; - // offset of the last reclen - auto _val = cumulative_offset - last_reclen + 4; - // pointer to last reclen in buffer - u8* placement = static_cast(buf) + _val; - // casting buffer to u16 to write whole value at once (2 bytes) - u16* pos = reinterpret_cast(placement); - *pos += Common::AlignUp(cumulative_offset, count) - cumulative_offset; - return count; + return cumulative_offset; +} + +void DirectoryPFS::RebuildDirents(void) { + // adding/removing entries changes mtime + if (this->st.st_mtim.tv_sec == this->last_dirent_rebuild_time) + return; + this->last_dirent_rebuild_time = this->st.st_mtim.tv_sec; + + constexpr u32 dirent_meta_size = sizeof(dirent_pfs_t::d_fileno) + sizeof(dirent_pfs_t::d_type) + + sizeof(dirent_pfs_t::d_namlen) + + sizeof(dirent_pfs_t::d_reclen); + + u64 dirent_size = 0; + this->dirent_cache.clear(); + + for (auto entry = entries.begin(); entry != entries.end(); ++entry) { + dirent_t tmp{}; + inode_ptr node = entry->second; + std::string name = entry->first; + + tmp.d_fileno = node->fileno; + tmp.d_namlen = name.size(); + strncpy(tmp.d_name, name.data(), tmp.d_namlen + 1); + tmp.d_type = node->type() >> 12; + tmp.d_reclen = Common::AlignUp(dirent_meta_size + tmp.d_namlen + 1, 8); + + dirent_cache[dirent_size] = tmp; + dirent_size += tmp.d_reclen; + } + + this->dirents_size = dirent_size; + + return; } } // namespace QuasiFS \ No newline at end of file diff --git a/src/core/file_sys/quasifs/src/quasifs_inode_quasi_file.cpp b/src/core/file_sys/quasifs/src/quasifs_inode_quasi_file.cpp index e3022a25b..b06781f21 100644 --- a/src/core/file_sys/quasifs/src/quasifs_inode_quasi_file.cpp +++ b/src/core/file_sys/quasifs/src/quasifs_inode_quasi_file.cpp @@ -25,6 +25,12 @@ s64 QuasiFile::pwrite(const void* buf, size_t count, s64 offset) { return count; } +s64 QuasiFile::lseek(s64 current, s64 offset, s32 whence) { + return ((SeekOrigin::ORIGIN == whence) * offset) + + ((SeekOrigin::CURRENT == whence) * (current + offset)) + + ((SeekOrigin::END == whence) * (this->st.st_size + offset)); +} + s32 QuasiFile::ftruncate(s64 length) { if (length < 0) return -QUASI_EINVAL; diff --git a/src/core/file_sys/quasifs/src/quasifs_partition.cpp b/src/core/file_sys/quasifs/src/quasifs_partition.cpp index 15d61e5e2..9f426aa46 100644 --- a/src/core/file_sys/quasifs/src/quasifs_partition.cpp +++ b/src/core/file_sys/quasifs/src/quasifs_partition.cpp @@ -12,16 +12,15 @@ namespace QuasiFS { -Partition::Partition() : Partition(Directory::Create(), "", 0755, 4096) {} +Partition::Partition() : Partition(Directory::Create(), "", 0755, 4096) {} Partition::Partition(const fs::path& host_root, const int root_permissions, const u32 ioblock_size) - : Partition(Directory::Create(), host_root, root_permissions, ioblock_size) {} + : Partition(dir_ptr(), host_root, root_permissions, ioblock_size) {} Partition::Partition(dir_ptr root_directory, const fs::path& host_root, const int root_permissions, const u32 ioblock_size) - : block_id(next_block_id++), host_root(host_root.lexically_normal()), + : root(root_directory), block_id(next_block_id++), host_root(host_root.lexically_normal()), ioblock_size(ioblock_size) { - this->root = Directory::Create(); // clear defaults, write chmod(this->root, root_permissions); IndexInode(this->root); @@ -233,35 +232,23 @@ int Partition::touch(dir_ptr parent, const std::string& name, inode_ptr child) { } int Partition::mkdir(dir_ptr parent, const std::string& name) { - return mkdir(parent, name, Directory::Create()); -} - -int Partition::mkdir(dir_ptr parent, const std::string& name, dir_ptr child) { if (nullptr == parent) return -QUASI_ENOENT; + dir_ptr real_parent = parent->mounted_root ? parent->mounted_root : parent; + dir_ptr child = real_parent->Spawn(); + child->st.st_blksize = ioblock_size; int ret = parent->link(name, child); if (ret == 0) IndexInode(child); - auto real_parent = parent->mounted_root ? parent->mounted_root : parent; mkrelative(real_parent, child); return ret; } -int Partition::rmdir(fs::path path) { - Resolved res; - int resolve_status = this->Resolve(path, res); - - if (resolve_status != 0) - return resolve_status; - - return this->rmdir(res.parent, res.leaf); -} - int Partition::rmdir(dir_ptr parent, const std::string& name) { if (nullptr == parent) return -QUASI_ENOENT; diff --git a/src/core/file_sys/quasifs/src/quasifs_vdriver.cpp b/src/core/file_sys/quasifs/src/quasifs_vdriver.cpp index 8516d56cc..715cda619 100644 --- a/src/core/file_sys/quasifs/src/quasifs_vdriver.cpp +++ b/src/core/file_sys/quasifs/src/quasifs_vdriver.cpp @@ -109,6 +109,7 @@ s32 QFS::OperationImpl::Open(const fs::path& path, int flags, u16 mode) { handle->read = request_read; handle->write = request_write; handle->append = request_append; + handle->pos = 0; auto next_free_handle = qfs.GetFreeHandleNo(); qfs.open_fd[next_free_handle] = handle; return next_free_handle; @@ -471,7 +472,7 @@ s32 QFS::OperationImpl::FTruncate(const s32 fd, u64 length) { return vio_status; } -s64 QFS::OperationImpl::LSeek(const s32 fd, u64 offset, SeekOrigin origin) { +s64 QFS::OperationImpl::LSeek(const s32 fd, s64 offset, s32 whence) { if (fd < 0) return -QUASI_EBADF; @@ -485,14 +486,14 @@ s64 QFS::OperationImpl::LSeek(const s32 fd, u64 offset, SeekOrigin origin) { if (handle->IsHostBound()) { int host_fd = handle->host_fd; - if (hio_status = qfs.hio_driver.LSeek(host_fd, offset, origin); hio_status < 0) + if (hio_status = qfs.hio_driver.LSeek(host_fd, offset, whence); hio_status < 0) // hosts operation must succeed in order to continue return hio_status; host_used = true; } qfs.vio_driver.SetCtx(nullptr, host_used, handle); - vio_status = qfs.vio_driver.LSeek(fd, offset, origin); + vio_status = qfs.vio_driver.LSeek(fd, offset, whence); qfs.vio_driver.ClearCtx(); if (host_used && (hio_status != vio_status)) @@ -550,7 +551,7 @@ s64 QFS::OperationImpl::Read(const s32 fd, void* buf, u64 count) { return vio_status; } -s64 QFS::OperationImpl::PRead(const s32 fd, void* buf, u64 count, u64 offset) { +s64 QFS::OperationImpl::PRead(const s32 fd, void* buf, u64 count, s64 offset) { if (fd < 0) return -QUASI_EBADF; @@ -687,7 +688,7 @@ s64 QFS::OperationImpl::Write(const s32 fd, const void* buf, u64 count) { return vio_status; } -s64 QFS::OperationImpl::PWrite(const s32 fd, const void* buf, u64 count, u64 offset) { +s64 QFS::OperationImpl::PWrite(const s32 fd, const void* buf, u64 count, s64 offset) { if (fd < 0) return -QUASI_EBADF; diff --git a/src/core/libraries/app_content/app_content.cpp b/src/core/libraries/app_content/app_content.cpp index f47fa99b1..f4eb4ddcb 100644 --- a/src/core/libraries/app_content/app_content.cpp +++ b/src/core/libraries/app_content/app_content.cpp @@ -112,8 +112,9 @@ int PS4_SYSV_ABI sceAppContentAddcontMount(u32 service_label, // We've located the correct folder. g_qfs->Operation.MKDir(mount_point->data, 0555 /* I think it's like /app0*/); - qfs::partition_ptr partition_dlc = qfs::Partition::Create( - qfs::Directory::Create(), entry.path(), 0555); + // Didn't verify FS type + qfs::partition_ptr partition_dlc = + qfs::Partition::Create(qfs::DirectoryPFS::Create(), entry.path(), 0555); g_qfs->Mount(mount_point->data, partition_dlc, qfs::MountOptions::MOUNT_RW); g_qfs->SyncHost(mount_point->data); g_qfs->Mount(mount_point->data, partition_dlc, diff --git a/src/core/libraries/kernel/file_system.cpp b/src/core/libraries/kernel/file_system.cpp index c318174f9..25b1c4d8e 100644 --- a/src/core/libraries/kernel/file_system.cpp +++ b/src/core/libraries/kernel/file_system.cpp @@ -151,7 +151,7 @@ s64 PS4_SYSV_ABI sceKernelWritev(s32 fd, const OrbisKernelIovec* iov, s32 iovcnt } s64 PS4_SYSV_ABI posix_lseek(s32 fd, s64 offset, s32 whence) { - qfs::SeekOrigin origin{}; + s32 origin{}; if (whence == 0) { origin = qfs::SeekOrigin::ORIGIN; } else if (whence == 1) { diff --git a/src/core/libraries/save_data/save_instance.cpp b/src/core/libraries/save_data/save_instance.cpp index 16b834d7b..c987735b7 100644 --- a/src/core/libraries/save_data/save_instance.cpp +++ b/src/core/libraries/save_data/save_instance.cpp @@ -192,7 +192,8 @@ void SaveInstance::SetupAndMount(bool read_only, bool copy_icon, bool ignore_cor max_blocks = static_cast(GetMaxBlockFromSFO(param_sfo)); g_qfs->Operation.MKDir(mount_point); - auto part = qfs::Partition::Create(qfs::Directory::Create(), save_path); + // Didn't verify FS type + auto part = qfs::Partition::Create(qfs::Directory::Create(), save_path); g_qfs->Mount(mount_point, part, read_only ? qfs::MountOptions::MOUNT_NOOPT : qfs::MountOptions::MOUNT_RW); g_qfs->SyncHost(mount_point); diff --git a/src/emulator.cpp b/src/emulator.cpp index badd4dbc2..ac3814d8a 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -94,9 +94,8 @@ Emulator::~Emulator() {} void Emulator::LoadFilesystem(const std::filesystem::path& game_folder) { auto* qfs = Common::Singleton::Instance(); - qfs::partition_ptr partition_app0 = qfs::Partition::Create(game_folder, 0555, 65536); - // qfs::partition_ptr partition_app0 = qfs::Partition::Create( - // qfs::Directory::Create(), game_folder, 0555, 512, 65536); + qfs::partition_ptr partition_app0 = + qfs::Partition::Create(qfs::DirectoryPFS::Create(), game_folder, 0555, 65536); qfs::partition_ptr partition_av_contents = qfs::Partition::Create("", 0775, 16384); qfs::partition_ptr partition_av_contents_photo = qfs::Partition::Create("", 0755, 32768); qfs::partition_ptr partition_av_contents_thumbs = qfs::Partition::Create("", 0755, 32768); @@ -127,9 +126,9 @@ void Emulator::LoadFilesystem(const std::filesystem::path& game_folder) { // qfs->Operation.MKDir("/dev/fd"); - qfs->ForceInsert("/dev/fd", "0", qfs::Device::Create()); - qfs->ForceInsert("/dev/fd", "1", qfs::Device::Create("stdout", false)); - qfs->ForceInsert("/dev/fd", "2", qfs::Device::Create("stderr", true)); + qfs->ForceInsert("/dev/fd", "0", Devices::ZeroDevice::Create()); + qfs->ForceInsert("/dev/fd", "1", Devices::Logger::Create("stdout", false)); + qfs->ForceInsert("/dev/fd", "2", Devices::Logger::Create("stderr", true)); // std* is unavailable from within the app??? qfs->Operation.LinkSymbolic("/dev/fd/0", "/dev/stdin"); qfs->Operation.LinkSymbolic("/dev/fd/1", "/dev/stdout"); @@ -138,14 +137,14 @@ void Emulator::LoadFilesystem(const std::filesystem::path& game_folder) { qfs->Operation.LinkSymbolic("/dev/fd/1", "/dev/deci_stdout"); qfs->Operation.LinkSymbolic("/dev/fd/2", "/dev/deci_stderr"); - qfs->ForceInsert("/dev", "console", qfs::Device::Create()); - qfs->ForceInsert("/dev", "deci_tty6", qfs::Device::Create()); - qfs->ForceInsert("/dev", "random", qfs::Device::Create()); - qfs->ForceInsert("/dev", "urandom", qfs::Device::Create()); - qfs->ForceInsert("/dev", "srandom", qfs::Device::Create()); - qfs->ForceInsert("/dev", "zero", qfs::Device::Create()); - qfs->ForceInsert("/dev", "null", qfs::Device::Create()); - qfs->ForceInsert("/dev", "rng", qfs::Device::Create()); + qfs->ForceInsert("/dev", "console", Devices::ConsoleDevice::Create()); + qfs->ForceInsert("/dev", "deci_tty6", Devices::DeciTty6Device::Create()); + qfs->ForceInsert("/dev", "random", Devices::RandomDevice::Create()); + qfs->ForceInsert("/dev", "urandom", Devices::RandomDevice::Create()); + qfs->ForceInsert("/dev", "srandom", Devices::SRandomDevice::Create()); + qfs->ForceInsert("/dev", "zero", Devices::ZeroDevice::Create()); + qfs->ForceInsert("/dev", "null", Devices::NullDevice::Create()); + qfs->ForceInsert("/dev", "rng", Devices::RngDevice::Create()); qfs->Operation.Chmod("/dev/deci_stderr", 0666); qfs->Operation.Chmod("/dev/deci_stdout", 0666);