1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 22:57:44 +00:00

Kernel: Make File::write() and File::read() return KResultOr<size_t>

Instead of returning a ssize_t where negative values mean error,
we now return KResultOr<size_t> and use the error state to report
errors exclusively.
This commit is contained in:
Andreas Kling 2020-08-04 18:02:23 +02:00
parent 58feebeed2
commit 7a3ab6c517
58 changed files with 223 additions and 229 deletions

View file

@ -132,9 +132,9 @@ bool BlockBasedFS::write_block(unsigned index, const u8* data, size_t count, siz
u32 base_offset = static_cast<u32>(index) * static_cast<u32>(block_size()) + offset;
file_description().seek(base_offset, SEEK_SET);
auto nwritten = file_description().write(data, count);
if (nwritten < 0)
if (nwritten.is_error())
return false;
ASSERT(static_cast<size_t>(nwritten) == count);
ASSERT(nwritten.value() == count);
return true;
}
@ -156,7 +156,8 @@ bool BlockBasedFS::raw_read(unsigned index, u8* buffer)
u32 base_offset = static_cast<u32>(index) * static_cast<u32>(m_logical_block_size);
file_description().seek(base_offset, SEEK_SET);
auto nread = file_description().read(buffer, m_logical_block_size);
ASSERT((size_t)nread == m_logical_block_size);
ASSERT(!nread.is_error());
ASSERT(nread.value() == m_logical_block_size);
return true;
}
bool BlockBasedFS::raw_write(unsigned index, const u8* buffer)
@ -164,7 +165,8 @@ bool BlockBasedFS::raw_write(unsigned index, const u8* buffer)
u32 base_offset = static_cast<u32>(index) * static_cast<u32>(m_logical_block_size);
file_description().seek(base_offset, SEEK_SET);
auto nwritten = file_description().write(buffer, m_logical_block_size);
ASSERT((size_t)nwritten == m_logical_block_size);
ASSERT(!nwritten.is_error());
ASSERT(nwritten.value() == m_logical_block_size);
return true;
}
@ -211,9 +213,9 @@ bool BlockBasedFS::read_block(unsigned index, u8* buffer, size_t count, size_t o
u32 base_offset = static_cast<u32>(index) * static_cast<u32>(block_size()) + static_cast<u32>(offset);
file_description().seek(base_offset, SEEK_SET);
auto nread = file_description().read(buffer, count);
if (nread < 0)
if (nread.is_error())
return false;
ASSERT(static_cast<size_t>(nread) == count);
ASSERT(nread.value() == count);
return true;
}
@ -222,9 +224,9 @@ bool BlockBasedFS::read_block(unsigned index, u8* buffer, size_t count, size_t o
u32 base_offset = static_cast<u32>(index) * static_cast<u32>(block_size());
file_description().seek(base_offset, SEEK_SET);
auto nread = file_description().read(entry.data, block_size());
if (nread < 0)
if (nread.is_error())
return false;
ASSERT(static_cast<size_t>(nread) == block_size());
ASSERT(nread.value() == block_size());
entry.has_data = true;
}
if (buffer)

View file

@ -145,29 +145,19 @@ bool FIFO::can_write(const FileDescription&, size_t) const
return m_buffer.space_for_writing() || !m_readers;
}
ssize_t FIFO::read(FileDescription&, size_t, u8* buffer, ssize_t size)
KResultOr<size_t> FIFO::read(FileDescription&, size_t, u8* buffer, size_t size)
{
if (!m_writers && m_buffer.is_empty())
return 0;
#ifdef FIFO_DEBUG
dbg() << "fifo: read(" << size << ")\n";
#endif
ssize_t nread = m_buffer.read(buffer, size);
#ifdef FIFO_DEBUG
dbg() << " -> read (" << String::format("%c", buffer[0]) << ") " << nread;
#endif
return nread;
return m_buffer.read(buffer, size);
}
ssize_t FIFO::write(FileDescription&, size_t, const u8* buffer, ssize_t size)
KResultOr<size_t> FIFO::write(FileDescription&, size_t, const u8* buffer, size_t size)
{
if (!m_readers) {
Thread::current()->send_signal(SIGPIPE, Process::current());
return -EPIPE;
}
#ifdef FIFO_DEBUG
dbg() << "fifo: write(" << (const void*)buffer << ", " << size << ")";
#endif
return m_buffer.write(buffer, size);
}

View file

@ -57,8 +57,8 @@ public:
private:
// ^File
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override;
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override;
virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override;
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override;
virtual bool can_read(const FileDescription&, size_t) const override;
virtual bool can_write(const FileDescription&, size_t) const override;
virtual String absolute_path(const FileDescription&) const override;

View file

@ -74,8 +74,8 @@ public:
virtual bool can_read(const FileDescription&, size_t) const = 0;
virtual bool can_write(const FileDescription&, size_t) const = 0;
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) = 0;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) = 0;
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) = 0;
virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) = 0;
virtual int ioctl(FileDescription&, unsigned request, FlatPtr arg);
virtual KResultOr<Region*> mmap(Process&, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared);

View file

