mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-04-26 12:55:14 -06:00
Implemented vector rw in virtual and posix
Reverted Partition::Format (stupid idea) Minor removals
This commit is contained in:
parent
21748acf46
commit
89b91c6f30
@ -13,6 +13,11 @@
|
||||
|
||||
namespace HostIODriver {
|
||||
|
||||
static_assert(std::is_same_v<decltype(OrbisKernelIovec::iov_base), decltype(iovec::iov_base)>,
|
||||
"IOV base pointer is incompatible with native call");
|
||||
static_assert(std::is_same_v<decltype(OrbisKernelIovec::iov_len), decltype(iovec::iov_len)>,
|
||||
"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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
@ -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);
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#include <dirent.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/unistd.h>
|
||||
|
||||
#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;
|
||||
|
||||
@ -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<char*>(buf) + handle->pos, nbytes, basep);
|
||||
if (br > 0)
|
||||
handle->pos += br;
|
||||
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -108,4 +108,5 @@ typedef struct mount_t {
|
||||
dir_ptr parentdir;
|
||||
unsigned int options;
|
||||
} mount_t;
|
||||
|
||||
} // namespace QuasiFS
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
@ -33,7 +33,6 @@ private:
|
||||
public:
|
||||
DirectoryPFS() = default;
|
||||
~DirectoryPFS() = default;
|
||||
|
||||
};
|
||||
|
||||
} // namespace QuasiFS
|
||||
@ -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 <typename... Args>
|
||||
static partition_ptr Create(Args&&... args) {
|
||||
return std::make_shared<Partition>(std::forward<Args>(args)...);
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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<Directory>();
|
||||
break;
|
||||
case FileSystem::PFS:
|
||||
this->root = Directory::Create<DirectoryPFS>();
|
||||
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<Directory>();
|
||||
// clear defaults, write
|
||||
chmod(this->root, root_permissions);
|
||||
IndexInode(this->root);
|
||||
mkrelative(this->root, this->root);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -93,27 +93,15 @@ Emulator::~Emulator() {}
|
||||
void Emulator::LoadFilesystem(const std::filesystem::path& game_folder) {
|
||||
auto* qfs = Common::Singleton<qfs::QFS>::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<std::string> 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<std::string> 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());
|
||||
|
||||
Loading…
Reference in New Issue
Block a user