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

Kernel: Change Inode::{read/write}_bytes interface to KResultOr<ssize_t>

The error handling in all these cases was still using the old style
negative values to indicate errors. We have a nicer solution for this
now with KResultOr<T>. This change switches the interface and then all
implementers to use the new style.
This commit is contained in:
Brian Gianforcaro 2021-05-01 14:29:39 -07:00 committed by Andreas Kling
parent de9b454f89
commit 234c6ae32d
18 changed files with 88 additions and 82 deletions

View file

@ -80,7 +80,8 @@ DevFSInode::DevFSInode(DevFS& fs)
: Inode(fs, fs.allocate_inode_index()) : Inode(fs, fs.allocate_inode_index())
{ {
} }
ssize_t DevFSInode::read_bytes(off_t, ssize_t, UserOrKernelBuffer&, FileDescription*) const
KResultOr<ssize_t> DevFSInode::read_bytes(off_t, ssize_t, UserOrKernelBuffer&, FileDescription*) const
{ {
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }
@ -99,7 +100,7 @@ void DevFSInode::flush_metadata()
{ {
} }
ssize_t DevFSInode::write_bytes(off_t, ssize_t, const UserOrKernelBuffer&, FileDescription*) KResultOr<ssize_t> DevFSInode::write_bytes(off_t, ssize_t, const UserOrKernelBuffer&, FileDescription*)
{ {
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }
@ -151,13 +152,13 @@ DevFSLinkInode::DevFSLinkInode(DevFS& fs, String name)
, m_name(name) , m_name(name)
{ {
} }
ssize_t DevFSLinkInode::read_bytes(off_t offset, ssize_t, UserOrKernelBuffer& buffer, FileDescription*) const KResultOr<ssize_t> DevFSLinkInode::read_bytes(off_t offset, ssize_t, UserOrKernelBuffer& buffer, FileDescription*) const
{ {
Locker locker(m_lock); Locker locker(m_lock);
VERIFY(offset == 0); VERIFY(offset == 0);
VERIFY(!m_link.is_null()); VERIFY(!m_link.is_null());
if (!buffer.write(((const u8*)m_link.substring_view(0).characters_without_null_termination()) + offset, m_link.length())) if (!buffer.write(((const u8*)m_link.substring_view(0).characters_without_null_termination()) + offset, m_link.length()))
return -EFAULT; return EFAULT;
return m_link.length(); return m_link.length();
} }
InodeMetadata DevFSLinkInode::metadata() const InodeMetadata DevFSLinkInode::metadata() const
@ -172,7 +173,7 @@ InodeMetadata DevFSLinkInode::metadata() const
metadata.mtime = mepoch; metadata.mtime = mepoch;
return metadata; return metadata;
} }
ssize_t DevFSLinkInode::write_bytes(off_t offset, ssize_t count, const UserOrKernelBuffer& buffer, FileDescription*) KResultOr<ssize_t> DevFSLinkInode::write_bytes(off_t offset, ssize_t count, const UserOrKernelBuffer& buffer, FileDescription*)
{ {
Locker locker(m_lock); Locker locker(m_lock);
VERIFY(offset == 0); VERIFY(offset == 0);
@ -345,7 +346,7 @@ String DevFSDeviceInode::name() const
return m_cached_name; return m_cached_name;
} }
ssize_t DevFSDeviceInode::read_bytes(off_t offset, ssize_t count, UserOrKernelBuffer& buffer, FileDescription* description) const KResultOr<ssize_t> DevFSDeviceInode::read_bytes(off_t offset, ssize_t count, UserOrKernelBuffer& buffer, FileDescription* description) const
{ {
Locker locker(m_lock); Locker locker(m_lock);
VERIFY(!!description); VERIFY(!!description);
@ -353,7 +354,7 @@ ssize_t DevFSDeviceInode::read_bytes(off_t offset, ssize_t count, UserOrKernelBu
return 0; return 0;
auto nread = const_cast<Device&>(*m_attached_device).read(*description, offset, buffer, count); auto nread = const_cast<Device&>(*m_attached_device).read(*description, offset, buffer, count);
if (nread.is_error()) if (nread.is_error())
return -EIO; return EIO;
return nread.value(); return nread.value();
} }
@ -371,7 +372,7 @@ InodeMetadata DevFSDeviceInode::metadata() const
metadata.minor_device = m_attached_device->minor(); metadata.minor_device = m_attached_device->minor();
return metadata; return metadata;
} }
ssize_t DevFSDeviceInode::write_bytes(off_t offset, ssize_t count, const UserOrKernelBuffer& buffer, FileDescription* description) KResultOr<ssize_t> DevFSDeviceInode::write_bytes(off_t offset, ssize_t count, const UserOrKernelBuffer& buffer, FileDescription* description)
{ {
Locker locker(m_lock); Locker locker(m_lock);
VERIFY(!!description); VERIFY(!!description);
@ -379,7 +380,7 @@ ssize_t DevFSDeviceInode::write_bytes(off_t offset, ssize_t count, const UserOrK
return 0; return 0;
auto nread = const_cast<Device&>(*m_attached_device).write(*description, offset, buffer, count); auto nread = const_cast<Device&>(*m_attached_device).write(*description, offset, buffer, count);
if (nread.is_error()) if (nread.is_error())
return -EIO; return EIO;
return nread.value(); return nread.value();
} }

View file

@ -57,11 +57,11 @@ public:
protected: protected:
DevFSInode(DevFS&); DevFSInode(DevFS&);
virtual ssize_t read_bytes(off_t, ssize_t, UserOrKernelBuffer& buffer, FileDescription*) const override; virtual KResultOr<ssize_t> read_bytes(off_t, ssize_t, UserOrKernelBuffer& buffer, FileDescription*) const override;
virtual KResult traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const override; virtual KResult traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const override;
virtual RefPtr<Inode> lookup(StringView name) override; virtual RefPtr<Inode> lookup(StringView name) override;
virtual void flush_metadata() override; virtual void flush_metadata() override;
virtual ssize_t write_bytes(off_t, ssize_t, const UserOrKernelBuffer& buffer, FileDescription*) override; virtual KResultOr<ssize_t> write_bytes(off_t, ssize_t, const UserOrKernelBuffer& buffer, FileDescription*) override;
virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override; virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override;
virtual KResult add_child(Inode&, const StringView& name, mode_t) override; virtual KResult add_child(Inode&, const StringView& name, mode_t) override;
virtual KResult remove_child(const StringView& name) override; virtual KResult remove_child(const StringView& name) override;
@ -83,9 +83,9 @@ private:
String determine_name() const; String determine_name() const;
DevFSDeviceInode(DevFS&, const Device&); DevFSDeviceInode(DevFS&, const Device&);
// ^Inode // ^Inode
virtual ssize_t read_bytes(off_t, ssize_t, UserOrKernelBuffer& buffer, FileDescription*) const override; virtual KResultOr<ssize_t> read_bytes(off_t, ssize_t, UserOrKernelBuffer& buffer, FileDescription*) const override;
virtual InodeMetadata metadata() const override; virtual InodeMetadata metadata() const override;
virtual ssize_t write_bytes(off_t, ssize_t, const UserOrKernelBuffer& buffer, FileDescription*) override; virtual KResultOr<ssize_t> write_bytes(off_t, ssize_t, const UserOrKernelBuffer& buffer, FileDescription*) override;
virtual KResult chown(uid_t, gid_t) override; virtual KResult chown(uid_t, gid_t) override;
NonnullRefPtr<Device> m_attached_device; NonnullRefPtr<Device> m_attached_device;
@ -106,9 +106,9 @@ public:
protected: protected:
DevFSLinkInode(DevFS&, String); DevFSLinkInode(DevFS&, String);
// ^Inode // ^Inode
virtual ssize_t read_bytes(off_t, ssize_t, UserOrKernelBuffer& buffer, FileDescription*) const override; virtual KResultOr<ssize_t> read_bytes(off_t, ssize_t, UserOrKernelBuffer& buffer, FileDescription*) const override;
virtual InodeMetadata metadata() const override; virtual InodeMetadata metadata() const override;
virtual ssize_t write_bytes(off_t, ssize_t, const UserOrKernelBuffer& buffer, FileDescription*) override; virtual KResultOr<ssize_t> write_bytes(off_t, ssize_t, const UserOrKernelBuffer& buffer, FileDescription*) override;
const String m_name; const String m_name;
String m_link; String m_link;

View file

@ -100,12 +100,12 @@ DevPtsFSInode::~DevPtsFSInode()
{ {
} }
ssize_t DevPtsFSInode::read_bytes(off_t, ssize_t, UserOrKernelBuffer&, FileDescription*) const KResultOr<ssize_t> DevPtsFSInode::read_bytes(off_t, ssize_t, UserOrKernelBuffer&, FileDescription*) const
{ {
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }
ssize_t DevPtsFSInode::write_bytes(off_t, ssize_t, const UserOrKernelBuffer&, FileDescription*) KResultOr<ssize_t> DevPtsFSInode::write_bytes(off_t, ssize_t, const UserOrKernelBuffer&, FileDescription*)
{ {
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }

View file

@ -47,12 +47,12 @@ private:
DevPtsFSInode(DevPtsFS&, InodeIndex, SlavePTY*); DevPtsFSInode(DevPtsFS&, InodeIndex, SlavePTY*);
// ^Inode // ^Inode
virtual ssize_t read_bytes(off_t, ssize_t, UserOrKernelBuffer& buffer, FileDescription*) const override; virtual KResultOr<ssize_t> read_bytes(off_t, ssize_t, UserOrKernelBuffer& buffer, FileDescription*) const override;
virtual InodeMetadata metadata() const override; virtual InodeMetadata metadata() const override;
virtual KResult traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const override; virtual KResult traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const override;
virtual RefPtr<Inode> lookup(StringView name) override; virtual RefPtr<Inode> lookup(StringView name) override;
virtual void flush_metadata() override; virtual void flush_metadata() override;
virtual ssize_t write_bytes(off_t, ssize_t, const UserOrKernelBuffer& buffer, FileDescription*) override; virtual KResultOr<ssize_t> write_bytes(off_t, ssize_t, const UserOrKernelBuffer& buffer, FileDescription*) override;
virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override; virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override;
virtual KResult add_child(Inode&, const StringView& name, mode_t) override; virtual KResult add_child(Inode&, const StringView& name, mode_t) override;
virtual KResult remove_child(const StringView& name) override; virtual KResult remove_child(const StringView& name) override;

View file

@ -807,7 +807,7 @@ RefPtr<Inode> Ext2FS::get_inode(InodeIdentifier inode) const
return new_inode; return new_inode;
} }
ssize_t Ext2FSInode::read_bytes(off_t offset, ssize_t count, UserOrKernelBuffer& buffer, FileDescription* description) const KResultOr<ssize_t> Ext2FSInode::read_bytes(off_t offset, ssize_t count, UserOrKernelBuffer& buffer, FileDescription* description) const
{ {
Locker inode_locker(m_lock); Locker inode_locker(m_lock);
VERIFY(offset >= 0); VERIFY(offset >= 0);
@ -823,7 +823,7 @@ ssize_t Ext2FSInode::read_bytes(off_t offset, ssize_t count, UserOrKernelBuffer&
VERIFY(offset == 0); VERIFY(offset == 0);
ssize_t nread = min((off_t)size() - offset, static_cast<off_t>(count)); ssize_t nread = min((off_t)size() - offset, static_cast<off_t>(count));
if (!buffer.write(((const u8*)m_raw_inode.i_block) + offset, (size_t)nread)) if (!buffer.write(((const u8*)m_raw_inode.i_block) + offset, (size_t)nread))
return -EFAULT; return EFAULT;
return nread; return nread;
} }
@ -832,7 +832,7 @@ ssize_t Ext2FSInode::read_bytes(off_t offset, ssize_t count, UserOrKernelBuffer&
if (m_block_list.is_empty()) { if (m_block_list.is_empty()) {
dmesgln("Ext2FSInode[{}]::read_bytes(): Empty block list", identifier()); dmesgln("Ext2FSInode[{}]::read_bytes(): Empty block list", identifier());
return -EIO; return EIO;
} }
bool allow_cache = !description || !description->is_direct(); bool allow_cache = !description || !description->is_direct();
@ -859,7 +859,7 @@ ssize_t Ext2FSInode::read_bytes(off_t offset, ssize_t count, UserOrKernelBuffer&
if (block_index.value() == 0) { if (block_index.value() == 0) {
// This is a hole, act as if it's filled with zeroes. // This is a hole, act as if it's filled with zeroes.
if (!buffer_offset.memset(0, num_bytes_to_copy)) if (!buffer_offset.memset(0, num_bytes_to_copy))
return -EFAULT; return EFAULT;
} else { } else {
if (auto result = fs().read_block(block_index, &buffer_offset, num_bytes_to_copy, offset_into_block, allow_cache); result.is_error()) { if (auto result = fs().read_block(block_index, &buffer_offset, num_bytes_to_copy, offset_into_block, allow_cache); result.is_error()) {
dmesgln("Ext2FSInode[{}]::read_bytes(): Failed to read block {} (index {})", identifier(), block_index.value(), bi); dmesgln("Ext2FSInode[{}]::read_bytes(): Failed to read block {} (index {})", identifier(), block_index.value(), bi);
@ -940,19 +940,19 @@ KResult Ext2FSInode::resize(u64 new_size)
auto clear_from = old_size; auto clear_from = old_size;
u8 zero_buffer[PAGE_SIZE] {}; u8 zero_buffer[PAGE_SIZE] {};
while (bytes_to_clear) { while (bytes_to_clear) {
auto nwritten = write_bytes(clear_from, min(static_cast<u64>(sizeof(zero_buffer)), bytes_to_clear), UserOrKernelBuffer::for_kernel_buffer(zero_buffer), nullptr); auto result = write_bytes(clear_from, min(static_cast<u64>(sizeof(zero_buffer)), bytes_to_clear), UserOrKernelBuffer::for_kernel_buffer(zero_buffer), nullptr);
if (nwritten < 0) if (result.is_error())
return KResult((ErrnoCode)-nwritten); return result.error();
VERIFY(nwritten != 0); VERIFY(result.value() != 0);
bytes_to_clear -= nwritten; bytes_to_clear -= result.value();
clear_from += nwritten; clear_from += result.value();
} }
} }
return KSuccess; return KSuccess;
} }
ssize_t Ext2FSInode::write_bytes(off_t offset, ssize_t count, const UserOrKernelBuffer& data, FileDescription* description) KResultOr<ssize_t> Ext2FSInode::write_bytes(off_t offset, ssize_t count, const UserOrKernelBuffer& data, FileDescription* description)
{ {
VERIFY(offset >= 0); VERIFY(offset >= 0);
VERIFY(count >= 0); VERIFY(count >= 0);
@ -967,7 +967,7 @@ ssize_t Ext2FSInode::write_bytes(off_t offset, ssize_t count, const UserOrKernel
if (max((size_t)(offset + count), (size_t)m_raw_inode.i_size) < max_inline_symlink_length) { if (max((size_t)(offset + count), (size_t)m_raw_inode.i_size) < max_inline_symlink_length) {
dbgln_if(EXT2_DEBUG, "Ext2FSInode[{}]::write_bytes(): Poking into i_block array for inline symlink '{}' ({} bytes)", identifier(), data.copy_into_string(count), count); dbgln_if(EXT2_DEBUG, "Ext2FSInode[{}]::write_bytes(): Poking into i_block array for inline symlink '{}' ({} bytes)", identifier(), data.copy_into_string(count), count);
if (!data.read(((u8*)m_raw_inode.i_block) + offset, (size_t)count)) if (!data.read(((u8*)m_raw_inode.i_block) + offset, (size_t)count))
return -EFAULT; return EFAULT;
if ((size_t)(offset + count) > (size_t)m_raw_inode.i_size) if ((size_t)(offset + count) > (size_t)m_raw_inode.i_size)
m_raw_inode.i_size = offset + count; m_raw_inode.i_size = offset + count;
set_metadata_dirty(true); set_metadata_dirty(true);
@ -988,7 +988,7 @@ ssize_t Ext2FSInode::write_bytes(off_t offset, ssize_t count, const UserOrKernel
if (m_block_list.is_empty()) { if (m_block_list.is_empty()) {
dbgln("Ext2FSInode[{}]::write_bytes(): Empty block list", identifier()); dbgln("Ext2FSInode[{}]::write_bytes(): Empty block list", identifier());
return -EIO; return EIO;
} }
BlockBasedFS::BlockIndex first_block_logical_index = offset / block_size; BlockBasedFS::BlockIndex first_block_logical_index = offset / block_size;
@ -1113,11 +1113,11 @@ KResult Ext2FSInode::write_directory(const Vector<Ext2FSDirectoryEntry>& entries
stream.fill_to_end(0); stream.fill_to_end(0);
auto buffer = UserOrKernelBuffer::for_kernel_buffer(stream.data()); auto buffer = UserOrKernelBuffer::for_kernel_buffer(stream.data());
ssize_t nwritten = write_bytes(0, stream.size(), buffer, nullptr); auto result = write_bytes(0, stream.size(), buffer, nullptr);
if (nwritten < 0) if (result.is_error())
return KResult((ErrnoCode)-nwritten); return result.error();
set_metadata_dirty(true); set_metadata_dirty(true);
if (static_cast<size_t>(nwritten) != directory_data.size()) if (static_cast<size_t>(result.value()) != directory_data.size())
return EIO; return EIO;
return KSuccess; return KSuccess;
} }

View file

@ -38,12 +38,12 @@ public:
private: private:
// ^Inode // ^Inode
virtual ssize_t read_bytes(off_t, ssize_t, UserOrKernelBuffer& buffer, FileDescription*) const override; virtual KResultOr<ssize_t> read_bytes(off_t, ssize_t, UserOrKernelBuffer& buffer, FileDescription*) const override;
virtual InodeMetadata metadata() const override; virtual InodeMetadata metadata() const override;
virtual KResult traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const override; virtual KResult traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const override;
virtual RefPtr<Inode> lookup(StringView name) override; virtual RefPtr<Inode> lookup(StringView name) override;
virtual void flush_metadata() override; virtual void flush_metadata() override;
virtual ssize_t write_bytes(off_t, ssize_t, const UserOrKernelBuffer& data, FileDescription*) override; virtual KResultOr<ssize_t> write_bytes(off_t, ssize_t, const UserOrKernelBuffer& data, FileDescription*) override;
virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override; virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override;
virtual KResult add_child(Inode& child, const StringView& name, mode_t) override; virtual KResult add_child(Inode& child, const StringView& name, mode_t) override;
virtual KResult remove_child(const StringView& name) override; virtual KResult remove_child(const StringView& name) override;

View file

@ -60,9 +60,10 @@ KResultOr<NonnullOwnPtr<KBuffer>> Inode::read_entire(FileDescription* descriptio
off_t offset = 0; off_t offset = 0;
for (;;) { for (;;) {
auto buf = UserOrKernelBuffer::for_kernel_buffer(buffer); auto buf = UserOrKernelBuffer::for_kernel_buffer(buffer);
nread = read_bytes(offset, sizeof(buffer), buf, description); auto result = read_bytes(offset, sizeof(buffer), buf, description);
if (nread < 0) if (result.is_error())
return KResult((ErrnoCode)-nread); return result.error();
nread = result.value();
VERIFY(nread <= (ssize_t)sizeof(buffer)); VERIFY(nread <= (ssize_t)sizeof(buffer));
if (nread <= 0) if (nread <= 0)
break; break;

View file

@ -52,10 +52,10 @@ public:
virtual KResult attach(FileDescription&) { return KSuccess; } virtual KResult attach(FileDescription&) { return KSuccess; }
virtual void detach(FileDescription&) { } virtual void detach(FileDescription&) { }
virtual void did_seek(FileDescription&, off_t) { } virtual void did_seek(FileDescription&, off_t) { }
virtual ssize_t read_bytes(off_t, ssize_t, UserOrKernelBuffer& buffer, FileDescription*) const = 0; virtual KResultOr<ssize_t> read_bytes(off_t, ssize_t, UserOrKernelBuffer& buffer, FileDescription*) const = 0;
virtual KResult traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const = 0; virtual KResult traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const = 0;
virtual RefPtr<Inode> lookup(StringView name) = 0; virtual RefPtr<Inode> lookup(StringView name) = 0;
virtual ssize_t write_bytes(off_t, ssize_t, const UserOrKernelBuffer& data, FileDescription*) = 0; virtual KResultOr<ssize_t> write_bytes(off_t, ssize_t, const UserOrKernelBuffer& data, FileDescription*) = 0;
virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) = 0; virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) = 0;
virtual KResult add_child(Inode&, const StringView& name, mode_t) = 0; virtual KResult add_child(Inode&, const StringView& name, mode_t) = 0;
virtual KResult remove_child(const StringView& name) = 0; virtual KResult remove_child(const StringView& name) = 0;

View file

@ -31,13 +31,14 @@ KResultOr<size_t> InodeFile::read(FileDescription& description, u64 offset, User
if (Checked<off_t>::addition_would_overflow(offset, count)) if (Checked<off_t>::addition_would_overflow(offset, count))
return EOVERFLOW; return EOVERFLOW;
ssize_t nread = m_inode->read_bytes(offset, count, buffer, &description); auto result = m_inode->read_bytes(offset, count, buffer, &description);
if (result.is_error())
return result.error();
auto nread = result.value();
if (nread > 0) { if (nread > 0) {
Thread::current()->did_file_read(nread); Thread::current()->did_file_read(nread);
evaluate_block_conditions(); evaluate_block_conditions();
} }
if (nread < 0)
return KResult((ErrnoCode)-nread);
return nread; return nread;
} }
@ -46,7 +47,11 @@ KResultOr<size_t> InodeFile::write(FileDescription& description, u64 offset, con
if (Checked<off_t>::addition_would_overflow(offset, count)) if (Checked<off_t>::addition_would_overflow(offset, count))
return EOVERFLOW; return EOVERFLOW;
ssize_t nwritten = m_inode->write_bytes(offset, count, data, &description); auto result = m_inode->write_bytes(offset, count, data, &description);
if (result.is_error())
return result.error();
auto nwritten = result.value();
if (nwritten > 0) { if (nwritten > 0) {
auto mtime_result = m_inode->set_mtime(kgettimeofday().to_truncated_seconds()); auto mtime_result = m_inode->set_mtime(kgettimeofday().to_truncated_seconds());
Thread::current()->did_file_write(nwritten); Thread::current()->did_file_write(nwritten);
@ -54,8 +59,6 @@ KResultOr<size_t> InodeFile::write(FileDescription& description, u64 offset, con
if (mtime_result.is_error()) if (mtime_result.is_error())
return mtime_result; return mtime_result;
} }
if (nwritten < 0)
return KResult((ErrnoCode)-nwritten);
return nwritten; return nwritten;
} }

View file

@ -728,7 +728,7 @@ KResult Plan9FSInode::ensure_open_for_mode(int mode)
} }
} }
ssize_t Plan9FSInode::read_bytes(off_t offset, ssize_t size, UserOrKernelBuffer& buffer, FileDescription*) const KResultOr<ssize_t> Plan9FSInode::read_bytes(off_t offset, ssize_t size, UserOrKernelBuffer& buffer, FileDescription*) const
{ {
auto result = const_cast<Plan9FSInode&>(*this).ensure_open_for_mode(O_RDONLY); auto result = const_cast<Plan9FSInode&>(*this).ensure_open_for_mode(O_RDONLY);
if (result.is_error()) if (result.is_error())
@ -762,22 +762,22 @@ ssize_t Plan9FSInode::read_bytes(off_t offset, ssize_t size, UserOrKernelBuffer&
// Guard against the server returning more data than requested. // Guard against the server returning more data than requested.
size_t nread = min(data.length(), (size_t)size); size_t nread = min(data.length(), (size_t)size);
if (!buffer.write(data.characters_without_null_termination(), nread)) if (!buffer.write(data.characters_without_null_termination(), nread))
return -EFAULT; return EFAULT;
return nread; return nread;
} }
ssize_t Plan9FSInode::write_bytes(off_t offset, ssize_t size, const UserOrKernelBuffer& data, FileDescription*) KResultOr<ssize_t> Plan9FSInode::write_bytes(off_t offset, ssize_t size, const UserOrKernelBuffer& data, FileDescription*)
{ {
auto result = ensure_open_for_mode(O_WRONLY); auto result = ensure_open_for_mode(O_WRONLY);
if (result.is_error()) if (result.is_error())
return result; return result.error();
size = fs().adjust_buffer_size(size); size = fs().adjust_buffer_size(size);
auto data_copy = data.copy_into_string(size); // FIXME: this seems ugly auto data_copy = data.copy_into_string(size); // FIXME: this seems ugly
if (data_copy.is_null()) if (data_copy.is_null())
return -EFAULT; return EFAULT;
Plan9FS::Message message { fs(), Plan9FS::Message::Type::Twrite }; Plan9FS::Message message { fs(), Plan9FS::Message::Type::Twrite };
message << fid() << (u64)offset; message << fid() << (u64)offset;

View file

@ -156,8 +156,8 @@ public:
// ^Inode // ^Inode
virtual InodeMetadata metadata() const override; virtual InodeMetadata metadata() const override;
virtual void flush_metadata() override; virtual void flush_metadata() override;
virtual ssize_t read_bytes(off_t, ssize_t, UserOrKernelBuffer& buffer, FileDescription*) const override; virtual KResultOr<ssize_t> read_bytes(off_t, ssize_t, UserOrKernelBuffer& buffer, FileDescription*) const override;
virtual ssize_t write_bytes(off_t, ssize_t, const UserOrKernelBuffer& data, FileDescription*) override; virtual KResultOr<ssize_t> write_bytes(off_t, ssize_t, const UserOrKernelBuffer& data, FileDescription*) override;
virtual KResult traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const override; virtual KResult traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const override;
virtual RefPtr<Inode> lookup(StringView name) override; virtual RefPtr<Inode> lookup(StringView name) override;
virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override; virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override;

View file

@ -1222,17 +1222,17 @@ InodeMetadata ProcFSInode::metadata() const
return metadata; return metadata;
} }
ssize_t ProcFSInode::read_bytes(off_t offset, ssize_t count, UserOrKernelBuffer& buffer, FileDescription* description) const KResultOr<ssize_t> ProcFSInode::read_bytes(off_t offset, ssize_t count, UserOrKernelBuffer& buffer, FileDescription* description) const
{ {
dbgln_if(PROCFS_DEBUG, "ProcFS: read_bytes offset: {} count: {}", offset, count); dbgln_if(PROCFS_DEBUG, "ProcFS: read_bytes offset: {} count: {}", offset, count);
VERIFY(offset >= 0); VERIFY(offset >= 0);
VERIFY(buffer.user_or_kernel_ptr()); VERIFY(buffer.user_or_kernel_ptr());
if (!description) if (!description)
return -EIO; return EIO;
if (!description->data()) { if (!description->data()) {
dbgln_if(PROCFS_DEBUG, "ProcFS: Do not have cached data!"); dbgln_if(PROCFS_DEBUG, "ProcFS: Do not have cached data!");
return -EIO; return EIO;
} }
// Be sure to keep a reference to data_buffer while we use it! // Be sure to keep a reference to data_buffer while we use it!
@ -1243,7 +1243,7 @@ ssize_t ProcFSInode::read_bytes(off_t offset, ssize_t count, UserOrKernelBuffer&
ssize_t nread = min(static_cast<off_t>(data_buffer->size() - offset), static_cast<off_t>(count)); ssize_t nread = min(static_cast<off_t>(data_buffer->size() - offset), static_cast<off_t>(count));
if (!buffer.write(data_buffer->data() + offset, nread)) if (!buffer.write(data_buffer->data() + offset, nread))
return -EFAULT; return EFAULT;
return nread; return nread;
} }
@ -1454,7 +1454,7 @@ void ProcFSInode::flush_metadata()
{ {
} }
ssize_t ProcFSInode::write_bytes(off_t offset, ssize_t size, const UserOrKernelBuffer& buffer, FileDescription*) KResultOr<ssize_t> ProcFSInode::write_bytes(off_t offset, ssize_t size, const UserOrKernelBuffer& buffer, FileDescription*)
{ {
// For process-specific inodes, hold the process's ptrace lock across the write // For process-specific inodes, hold the process's ptrace lock across the write
// and refuse to write at all data if the process is not dumpable. // and refuse to write at all data if the process is not dumpable.
@ -1493,10 +1493,10 @@ ssize_t ProcFSInode::write_bytes(off_t offset, ssize_t size, const UserOrKernelB
break; break;
} }
} else } else
return -EPERM; return EPERM;
} else { } else {
if (!directory_entry->write_callback) if (!directory_entry->write_callback)
return -EPERM; return EPERM;
write_callback = directory_entry->write_callback; write_callback = directory_entry->write_callback;
} }

View file

@ -78,12 +78,12 @@ private:
// ^Inode // ^Inode
virtual KResult attach(FileDescription&) override; virtual KResult attach(FileDescription&) override;
virtual void did_seek(FileDescription&, off_t) override; virtual void did_seek(FileDescription&, off_t) override;
virtual ssize_t read_bytes(off_t, ssize_t, UserOrKernelBuffer& buffer, FileDescription*) const override; virtual KResultOr<ssize_t> read_bytes(off_t, ssize_t, UserOrKernelBuffer& buffer, FileDescription*) const override;
virtual InodeMetadata metadata() const override; virtual InodeMetadata metadata() const override;
virtual KResult traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const override; virtual KResult traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const override;
virtual RefPtr<Inode> lookup(StringView name) override; virtual RefPtr<Inode> lookup(StringView name) override;
virtual void flush_metadata() override; virtual void flush_metadata() override;
virtual ssize_t write_bytes(off_t, ssize_t, const UserOrKernelBuffer& buffer, FileDescription*) override; virtual KResultOr<ssize_t> write_bytes(off_t, ssize_t, const UserOrKernelBuffer& buffer, FileDescription*) override;
virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override; virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override;
virtual KResult add_child(Inode&, const StringView& name, mode_t) override; virtual KResult add_child(Inode&, const StringView& name, mode_t) override;
virtual KResult remove_child(const StringView& name) override; virtual KResult remove_child(const StringView& name) override;
@ -111,12 +111,12 @@ private:
// ^Inode // ^Inode
virtual KResult attach(FileDescription&) override; virtual KResult attach(FileDescription&) override;
virtual void did_seek(FileDescription&, off_t) override; virtual void did_seek(FileDescription&, off_t) override;
virtual ssize_t read_bytes(off_t, ssize_t, UserOrKernelBuffer&, FileDescription*) const override { VERIFY_NOT_REACHED(); } virtual KResultOr<ssize_t> read_bytes(off_t, ssize_t, UserOrKernelBuffer&, FileDescription*) const override { VERIFY_NOT_REACHED(); }
virtual InodeMetadata metadata() const override; virtual InodeMetadata metadata() const override;
virtual KResult traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const override { VERIFY_NOT_REACHED(); } virtual KResult traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const override { VERIFY_NOT_REACHED(); }
virtual RefPtr<Inode> lookup(StringView name) override; virtual RefPtr<Inode> lookup(StringView name) override;
virtual void flush_metadata() override {}; virtual void flush_metadata() override {};
virtual ssize_t write_bytes(off_t, ssize_t, const UserOrKernelBuffer&, FileDescription*) override { VERIFY_NOT_REACHED(); } virtual KResultOr<ssize_t> write_bytes(off_t, ssize_t, const UserOrKernelBuffer&, FileDescription*) override { VERIFY_NOT_REACHED(); }
virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override; virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override;
virtual KResult add_child(Inode&, const StringView& name, mode_t) override; virtual KResult add_child(Inode&, const StringView& name, mode_t) override;
virtual KResult remove_child(const StringView& name) override; virtual KResult remove_child(const StringView& name) override;

View file

@ -126,7 +126,7 @@ KResult TmpFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntry
return KSuccess; return KSuccess;
} }
ssize_t TmpFSInode::read_bytes(off_t offset, ssize_t size, UserOrKernelBuffer& buffer, FileDescription*) const KResultOr<ssize_t> TmpFSInode::read_bytes(off_t offset, ssize_t size, UserOrKernelBuffer& buffer, FileDescription*) const
{ {
Locker locker(m_lock, Lock::Mode::Shared); Locker locker(m_lock, Lock::Mode::Shared);
VERIFY(!is_directory()); VERIFY(!is_directory());
@ -143,11 +143,11 @@ ssize_t TmpFSInode::read_bytes(off_t offset, ssize_t size, UserOrKernelBuffer& b
size = m_metadata.size - offset; size = m_metadata.size - offset;
if (!buffer.write(m_content->data() + offset, size)) if (!buffer.write(m_content->data() + offset, size))
return -EFAULT; return EFAULT;
return size; return size;
} }
ssize_t TmpFSInode::write_bytes(off_t offset, ssize_t size, const UserOrKernelBuffer& buffer, FileDescription*) KResultOr<ssize_t> TmpFSInode::write_bytes(off_t offset, ssize_t size, const UserOrKernelBuffer& buffer, FileDescription*)
{ {
Locker locker(m_lock); Locker locker(m_lock);
VERIFY(!is_directory()); VERIFY(!is_directory());
@ -175,7 +175,7 @@ ssize_t TmpFSInode::write_bytes(off_t offset, ssize_t size, const UserOrKernelBu
// existing ones. // existing ones.
auto tmp = KBuffer::try_create_with_size(new_size * 2); auto tmp = KBuffer::try_create_with_size(new_size * 2);
if (!tmp) if (!tmp)
return -ENOMEM; return ENOMEM;
tmp->set_size(new_size); tmp->set_size(new_size);
if (m_content) if (m_content)
memcpy(tmp->data(), m_content->data(), old_size); memcpy(tmp->data(), m_content->data(), old_size);
@ -187,7 +187,7 @@ ssize_t TmpFSInode::write_bytes(off_t offset, ssize_t size, const UserOrKernelBu
} }
if (!buffer.read(m_content->data() + offset, size)) // TODO: partial reads? if (!buffer.read(m_content->data() + offset, size)) // TODO: partial reads?
return -EFAULT; return EFAULT;
return size; return size;
} }

View file

@ -54,12 +54,12 @@ public:
const TmpFS& fs() const { return static_cast<const TmpFS&>(Inode::fs()); } const TmpFS& fs() const { return static_cast<const TmpFS&>(Inode::fs()); }
// ^Inode // ^Inode
virtual ssize_t read_bytes(off_t, ssize_t, UserOrKernelBuffer& buffer, FileDescription*) const override; virtual KResultOr<ssize_t> read_bytes(off_t, ssize_t, UserOrKernelBuffer& buffer, FileDescription*) const override;
virtual InodeMetadata metadata() const override; virtual InodeMetadata metadata() const override;
virtual KResult traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const override; virtual KResult traverse_as_directory(Function<bool(const FS::DirectoryEntryView&)>) const override;
virtual RefPtr<Inode> lookup(StringView name) override; virtual RefPtr<Inode> lookup(StringView name) override;
virtual void flush_metadata() override; virtual void flush_metadata() override;
virtual ssize_t write_bytes(off_t, ssize_t, const UserOrKernelBuffer& buffer, FileDescription*) override; virtual KResultOr<ssize_t> write_bytes(off_t, ssize_t, const UserOrKernelBuffer& buffer, FileDescription*) override;
virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override; virtual KResultOr<NonnullRefPtr<Inode>> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override;
virtual KResult add_child(Inode&, const StringView& name, mode_t) override; virtual KResult add_child(Inode&, const StringView& name, mode_t) override;
virtual KResult remove_child(const StringView& name) override; virtual KResult remove_child(const StringView& name) override;

View file

@ -710,9 +710,9 @@ KResult VFS::symlink(StringView target, StringView linkpath, Custody& base)
return inode_or_error.error(); return inode_or_error.error();
auto& inode = inode_or_error.value(); auto& inode = inode_or_error.value();
auto target_buffer = UserOrKernelBuffer::for_kernel_buffer(const_cast<u8*>((const u8*)target.characters_without_null_termination())); auto target_buffer = UserOrKernelBuffer::for_kernel_buffer(const_cast<u8*>((const u8*)target.characters_without_null_termination()));
ssize_t nwritten = inode->write_bytes(0, target.length(), target_buffer, nullptr); auto result = inode->write_bytes(0, target.length(), target_buffer, nullptr);
if (nwritten < 0) if (result.is_error())
return KResult((ErrnoCode)-nwritten); return result.error();
return KSuccess; return KSuccess;
} }

View file

@ -50,8 +50,8 @@ static bool should_make_executable_exception_for_dynamic_loader(bool make_readab
Elf32_Ehdr header; Elf32_Ehdr header;
auto buffer = UserOrKernelBuffer::for_kernel_buffer((u8*)&header); auto buffer = UserOrKernelBuffer::for_kernel_buffer((u8*)&header);
auto nread = inode.read_bytes(0, sizeof(header), buffer, nullptr); auto result = inode.read_bytes(0, sizeof(header), buffer, nullptr);
if (nread != sizeof(header)) if (result.is_error() || result.value() != sizeof(header))
return false; return false;
// The file is a valid ELF binary // The file is a valid ELF binary

View file

@ -540,13 +540,14 @@ PageFaultResponse Region::handle_inode_fault(size_t page_index_in_region, Scoped
// Reading the page may block, so release the MM lock temporarily // Reading the page may block, so release the MM lock temporarily
mm_lock.unlock(); mm_lock.unlock();
auto buffer = UserOrKernelBuffer::for_kernel_buffer(page_buffer); auto buffer = UserOrKernelBuffer::for_kernel_buffer(page_buffer);
auto nread = inode.read_bytes(page_index_in_vmobject * PAGE_SIZE, PAGE_SIZE, buffer, nullptr); auto result = inode.read_bytes(page_index_in_vmobject * PAGE_SIZE, PAGE_SIZE, buffer, nullptr);
mm_lock.lock(); mm_lock.lock();
if (nread < 0) { if (result.is_error()) {
dmesgln("MM: handle_inode_fault had error ({}) while reading!", nread); dmesgln("MM: handle_inode_fault had error ({}) while reading!", result.error());
return PageFaultResponse::ShouldCrash; return PageFaultResponse::ShouldCrash;
} }
auto nread = result.value();
if (nread < PAGE_SIZE) { if (nread < PAGE_SIZE) {
// If we read less than a page, zero out the rest to avoid leaking uninitialized data. // If we read less than a page, zero out the rest to avoid leaking uninitialized data.
memset(page_buffer + nread, 0, PAGE_SIZE - nread); memset(page_buffer + nread, 0, PAGE_SIZE - nread);