From 89b91c6f3001a5a05d63f5ceba3f3e350caadd6f Mon Sep 17 00:00:00 2001 From: Marek Ledworowski Date: Thu, 6 Nov 2025 21:53:30 +0100 Subject: [PATCH] Implemented vector rw in virtual and posix Reverted Partition::Format (stupid idea) Minor removals --- src/core/file_sys/hostio/host_io_posix.h | 19 ++- src/core/file_sys/hostio/host_io_virtual.h | 14 +- src/core/file_sys/hostio/host_io_win32.h | 14 +- src/core/file_sys/hostio/src/host_io_base.cpp | 52 +++--- src/core/file_sys/hostio/src/host_io_base.h | 18 +- .../file_sys/hostio/src/host_io_posix.cpp | 75 +++++++-- .../file_sys/hostio/src/host_io_virtual.cpp | 88 +++++++--- .../file_sys/hostio/src/host_io_win32.cpp | 38 ++--- src/core/file_sys/quasifs/quasi_types.h | 1 + src/core/file_sys/quasifs/quasifs.h | 14 +- src/core/file_sys/quasifs/quasifs_inode.h | 41 +---- .../quasifs/quasifs_inode_quasi_device.h | 7 +- .../quasifs_inode_quasi_directory_pfs.h | 1 - src/core/file_sys/quasifs/quasifs_partition.h | 13 +- src/core/file_sys/quasifs/src/quasifs.cpp | 2 +- .../src/quasifs_inode_quasi_device.cpp | 8 + .../quasifs/src/quasifs_partition.cpp | 28 +--- .../file_sys/quasifs/src/quasifs_vdriver.cpp | 157 +++++++++++++++++- src/emulator.cpp | 61 +++---- 19 files changed, 439 insertions(+), 212 deletions(-) diff --git a/src/core/file_sys/hostio/host_io_posix.h b/src/core/file_sys/hostio/host_io_posix.h index b76179b8f..0294f784c 100644 --- a/src/core/file_sys/hostio/host_io_posix.h +++ b/src/core/file_sys/hostio/host_io_posix.h @@ -13,6 +13,11 @@ namespace HostIODriver { +static_assert(std::is_same_v, + "IOV base pointer is incompatible with native call"); +static_assert(std::is_same_v, + "IOV length specifier is incompatible with native call"); + /** * This driver bends time and space a bit, because it conforms to POSIX-like returns, * i.e. -1 for error, 0 for success @@ -95,17 +100,21 @@ public: s32 Truncate(const fs::path& path, u64 size) override; s32 FTruncate(const s32 fd, u64 size) override; - s64 Write(const s32 fd, const void* buf, u64 count) override; s64 Read(const s32 fd, void* buf, u64 count) override; - - s64 PWrite(const s32 fd, const void* buf, u64 count, u64 offset) override; s64 PRead(const s32 fd, void* buf, u64 count, u64 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 WriteV(const s32 fd, const OrbisKernelIovec* iov, u32 iovcnt) override; + s64 PWriteV(const s32 fd, const OrbisKernelIovec* iov, u32 iovcnt, s64 offset) override; s32 MKDir(const fs::path& path, u16 mode = 0755) override; s32 RMDir(const fs::path& path) override; - s32 Stat(const fs::path& path, Libraries::Kernel::OrbisKernelStat* statbuf) override; - s32 FStat(const s32 fd, Libraries::Kernel::OrbisKernelStat* statbuf) override; + s32 Stat(const fs::path& path, OrbisKernelStat* statbuf) override; + s32 FStat(const s32 fd, OrbisKernelStat* statbuf) override; s32 Chmod(const fs::path& path, u16 mode) override; s32 FChmod(const s32 fd, u16 mode) override; diff --git a/src/core/file_sys/hostio/host_io_virtual.h b/src/core/file_sys/hostio/host_io_virtual.h index 176fef000..933eea103 100644 --- a/src/core/file_sys/hostio/host_io_virtual.h +++ b/src/core/file_sys/hostio/host_io_virtual.h @@ -61,17 +61,21 @@ public: s32 Truncate(const fs::path& path, u64 size) override; s32 FTruncate(const s32 fd, u64 size) override; - s64 Write(const s32 fd, const void* buf, u64 count) override; s64 Read(const s32 fd, void* buf, u64 count) override; - - s64 PWrite(const s32 fd, const void* buf, u64 count, u64 offset) override; s64 PRead(const s32 fd, void* buf, u64 count, u64 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 WriteV(const s32 fd, const OrbisKernelIovec* iov, u32 iovcnt) override; + s64 PWriteV(const s32 fd, const OrbisKernelIovec* iov, u32 iovcnt, s64 offset) override; s32 MKDir(const fs::path& path, u16 mode = 0755) override; s32 RMDir(const fs::path& path) override; - s32 Stat(const fs::path& path, Libraries::Kernel::OrbisKernelStat* statbuf) override; - s32 FStat(const s32 fd, Libraries::Kernel::OrbisKernelStat* statbuf) override; + s32 Stat(const fs::path& path, OrbisKernelStat* statbuf) override; + s32 FStat(const s32 fd, OrbisKernelStat* statbuf) override; s32 Chmod(const fs::path& path, u16 mode) override; s32 FChmod(const s32 fd, u16 mode) override; diff --git a/src/core/file_sys/hostio/host_io_win32.h b/src/core/file_sys/hostio/host_io_win32.h index f00d3fbb7..7150eff23 100644 --- a/src/core/file_sys/hostio/host_io_win32.h +++ b/src/core/file_sys/hostio/host_io_win32.h @@ -91,17 +91,21 @@ public: s32 Truncate(const fs::path& path, u64 size) override; s32 FTruncate(const s32 fd, u64 size) override; - s64 Write(const s32 fd, const void* buf, u64 count) override; s64 Read(const s32 fd, void* buf, u64 count) override; - - s64 PWrite(const s32 fd, const void* buf, u64 count, u64 offset) override; s64 PRead(const s32 fd, void* buf, u64 count, u64 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 WriteV(const s32 fd, const OrbisKernelIovec* iov, u32 iovcnt) override; + s64 PWriteV(const s32 fd, const OrbisKernelIovec* iov, u32 iovcnt, s64 offset) override; s32 MKDir(const fs::path& path, u16 mode = 0755) override; s32 RMDir(const fs::path& path) override; - // s32 Stat(const fs::path& path, Libraries::Kernel::OrbisKernelStat* statbuf) override; - // s32 FStat(const s32 fd, Libraries::Kernel::OrbisKernelStat* statbuf) override; + // s32 Stat(const fs::path& path, OrbisKernelStat* statbuf) override; + // s32 FStat(const s32 fd, OrbisKernelStat* statbuf) override; // s32 Chmod(const fs::path& path, u16 mode) override; // s32 FChmod(const s32 fd, u16 mode) 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 900dc4e81..c19e33a8f 100644 --- a/src/core/file_sys/hostio/src/host_io_base.cpp +++ b/src/core/file_sys/hostio/src/host_io_base.cpp @@ -17,37 +17,45 @@ HostIO_Base::~HostIO_Base() = default; // clang-format off s32 HostIO_Base::Open(const fs::path& path, int flags, u16 mode) { STUB(); } -s32 HostIO_Base::Creat(const fs::path& path, u16 mode) { STUB() } -s32 HostIO_Base::Close(const s32 fd) { STUB() } +s32 HostIO_Base::Creat(const fs::path& path, u16 mode) { STUB(); } +s32 HostIO_Base::Close(const s32 fd) { STUB(); } -s32 HostIO_Base::Link(const fs::path& src, const fs::path& dst) { STUB() } -s32 HostIO_Base::Unlink(const fs::path& path) { STUB() } -s32 HostIO_Base::LinkSymbolic(const fs::path& src, const fs::path& dst) { STUB() } +s32 HostIO_Base::Link(const fs::path& src, const fs::path& dst) { STUB(); } +s32 HostIO_Base::Unlink(const fs::path& path) { STUB(); } +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::Tell(const s32 fd) { 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::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() } +s32 HostIO_Base::Truncate(const fs::path& path, u64 size) { STUB(); } +s32 HostIO_Base::FTruncate(const s32 fd, u64 size) { STUB(); } -s64 HostIO_Base::Write(const s32 fd, const void* buf, u64 count) { STUB() } -s64 HostIO_Base::Read(const s32 fd, void* buf, u64 count) { 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::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::PWrite(const s32 fd, const void* buf, u64 count, u64 offset) { STUB() } -s64 HostIO_Base::PRead(const s32 fd, void* buf, u64 count, u64 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::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(); } -s32 HostIO_Base::MKDir(const fs::path& path, u16 mode) { STUB() } -s32 HostIO_Base::RMDir(const fs::path& path) { STUB() } +s32 HostIO_Base::MKDir(const fs::path& path, u16 mode) { STUB(); } +s32 HostIO_Base::RMDir(const fs::path& path) { STUB(); } -s32 HostIO_Base::Stat(const fs::path& path, Libraries::Kernel::OrbisKernelStat* statbuf) { STUB() } -s32 HostIO_Base::FStat(const s32 fd, Libraries::Kernel::OrbisKernelStat* statbuf) { STUB() } +s32 HostIO_Base::Stat(const fs::path& path, OrbisKernelStat* statbuf) { STUB(); } +s32 HostIO_Base::FStat(const s32 fd, OrbisKernelStat* statbuf) { STUB(); } -s32 HostIO_Base::Chmod(const fs::path& path, u16 mode) { STUB() } -s32 HostIO_Base::FChmod(const s32 fd, u16 mode) { STUB() } +s32 HostIO_Base::Chmod(const fs::path& path, u16 mode) { STUB(); } +s32 HostIO_Base::FChmod(const s32 fd, u16 mode) { STUB(); } -s64 HostIO_Base::GetDents(s32 fd, void* buf, u32 nbytes, s64* basep) { STUB() } +s64 HostIO_Base::GetDents(s32 fd, void* buf, u32 nbytes, s64* basep) { + STUB() +} // clang-format on } // namespace HostIODriver \ No newline at end of file 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 59a9d5ccc..c5bb24c6b 100644 --- a/src/core/file_sys/hostio/src/host_io_base.h +++ b/src/core/file_sys/hostio/src/host_io_base.h @@ -12,10 +12,9 @@ namespace HostIODriver { namespace fs = std::filesystem; using namespace QuasiFS; +using namespace Libraries::Kernel; class HostIO_Base { - -protected: public: HostIO_Base(); ~HostIO_Base(); @@ -37,15 +36,22 @@ public: virtual s32 FTruncate(const s32 fd, u64 size); virtual s64 LSeek(const s32 fd, u64 offset, QuasiFS::SeekOrigin origin); virtual s64 Tell(const s32 fd); - 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 Read(const s32 fd, void* buf, u64 count); virtual s64 PRead(const s32 fd, void* buf, u64 count, u64 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 WriteV(const s32 fd, const OrbisKernelIovec* iov, u32 iovcnt); + virtual s64 PWriteV(const s32 fd, const OrbisKernelIovec* iov, u32 iovcnt, s64 offset); + virtual s32 MKDir(const fs::path& path, u16 mode = 0755); virtual s32 RMDir(const fs::path& path); - virtual s32 Stat(const fs::path& path, Libraries::Kernel::OrbisKernelStat* statbuf); - virtual s32 FStat(const s32 fd, Libraries::Kernel::OrbisKernelStat* statbuf); + virtual s32 Stat(const fs::path& path, OrbisKernelStat* statbuf); + virtual s32 FStat(const s32 fd, OrbisKernelStat* statbuf); virtual s32 Chmod(const fs::path& path, u16 mode); virtual s32 FChmod(const s32 fd, u16 mode); 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 8a96935e3..81d751777 100644 --- a/src/core/file_sys/hostio/src/host_io_posix.cpp +++ b/src/core/file_sys/hostio/src/host_io_posix.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "core/file_sys/hostio/host_io_posix.h" @@ -89,28 +90,80 @@ s32 HostIO_POSIX::FTruncate(const s32 fd, u64 size) { return status >= 0 ? status : -errno; } -s64 HostIO_POSIX::Write(const s32 fd, const void* buf, u64 count) { - errno = 0; - s32 status = write(fd, buf, count); - return status >= 0 ? status : -errno; -} - s64 HostIO_POSIX::Read(const s32 fd, void* buf, u64 count) { errno = 0; s32 status = read(fd, buf, count); return status >= 0 ? status : -errno; } +s64 HostIO_POSIX::PRead(const s32 fd, void* buf, u64 count, u64 offset) { + errno = 0; + s32 status = pread(fd, buf, count, offset); + return status >= 0 ? status : -errno; +} + +s64 HostIO_POSIX::ReadV(const s32 fd, OrbisKernelIovec* iov, u32 iovcnt) { + errno = 0; + + iovec* iov_native = new iovec[iovcnt]; + for (s32 idx = 0; idx < iovcnt; idx++) + iov_native[idx] = {.iov_base = iov[idx].iov_base, .iov_len = iov[idx].iov_len}; + + s64 ret = readv(fd, iov_native, iovcnt); + delete[] iov_native; + + return ret; +} + +s64 HostIO_POSIX::PReadV(const s32 fd, OrbisKernelIovec* iov, u32 iovcnt, s64 offset) { + errno = 0; + + iovec* iov_native = new iovec[iovcnt]; + for (s32 idx = 0; idx < iovcnt; idx++) + iov_native[idx] = {.iov_base = iov[idx].iov_base, .iov_len = iov[idx].iov_len}; + + s64 ret = preadv(fd, iov_native, iovcnt, offset); + delete[] iov_native; + + return ret; +} + +s64 HostIO_POSIX::Write(const s32 fd, const void* buf, u64 count) { + errno = 0; + s32 status = write(fd, buf, count); + return status >= 0 ? status : -errno; +} + s64 HostIO_POSIX::PWrite(const s32 fd, const void* buf, u64 count, u64 offset) { errno = 0; s32 status = pwrite(fd, buf, count, offset); return status >= 0 ? status : -errno; } -s64 HostIO_POSIX::PRead(const s32 fd, void* buf, u64 count, u64 offset) { +s64 HostIO_POSIX::WriteV(const s32 fd, const OrbisKernelIovec* iov, u32 iovcnt) { errno = 0; - s32 status = pread(fd, buf, count, offset); - return status >= 0 ? status : -errno; + + iovec* iov_native = new iovec[iovcnt]; + for (s32 idx = 0; idx < iovcnt; idx++) + iov_native[idx] = {.iov_base = iov[idx].iov_base, .iov_len = iov[idx].iov_len}; + + s64 ret = writev(fd, iov_native, iovcnt); + delete[] iov_native; + + return ret; +} + +s64 HostIO_POSIX::PWriteV(const s32 fd, const OrbisKernelIovec* iov, u32 iovcnt, s64 offset) { + errno = 0; + + iovec* iov_native = new iovec[iovcnt]; + for (s32 idx = 0; idx < iovcnt; idx++) + iov_native[idx] = {.iov_base = iov[idx].iov_base, .iov_len = iov[idx].iov_len}; + + s64 ret = pwritev(fd, iov_native, iovcnt, offset); + delete[] iov_native; + + return ret; } s32 HostIO_POSIX::MKDir(const fs::path& path, u16 mode) { @@ -125,7 +178,7 @@ s32 HostIO_POSIX::RMDir(const fs::path& path) { return 0 == status ? status : -errno; } -s32 HostIO_POSIX::Stat(const fs::path& path, Libraries::Kernel::OrbisKernelStat* statbuf) { +s32 HostIO_POSIX::Stat(const fs::path& path, OrbisKernelStat* statbuf) { errno = 0; struct stat st; @@ -158,7 +211,7 @@ s32 HostIO_POSIX::Stat(const fs::path& path, Libraries::Kernel::OrbisKernelStat* return 0; } -s32 HostIO_POSIX::FStat(const s32 fd, Libraries::Kernel::OrbisKernelStat* statbuf) { +s32 HostIO_POSIX::FStat(const s32 fd, OrbisKernelStat* statbuf) { errno = 0; struct stat st; 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 f97a7e780..ca73793ce 100644 --- a/src/core/file_sys/hostio/src/host_io_virtual.cpp +++ b/src/core/file_sys/hostio/src/host_io_virtual.cpp @@ -200,24 +200,9 @@ s32 HostIO_Virtual::FTruncate(const s32 fd, u64 size) { if (nullptr == node) return -QUASI_EBADF; - // if (node->is_dir()) - // return -QUASI_EISDIR; - - // if (!node->is_file()) - // return -QUASI_EINVAL; - return handle->node->ftruncate(size); } -s64 HostIO_Virtual::Write(const s32 fd, const void* buf, u64 count) { - s64 bw = this->PWrite(fd, buf, count, handle->pos); - - if (bw > 0) - handle->pos += bw; - - return bw; -} - s64 HostIO_Virtual::Read(const s32 fd, void* buf, u64 count) { s64 br = PRead(fd, buf, count, handle->pos); @@ -227,6 +212,51 @@ 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) { + if (nullptr == handle) + return -QUASI_EINVAL; + + inode_ptr node = handle->node; + + if (nullptr == node) + return -QUASI_EBADF; + + return node->pread(buf, count, offset); +} + +s64 HostIO_Virtual::ReadV(const s32 fd, OrbisKernelIovec* iov, u32 iovcnt) { + s64 br = PReadV(fd, iov, iovcnt, handle->pos); + + if (br > 0) + handle->pos += br; + + return br; +} + +s64 HostIO_Virtual::PReadV(const s32 fd, OrbisKernelIovec* iov, u32 iovcnt, s64 offset) { + if (nullptr == handle) + return -QUASI_EBADF; + + inode_ptr node = handle->node; + + if (nullptr == node) + return -QUASI_EBADF; + + if (handle->append) + offset = node->st.st_size; + + return node->preadv(iov, iovcnt, offset); +} + +s64 HostIO_Virtual::Write(const s32 fd, const void* buf, u64 count) { + s64 bw = this->PWrite(fd, buf, count, handle->pos); + + if (bw > 0) + handle->pos += bw; + + return bw; +} + s64 HostIO_Virtual::PWrite(const s32 fd, const void* buf, u64 count, u64 offset) { if (nullptr == handle) return -QUASI_EBADF; @@ -242,16 +272,28 @@ s64 HostIO_Virtual::PWrite(const s32 fd, const void* buf, u64 count, u64 offset) return node->pwrite(buf, count, offset); } -s64 HostIO_Virtual::PRead(const s32 fd, void* buf, u64 count, u64 offset) { +s64 HostIO_Virtual::WriteV(const s32 fd, const OrbisKernelIovec* iov, u32 iovcnt) { + s64 bw = this->PWriteV(fd, iov, iovcnt, handle->pos); + + if (bw > 0) + handle->pos += bw; + + return bw; +} + +s64 HostIO_Virtual::PWriteV(const s32 fd, const OrbisKernelIovec* iov, u32 iovcnt, s64 offset) { if (nullptr == handle) - return -QUASI_EINVAL; + return -QUASI_EBADF; inode_ptr node = handle->node; if (nullptr == node) return -QUASI_EBADF; - return node->pread(buf, count, offset); + if (handle->append) + offset = node->st.st_size; + + return node->pwritev(iov, iovcnt, offset); } s32 HostIO_Virtual::MKDir(const fs::path& path, u16 mode) { @@ -286,7 +328,7 @@ s32 HostIO_Virtual::RMDir(const fs::path& path) { return 0; } -s32 HostIO_Virtual::Stat(const fs::path& path, Libraries::Kernel::OrbisKernelStat* statbuf) { +s32 HostIO_Virtual::Stat(const fs::path& path, OrbisKernelStat* statbuf) { if (nullptr == this->res) return -QUASI_EINVAL; @@ -295,12 +337,12 @@ s32 HostIO_Virtual::Stat(const fs::path& path, Libraries::Kernel::OrbisKernelSta if (nullptr == node) return -QUASI_ENOENT; - memcpy(statbuf, &node->st, sizeof(Libraries::Kernel::OrbisKernelStat)); + memcpy(statbuf, &node->st, sizeof(OrbisKernelStat)); return 0; } -s32 HostIO_Virtual::FStat(const s32 fd, Libraries::Kernel::OrbisKernelStat* statbuf) { +s32 HostIO_Virtual::FStat(const s32 fd, OrbisKernelStat* statbuf) { if (nullptr == this->handle) return -QUASI_EINVAL; @@ -309,7 +351,7 @@ s32 HostIO_Virtual::FStat(const s32 fd, Libraries::Kernel::OrbisKernelStat* stat if (nullptr == node) return -QUASI_EBADF; - memcpy(statbuf, &node->st, sizeof(Libraries::Kernel::OrbisKernelStat)); + memcpy(statbuf, &node->st, sizeof(OrbisKernelStat)); return 0; } @@ -350,7 +392,7 @@ s64 HostIO_Virtual::GetDents(s32 fd, void* buf, u32 nbytes, s64* basep) { if (nullptr != basep) *basep = handle->pos; - s64 br = node->getdents(buf + handle->pos, nbytes, basep); + s64 br = node->getdents(static_cast(buf) + handle->pos, nbytes, basep); if (br > 0) handle->pos += br; 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 2e226345e..a37273042 100644 --- a/src/core/file_sys/hostio/src/host_io_win32.cpp +++ b/src/core/file_sys/hostio/src/host_io_win32.cpp @@ -84,31 +84,12 @@ int HostIO_Win32::FTruncate(const s32 fd, u64 size) { return status >= 0 ? status : -errno; } -s64 HostIO_Win32::Write(const s32 fd, const void* buf, u64 count) { - errno = 0; - s32 status = _write(fd, buf, count); - return status >= 0 ? status : -errno; -} - s64 HostIO_Win32::Read(const s32 fd, void* buf, u64 count) { errno = 0; s32 status = _read(fd, buf, count); return status >= 0 ? status : -errno; } -s64 HostIO_Win32::PWrite(const s32 fd, const void* buf, u64 count, u64 offset) { - errno = 0; - s64 bak = LSeek(fd, 0, SeekOrigin::CURRENT); - if (bak < 0) - return -errno; - LSeek(fd, offset, SeekOrigin::ORIGIN); - - s32 status = _write(fd, buf, count); - - LSeek(fd, bak, SeekOrigin::ORIGIN); - return status >= 0 ? status : -errno; -} - s64 HostIO_Win32::PRead(const s32 fd, void* buf, u64 count, u64 offset) { errno = 0; s64 bak = LSeek(fd, 0, SeekOrigin::CURRENT); @@ -122,6 +103,25 @@ s64 HostIO_Win32::PRead(const s32 fd, void* buf, u64 count, u64 offset) { return status >= 0 ? status : -errno; } +s64 HostIO_Win32::Write(const s32 fd, const void* buf, u64 count) { + errno = 0; + s32 status = _write(fd, buf, count); + return status >= 0 ? status : -errno; +} + +s64 HostIO_Win32::PWrite(const s32 fd, const void* buf, u64 count, u64 offset) { + errno = 0; + s64 bak = LSeek(fd, 0, SeekOrigin::CURRENT); + if (bak < 0) + return -errno; + LSeek(fd, offset, SeekOrigin::ORIGIN); + + s32 status = _write(fd, buf, count); + + LSeek(fd, bak, SeekOrigin::ORIGIN); + return status >= 0 ? status : -errno; +} + s32 HostIO_Win32::MKDir(const fs::path& path, u16 mode) { errno = 0; s32 status = _wmkdir(path.c_str()); diff --git a/src/core/file_sys/quasifs/quasi_types.h b/src/core/file_sys/quasifs/quasi_types.h index 46aa08c85..a7c1fc5e8 100644 --- a/src/core/file_sys/quasifs/quasi_types.h +++ b/src/core/file_sys/quasifs/quasi_types.h @@ -108,4 +108,5 @@ typedef struct mount_t { dir_ptr parentdir; unsigned int options; } mount_t; + } // namespace QuasiFS \ No newline at end of file diff --git a/src/core/file_sys/quasifs/quasifs.h b/src/core/file_sys/quasifs/quasifs.h index 4f17b2dab..867e9a0f8 100644 --- a/src/core/file_sys/quasifs/quasifs.h +++ b/src/core/file_sys/quasifs/quasifs.h @@ -73,10 +73,20 @@ private: s32 FTruncate(const s32 fd, u64 size) override; s64 LSeek(const s32 fd, u64 offset, SeekOrigin origin) override; s64 Tell(const s32 fd) 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 Read(const s32 fd, void* buf, u64 count) override; s64 PRead(const s32 fd, void* buf, u64 count, u64 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 WriteV(const s32 fd, const Libraries::Kernel::OrbisKernelIovec* iov, + u32 iovcnt) override; + s64 PWriteV(const s32 fd, const Libraries::Kernel::OrbisKernelIovec* iov, u32 iovcnt, + s64 offset) override; + s32 MKDir(const fs::path& path, u16 mode = 0755) override; s32 RMDir(const fs::path& path) override; diff --git a/src/core/file_sys/quasifs/quasifs_inode.h b/src/core/file_sys/quasifs/quasifs_inode.h index d2994347f..c4f9c43bd 100644 --- a/src/core/file_sys/quasifs/quasifs_inode.h +++ b/src/core/file_sys/quasifs/quasifs_inode.h @@ -16,6 +16,8 @@ namespace QuasiFS { +static_assert(sizeof(time_t) == 8, "Time is not stored in 64 bits"); + class Inode { public: Inode() { @@ -24,8 +26,6 @@ public: st.st_uid = 0; st.st_gid = 0; - static_assert(sizeof(time_t) == 8, "Time is not stored in 64 bits"); - st.st_birthtim.tv_sec = time(0); st.st_birthtim.tv_nsec = 0; st.st_ctim.tv_sec = time(0); @@ -42,17 +42,6 @@ public: return -QUASI_ENOTTY; } - // these don't make sense with anything that's not a device - // kept here to verify - virtual s64 read(void* buf, u64 count) { - return -QUASI_EBADF; - } - - virtual s64 write(const void* buf, u64 count) { - return -QUASI_EBADF; - } - - // these 4 make sense everywhere virtual s64 pread(void* buf, u64 count, s64 offset) { return -QUASI_EBADF; } @@ -61,29 +50,7 @@ public: return -QUASI_EBADF; } - virtual s64 readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) { - u64 tb = 0; - for (unsigned int idx = 0; idx < iovcnt; idx++) { - int status = this->read(iov[idx].iov_base, iov[idx].iov_len); - if (status < 0) - return status; - tb += status; - } - return tb; - } - - virtual s64 writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) { - u64 tb = 0; - for (unsigned int idx = 0; idx < iovcnt; idx++) { - int status = this->write(iov[idx].iov_base, iov[idx].iov_len); - if (status < 0) - return status; - tb += status; - } - return tb; - } - - virtual s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, s64 offset) { + virtual s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, u32 iovcnt, s64 offset) { u64 tb = 0; for (unsigned int idx = 0; idx < iovcnt; idx++) { int status = this->pread(iov[idx].iov_base, iov[idx].iov_len, offset); @@ -94,7 +61,7 @@ public: return tb; } - virtual s64 pwritev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, s64 offset) { + virtual s64 pwritev(const Libraries::Kernel::OrbisKernelIovec* iov, u32 iovcnt, s64 offset) { u64 tb = 0; for (unsigned int idx = 0; idx < iovcnt; idx++) { int status = this->pwrite(iov[idx].iov_base, iov[idx].iov_len, offset); 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 4a69d9070..6e04a4cb4 100644 --- a/src/core/file_sys/quasifs/quasifs_inode_quasi_device.h +++ b/src/core/file_sys/quasifs/quasifs_inode_quasi_device.h @@ -22,8 +22,11 @@ public: UNREACHABLE(); } - s64 pread(void* buf, u64 count, s64 offset) override; - s64 pwrite(const void* buf, u64 count, s64 offset) override; + virtual s64 read(void* buf, u64 count); + virtual s64 write(const void* buf, u64 count); + + s64 pread(void* buf, u64 count, s64 offset) final override; + s64 pwrite(const void* buf, u64 count, s64 offset) final override; }; } // namespace QuasiFS \ No newline at end of file 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 a0b081606..3391f5121 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 @@ -33,7 +33,6 @@ private: public: DirectoryPFS() = default; ~DirectoryPFS() = default; - }; } // namespace QuasiFS \ No newline at end of file diff --git a/src/core/file_sys/quasifs/quasifs_partition.h b/src/core/file_sys/quasifs/quasifs_partition.h index bd05d0980..04666c01c 100644 --- a/src/core/file_sys/quasifs/quasifs_partition.h +++ b/src/core/file_sys/quasifs/quasifs_partition.h @@ -30,22 +30,19 @@ private: const fs::path host_root{}; // IO block size, allocation unit (multiples of 512) - u32 ioblock_size{4096}; + const u32 ioblock_size{4096}; // amount of raw on-disk blocks per io block // this is pretty much so we don't recalculate it over and over and over // and - u32 block_size{512}; - - u8 filesystem_format = FileSystem::NORMAL; + const u32 block_size{512}; public: // host-bound directory, permissions for root directory - Partition(const fs::path& host_root = ""); + Partition(); + Partition(const fs::path& host_root = "", const int root_permissions = 0755, + const u32 block_size = 512, const u32 ioblock_size = 4096); ~Partition() = default; - void Format(const int root_permissions = 0755, u8 format = FileSystem::NORMAL, - const u32 block_size = 512, const u32 ioblock_size = 4096); - template static partition_ptr Create(Args&&... args) { return std::make_shared(std::forward(args)...); diff --git a/src/core/file_sys/quasifs/src/quasifs.cpp b/src/core/file_sys/quasifs/src/quasifs.cpp index 4b77a084f..9839acffc 100644 --- a/src/core/file_sys/quasifs/src/quasifs.cpp +++ b/src/core/file_sys/quasifs/src/quasifs.cpp @@ -5,10 +5,10 @@ #include "core/file_sys/quasifs/quasi_errno.h" #include "core/file_sys/quasifs/quasi_types.h" #include "core/file_sys/quasifs/quasifs.h" -#include "core/file_sys/quasifs/quasifs_inode_quasi_file_virtual.h" #include "core/file_sys/quasifs/quasifs_inode_quasi_directory.h" #include "core/file_sys/quasifs/quasifs_inode_quasi_directory_pfs.h" #include "core/file_sys/quasifs/quasifs_inode_quasi_file.h" +#include "core/file_sys/quasifs/quasifs_inode_quasi_file_virtual.h" #include "core/file_sys/quasifs/quasifs_inode_symlink.h" #include "core/file_sys/quasifs/quasifs_partition.h" diff --git a/src/core/file_sys/quasifs/src/quasifs_inode_quasi_device.cpp b/src/core/file_sys/quasifs/src/quasifs_inode_quasi_device.cpp index 622f213eb..77534c1c6 100644 --- a/src/core/file_sys/quasifs/src/quasifs_inode_quasi_device.cpp +++ b/src/core/file_sys/quasifs/src/quasifs_inode_quasi_device.cpp @@ -15,6 +15,14 @@ Device::Device() { Device::~Device() = default; +s64 Device::read(void* buf, u64 count) { + return -QUASI_EBADF; +} + +s64 Device::write(const void* buf, u64 count) { + return -QUASI_EBADF; +} + s64 Device::pread(void* buf, u64 count, s64 offset) { return read(buf, count); } diff --git a/src/core/file_sys/quasifs/src/quasifs_partition.cpp b/src/core/file_sys/quasifs/src/quasifs_partition.cpp index bc2e21ead..ac300fdd2 100644 --- a/src/core/file_sys/quasifs/src/quasifs_partition.cpp +++ b/src/core/file_sys/quasifs/src/quasifs_partition.cpp @@ -12,28 +12,14 @@ namespace QuasiFS { -Partition::Partition(const fs::path& host_root) - : block_id(next_block_id++), host_root(host_root.lexically_normal()) {} - -void Partition::Format(const int root_permissions, u8 format, const u32 block_size, - const u32 ioblock_size) { - this->inode_table.clear(); - this->next_fileno = 2; - this->ioblock_size = ioblock_size; - this->block_size = block_size; - this->filesystem_format = format; - - switch (format) { - default: - LOG_ERROR(Kernel_Fs, "Unknown target partition type. Defaulting to normal"); - case FileSystem::NORMAL: - this->root = Directory::Create(); - break; - case FileSystem::PFS: - this->root = Directory::Create(); - break; - } +Partition::Partition() : Partition("", 0755, 512, 4096) {} +Partition::Partition(const fs::path& host_root, const int root_permissions, const u32 block_size, + const u32 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); IndexInode(this->root); mkrelative(this->root, this->root); diff --git a/src/core/file_sys/quasifs/src/quasifs_vdriver.cpp b/src/core/file_sys/quasifs/src/quasifs_vdriver.cpp index a464d9687..2403053de 100644 --- a/src/core/file_sys/quasifs/src/quasifs_vdriver.cpp +++ b/src/core/file_sys/quasifs/src/quasifs_vdriver.cpp @@ -512,6 +512,143 @@ void UpdateStatFromHost(Libraries::Kernel::OrbisKernelStat* vfs, vfs->st_ctim = host->st_ctim; } +s64 QFS::OperationImpl::Read(const s32 fd, void* buf, u64 count) { + if (fd < 0) + return -QUASI_EBADF; + + fd_handle_ptr handle = qfs.GetHandle(fd); + if (nullptr == handle) + return -QUASI_EBADF; + + if (!handle->read) + return -QUASI_EBADF; + + bool host_used = false; + int hio_status = 0; + int vio_status = 0; + + if (handle->IsHostBound()) { + int host_fd = handle->host_fd; + if (hio_status = qfs.hio_driver.Read(host_fd, buf, count); 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.Read(fd, buf, count); + qfs.vio_driver.ClearCtx(); + + if (host_used && (hio_status != vio_status)) + LOG_ERROR(Kernel_Fs, "Host returned {}, but virtual driver returned {}", hio_status, + vio_status); + + return vio_status; +} + +s64 QFS::OperationImpl::PRead(const s32 fd, void* buf, u64 count, u64 offset) { + if (fd < 0) + return -QUASI_EBADF; + + fd_handle_ptr handle = qfs.GetHandle(fd); + if (nullptr == handle) + return -QUASI_EBADF; + + if (!handle->read) + return -QUASI_EBADF; + + bool host_used = false; + int hio_status = 0; + int vio_status = 0; + + if (handle->IsHostBound()) { + int host_fd = handle->host_fd; + if (hio_status = qfs.hio_driver.PRead(host_fd, buf, count, offset); 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.PRead(fd, buf, count, offset); + qfs.vio_driver.ClearCtx(); + + if (host_used && (hio_status != vio_status)) + LOG_ERROR(Kernel_Fs, "Host returned {}, but virtual driver returned {}", hio_status, + vio_status); + + return vio_status; +}; + +s64 QFS::OperationImpl::ReadV(const s32 fd, Libraries::Kernel::OrbisKernelIovec* iov, u32 iovcnt) { + if (fd < 0) + return -QUASI_EBADF; + + fd_handle_ptr handle = qfs.GetHandle(fd); + if (nullptr == handle) + return -QUASI_EBADF; + + if (!handle->read) + return -QUASI_EBADF; + + bool host_used = false; + int hio_status = 0; + int vio_status = 0; + + if (handle->IsHostBound()) { + int host_fd = handle->host_fd; + if (hio_status = qfs.hio_driver.ReadV(host_fd, iov, iovcnt); 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.ReadV(fd, iov, iovcnt); + qfs.vio_driver.ClearCtx(); + + if (host_used && (hio_status != vio_status)) + LOG_ERROR(Kernel_Fs, "Host returned {}, but virtual driver returned {}", hio_status, + vio_status); + + return vio_status; +} + +s64 QFS::OperationImpl::PReadV(const s32 fd, Libraries::Kernel::OrbisKernelIovec* iov, u32 iovcnt, + s64 offset) { + if (fd < 0) + return -QUASI_EBADF; + + fd_handle_ptr handle = qfs.GetHandle(fd); + if (nullptr == handle) + return -QUASI_EBADF; + + if (!handle->read) + return -QUASI_EBADF; + + bool host_used = false; + int hio_status = 0; + int vio_status = 0; + + if (handle->IsHostBound()) { + int host_fd = handle->host_fd; + if (hio_status = qfs.hio_driver.PReadV(host_fd, iov, iovcnt, offset); 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.PReadV(fd, iov, iovcnt, offset); + qfs.vio_driver.ClearCtx(); + + if (host_used && (hio_status != vio_status)) + LOG_ERROR(Kernel_Fs, "Host returned {}, but virtual driver returned {}", hio_status, + vio_status); + + return vio_status; +} + s64 QFS::OperationImpl::Write(const s32 fd, const void* buf, u64 count) { if (fd < 0) return -QUASI_EBADF; @@ -580,7 +717,8 @@ s64 QFS::OperationImpl::PWrite(const s32 fd, const void* buf, u64 count, u64 off return vio_status; }; -s64 QFS::OperationImpl::Read(const s32 fd, void* buf, u64 count) { +s64 QFS::OperationImpl::WriteV(const s32 fd, const Libraries::Kernel::OrbisKernelIovec* iov, + u32 iovcnt) { if (fd < 0) return -QUASI_EBADF; @@ -588,7 +726,7 @@ s64 QFS::OperationImpl::Read(const s32 fd, void* buf, u64 count) { if (nullptr == handle) return -QUASI_EBADF; - if (!handle->read) + if (!handle->write) return -QUASI_EBADF; bool host_used = false; @@ -597,14 +735,14 @@ s64 QFS::OperationImpl::Read(const s32 fd, void* buf, u64 count) { if (handle->IsHostBound()) { int host_fd = handle->host_fd; - if (hio_status = qfs.hio_driver.Read(host_fd, buf, count); hio_status < 0) + if (hio_status = qfs.hio_driver.WriteV(host_fd, iov, iovcnt); 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.Read(fd, buf, count); + vio_status = qfs.vio_driver.WriteV(fd, iov, iovcnt); qfs.vio_driver.ClearCtx(); if (host_used && (hio_status != vio_status)) @@ -614,7 +752,8 @@ 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::PWriteV(const s32 fd, const Libraries::Kernel::OrbisKernelIovec* iov, + u32 iovcnt, s64 offset) { if (fd < 0) return -QUASI_EBADF; @@ -622,7 +761,7 @@ s64 QFS::OperationImpl::PRead(const s32 fd, void* buf, u64 count, u64 offset) { if (nullptr == handle) return -QUASI_EBADF; - if (!handle->read) + if (!handle->write) return -QUASI_EBADF; bool host_used = false; @@ -631,14 +770,14 @@ s64 QFS::OperationImpl::PRead(const s32 fd, void* buf, u64 count, u64 offset) { if (handle->IsHostBound()) { int host_fd = handle->host_fd; - if (hio_status = qfs.hio_driver.PRead(host_fd, buf, count, offset); hio_status < 0) + if (hio_status = qfs.hio_driver.PWriteV(host_fd, iov, iovcnt, offset); 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.PRead(fd, buf, count, offset); + vio_status = qfs.vio_driver.PWriteV(fd, iov, iovcnt, offset); qfs.vio_driver.ClearCtx(); if (host_used && (hio_status != vio_status)) @@ -646,7 +785,7 @@ s64 QFS::OperationImpl::PRead(const s32 fd, void* buf, u64 count, u64 offset) { vio_status); return vio_status; -}; +} s32 QFS::OperationImpl::MKDir(const fs::path& path, u16 mode) { Resolved res; diff --git a/src/emulator.cpp b/src/emulator.cpp index b32b71250..848a3bda0 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -93,27 +93,15 @@ Emulator::~Emulator() {} void Emulator::LoadFilesystem(const std::filesystem::path& game_folder) { auto* qfs = Common::Singleton::Instance(); - qfs->Operation.MKDir("/app0", 0555); - qfs->Operation.MKDir("/hostapp", 0555); - qfs::partition_ptr partition_app0 = qfs::Partition::Create(game_folder); - partition_app0->Format(0555, qfs::FileSystem::PFS, 512, 65536); - - qfs->Mount("/app0", partition_app0, qfs::MountOptions::MOUNT_NOOPT); - qfs->Mount("/hostapp", partition_app0, - qfs::MountOptions::MOUNT_NOOPT | qfs::MountOptions::MOUNT_BIND); - - qfs->Operation.Chmod("/", 0777); + qfs::partition_ptr partition_app0 = qfs::Partition::Create(game_folder, 0555, 512, 65536); qfs::partition_ptr partition_av_contents = qfs::Partition::Create("", 0775, 512, 16384); qfs::partition_ptr partition_av_contents_photo = qfs::Partition::Create("", 0755, 4096, 32768); qfs::partition_ptr partition_av_contents_thumbs = qfs::Partition::Create("", 0755, 4096, 32768); qfs::partition_ptr partition_av_contents_video = qfs::Partition::Create("", 0755, 4096, 32768); qfs::partition_ptr partition_dev = qfs::Partition::Create("", 0755, 16384, 16384); - partition_app0->Format(0555, qfs::FileSystem::PFS, 512, 65536); - partition_app0->Format(0555, qfs::FileSystem::PFS, 512, 65536); - partition_app0->Format(0555, qfs::FileSystem::PFS, 512, 65536); - partition_app0->Format(0555, qfs::FileSystem::PFS, 512, 65536); - + qfs->Operation.MKDir("/app0", 0555); + qfs->Operation.MKDir("/hostapp", 0555); qfs->Operation.MKDir("/av_contents", 0775); qfs->Operation.MKDir("/av_contents/photo", 0755); qfs->Operation.MKDir("/av_contents/thumbnails", 0755); @@ -125,6 +113,7 @@ void Emulator::LoadFilesystem(const std::filesystem::path& game_folder) { qfs->Operation.MKDir("/temp", 0777); qfs->Operation.MKDir("/temp0", 0777); + qfs->Mount("/app0", partition_app0, qfs::MountOptions::MOUNT_NOOPT); qfs->Mount("/av_contents", partition_av_contents, qfs::MountOptions::MOUNT_RW); qfs->Mount("/av_contents/photo", partition_av_contents_photo, qfs::MountOptions::MOUNT_RW); qfs->Mount("/av_contents/thumbnails", partition_av_contents_thumbs, @@ -132,6 +121,8 @@ void Emulator::LoadFilesystem(const std::filesystem::path& game_folder) { qfs->Mount("/av_contents/video", partition_av_contents_video, qfs::MountOptions::MOUNT_RW); qfs->Mount("/dev", partition_dev, qfs::MountOptions::MOUNT_RW); + qfs->Mount("/hostapp", partition_app0, + qfs::MountOptions::MOUNT_NOOPT | qfs::MountOptions::MOUNT_BIND); // // Setup /dev @@ -286,7 +277,7 @@ void Emulator::Run(std::filesystem::path file, std::vector args, qfs->Mount("/temp0", partition_temp, qfs::MountOptions::MOUNT_RW | qfs::MountOptions::MOUNT_BIND); qfs->SyncHost("/data"); - qfs->SyncHost("/donwload0"); + qfs->SyncHost("/download0"); qfs->SyncHost("/temp"); qfs->SyncHost("/temp0"); @@ -430,34 +421,34 @@ void Emulator::Run(std::filesystem::path file, std::vector args, g_window = window.get(); // const auto& mount_data_dir = Common::FS::GetUserPath(Common::FS::PathType::GameDataDir) / id; - if (!std::filesystem::exists(mount_data_dir)) { - std::filesystem::create_directory(mount_data_dir); - } - mnt->Mount(mount_data_dir, "/data"); // should just exist, manually create with game serial + // if (!std::filesystem::exists(mount_data_dir)) { + // std::filesystem::create_directory(mount_data_dir); + // } + // mnt->Mount(mount_data_dir, "/data"); // should just exist, manually create with game serial // Mounting temp folders // const auto& mount_temp_dir = Common::FS::GetUserPath(Common::FS::PathType::TempDataDir) / id; - if (std::filesystem::exists(mount_temp_dir)) { - // Temp folder should be cleared on each boot. - std::filesystem::remove_all(mount_temp_dir); - } - std::filesystem::create_directory(mount_temp_dir); - mnt->Mount(mount_temp_dir, "/temp0"); - mnt->Mount(mount_temp_dir, "/temp"); + // if (std::filesystem::exists(mount_temp_dir)) { + // // Temp folder should be cleared on each boot. + // std::filesystem::remove_all(mount_temp_dir); + // } + // std::filesystem::create_directory(mount_temp_dir); + // mnt->Mount(mount_temp_dir, "/temp0"); + // mnt->Mount(mount_temp_dir, "/temp"); // const auto& mount_download_dir = // Common::FS::GetUserPath(Common::FS::PathType::DownloadDir) / id; - if (!std::filesystem::exists(mount_download_dir)) { - std::filesystem::create_directory(mount_download_dir); - } - mnt->Mount(mount_download_dir, "/download0"); + // if (!std::filesystem::exists(mount_download_dir)) { + // std::filesystem::create_directory(mount_download_dir); + // } + // mnt->Mount(mount_download_dir, "/download0"); // const auto& mount_captures_dir = // Common::FS::GetUserPath(Common::FS::PathType::CapturesDir); - if (!std::filesystem::exists(mount_captures_dir)) { - std::filesystem::create_directory(mount_captures_dir); - } - VideoCore::SetOutputDir(mount_captures_dir, id); + // if (!std::filesystem::exists(mount_captures_dir)) { + // std::filesystem::create_directory(mount_captures_dir); + // } + // VideoCore::SetOutputDir(mount_captures_dir, id); // Initialize kernel and library facilities. Libraries::InitHLELibs(&linker->GetHLESymbols());