@ -124,28 +124,32 @@ off_t FileDescription::seek(off_t offset, int whence)
return m_current_offset;
}
ssize_t FileDescription::read(u8* buffer, ssize_t count)
KResultOr<size_t> FileDescription::read(u8* buffer, size_t count)
{
LOCKER(m_lock);
if ((m_current_offset + count) < 0)
Checked<size_t> new_offset = m_current_offset;
new_offset += count;
if (new_offset.has_overflow())
return -EOVERFLOW;
SmapDisabler disabler;
int nread = m_file->read(*this, offset(), buffer, count);
if (nread > 0 && m_file->is_seekable())
m_current_offset += nread;
return nread;
auto nread_or_error = m_file->read(*this, offset(), buffer, count);
if (!nread_or_error.is_error() && m_file->is_seekable())
m_current_offset += nread_or_error.value();
return nread_or_error;
}
ssize_t FileDescription::write(const u8* data, ssize_t size)
KResultOr<size_t> FileDescription::write(const u8* data, size_t size)
{
LOCKER(m_lock);
if ((m_current_offset + size) < 0)
Checked<size_t> new_offset = m_current_offset;
new_offset += size;
if (new_offset.has_overflow())
return -EOVERFLOW;
SmapDisabler disabler;
int nwritten = m_file->write(*this, offset(), data, size);
if (nwritten > 0 && m_file->is_seekable())
m_current_offset += nwritten;
return nwritten;
auto nwritten_or_error = m_file->write(*this, offset(), data, size);
if (!nwritten_or_error.is_error() && m_file->is_seekable())
m_current_offset += nwritten_or_error.value();
return nwritten_or_error;
}
bool FileDescription::can_write() const

View file

@ -60,8 +60,8 @@ public:
KResult close();
off_t seek(off_t, int whence);
ssize_t read(u8*, ssize_t);
ssize_t write(const u8* data, ssize_t);
KResultOr<size_t> read(u8*, size_t);
KResultOr<size_t> write(const u8* data, size_t);
KResult fstat(stat&);
KResult chmod(mode_t);

View file

@ -44,21 +44,25 @@ InodeFile::~InodeFile()
{
}
ssize_t InodeFile::read(FileDescription& description, size_t offset, u8* buffer, ssize_t count)
KResultOr<size_t> InodeFile::read(FileDescription& description, size_t offset, u8* buffer, size_t count)
{
ssize_t nread = m_inode->read_bytes(offset, count, buffer, &description);
if (nread > 0)
Thread::current()->did_file_read(nread);
if (nread < 0)
return KResult(nread);
return nread;
}
ssize_t InodeFile::write(FileDescription& description, size_t offset, const u8* data, ssize_t count)
KResultOr<size_t> InodeFile::write(FileDescription& description, size_t offset, const u8* data, size_t count)
{
ssize_t nwritten = m_inode->write_bytes(offset, count, data, &description);
if (nwritten > 0) {
m_inode->set_mtime(kgettimeofday().tv_sec);
Thread::current()->did_file_write(nwritten);
}
if (nwritten < 0)
return KResult(nwritten);
return nwritten;
}

View file

@ -47,8 +47,8 @@ public:
virtual bool can_read(const FileDescription&, size_t) const override { return true; }
virtual bool can_write(const FileDescription&, size_t) const override { return true; }
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override;
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override;
virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override;
virtual KResultOr<Region*> mmap(Process&, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared) override;
virtual String absolute_path(const FileDescription&) const override;

View file

@ -57,7 +57,7 @@ bool InodeWatcher::can_write(const FileDescription&, size_t) const
return true;
}
ssize_t InodeWatcher::read(FileDescription&, size_t, u8* buffer, ssize_t buffer_size)
KResultOr<size_t> InodeWatcher::read(FileDescription&, size_t, u8* buffer, size_t buffer_size)
{
LOCKER(m_lock);
ASSERT(!m_queue.is_empty() || !m_inode);
@ -72,9 +72,9 @@ ssize_t InodeWatcher::read(FileDescription&, size_t, u8* buffer, ssize_t buffer_
return sizeof(event);
}
ssize_t InodeWatcher::write(FileDescription&, size_t, const u8*, ssize_t)
KResultOr<size_t> InodeWatcher::write(FileDescription&, size_t, const u8*, size_t)
{
return -EIO;
return KResult(-EIO);
}
String InodeWatcher::absolute_path(const FileDescription&) const

View file

@ -55,8 +55,8 @@ public:
virtual bool can_read(const FileDescription&, size_t) const override;
virtual bool can_write(const FileDescription&, size_t) const override;
virtual ssize_t read(FileDescription&, size_t, u8*, ssize_t) override;
virtual ssize_t write(FileDescription&, size_t, const u8*, ssize_t) override;
virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override;
virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override;
virtual String absolute_path(const FileDescription&) const override;
virtual const char* class_name() const override { return "InodeWatcher"; };

View file

@ -426,9 +426,10 @@ KResult Plan9FS::post_message(Message& message)
if (Thread::current()->block<Thread::WriteBlocker>(nullptr, description).was_interrupted())
return KResult(-EINTR);
}
ssize_t nwritten = description.write(data, size);
if (nwritten < 0)
return KResult(nwritten);
auto nwritten_or_error = description.write(data, size);
if (nwritten_or_error.is_error())
return nwritten_or_error.error();
auto nwritten = nwritten_or_error.value();
data += nwritten;
size -= nwritten;
}
@ -444,9 +445,10 @@ KResult Plan9FS::do_read(u8* data, size_t size)
if (Thread::current()->block<Thread::ReadBlocker>(nullptr, description).was_interrupted())
return KResult(-EINTR);
}
ssize_t nread = description.read(data, size);
if (nread < 0)
return KResult(nread);
auto nread_or_error = description.read(data, size);
if (nread_or_error.is_error())
return nread_or_error.error();
auto nread = nread_or_error.value();
if (nread == 0)
return KResult(-EIO);
data += nread;