1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 02:32:36 +01:00

fs: fix read/read_at/write (Unix)

It's known that too huge read can require multiple syscalls.
This commit is contained in:
Nekotekina 2022-12-25 14:48:56 +03:00 committed by Ivan
parent 2f9cac8d18
commit eeda958f33

View File

@ -1382,24 +1382,55 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
u64 read(void* buffer, u64 count) override u64 read(void* buffer, u64 count) override
{ {
const auto result = ::read(m_fd, buffer, count); u64 result = 0;
ensure(result != -1); // "file::read"
// Loop because (huge?) read can be processed partially
while (auto r = ::read(m_fd, buffer, count))
{
ensure(r > 0); // "file::read"
count -= r;
result += r;
buffer = static_cast<u8*>(buffer) + r;
if (!count)
break;
}
return result; return result;
} }
u64 read_at(u64 offset, void* buffer, u64 count) override u64 read_at(u64 offset, void* buffer, u64 count) override
{ {
const auto result = ::pread(m_fd, buffer, count, offset); u64 result = 0;
ensure(result != -1);
// For safety; see read()
while (auto r = ::pread(m_fd, buffer, count, offset))
{
ensure(r > 0); // "file::read_at"
count -= r;
offset += r;
result += r;
buffer = static_cast<u8*>(buffer) + r;
if (!count)
break;
}
return result; return result;
} }
u64 write(const void* buffer, u64 count) override u64 write(const void* buffer, u64 count) override
{ {
const auto result = ::write(m_fd, buffer, count); u64 result = 0;
ensure(result != -1); // "file::write"
// For safety; see read()
while (auto r = ::write(m_fd, buffer, count))
{
ensure(r > 0); // "file::write"
count -= r;
result += r;
buffer = static_cast<const u8*>(buffer) + r;
if (!count)
break;
}
return result; return result;
} }