diff --git a/Kernel/Devices/Storage/StorageDevicePartition.cpp b/Kernel/Devices/Storage/StorageDevicePartition.cpp index 6c29b56825..452829d6b0 100644 --- a/Kernel/Devices/Storage/StorageDevicePartition.cpp +++ b/Kernel/Devices/Storage/StorageDevicePartition.cpp @@ -47,30 +47,24 @@ void StorageDevicePartition::start_request(AsyncBlockDeviceRequest& request) ErrorOr StorageDevicePartition::read(OpenFileDescription& fd, u64 offset, UserOrKernelBuffer& outbuf, size_t len) { + // NOTE: The last available offset is actually just after the last addressable block. + if (offset >= (m_metadata.end_block() - m_metadata.start_block() + 1) * block_size()) + return 0; + size_t nread = min(static_cast((m_metadata.end_block() - m_metadata.start_block() + 1) - offset), len); u64 adjust = m_metadata.start_block() * block_size(); - dbgln_if(OFFD_DEBUG, "StorageDevicePartition::read offset={}, adjust={}, len={}", fd.offset(), adjust, len); - return m_device.strong_ref()->read(fd, offset + adjust, outbuf, len); -} - -bool StorageDevicePartition::can_read(OpenFileDescription const& fd, u64 offset) const -{ - u64 adjust = m_metadata.start_block() * block_size(); - dbgln_if(OFFD_DEBUG, "StorageDevicePartition::can_read offset={}, adjust={}", offset, adjust); - return m_device.strong_ref()->can_read(fd, offset + adjust); + dbgln_if(OFFD_DEBUG, "StorageDevicePartition::read offset={}, adjust={}, len={}", fd.offset(), adjust, nread); + return m_device.strong_ref()->read(fd, offset + adjust, outbuf, nread); } ErrorOr StorageDevicePartition::write(OpenFileDescription& fd, u64 offset, UserOrKernelBuffer const& inbuf, size_t len) { + // NOTE: The last available offset is actually just after the last addressable block. + if (offset >= (m_metadata.end_block() - m_metadata.start_block() + 1) * block_size()) + return Error::from_errno(ENOSPC); + size_t nwrite = min(static_cast((m_metadata.end_block() - m_metadata.start_block() + 1) - offset), len); u64 adjust = m_metadata.start_block() * block_size(); - dbgln_if(OFFD_DEBUG, "StorageDevicePartition::write offset={}, adjust={}, len={}", offset, adjust, len); - return m_device.strong_ref()->write(fd, offset + adjust, inbuf, len); -} - -bool StorageDevicePartition::can_write(OpenFileDescription const& fd, u64 offset) const -{ - u64 adjust = m_metadata.start_block() * block_size(); - dbgln_if(OFFD_DEBUG, "StorageDevicePartition::can_write offset={}, adjust={}", offset, adjust); - return m_device.strong_ref()->can_write(fd, offset + adjust); + dbgln_if(OFFD_DEBUG, "StorageDevicePartition::write offset={}, adjust={}, len={}", offset, adjust, nwrite); + return m_device.strong_ref()->write(fd, offset + adjust, inbuf, nwrite); } StringView StorageDevicePartition::class_name() const diff --git a/Kernel/Devices/Storage/StorageDevicePartition.h b/Kernel/Devices/Storage/StorageDevicePartition.h index 1d3f77ece5..2426ae564a 100644 --- a/Kernel/Devices/Storage/StorageDevicePartition.h +++ b/Kernel/Devices/Storage/StorageDevicePartition.h @@ -24,9 +24,13 @@ public: // ^BlockDevice virtual ErrorOr read(OpenFileDescription&, u64, UserOrKernelBuffer&, size_t) override; - virtual bool can_read(OpenFileDescription const&, u64) const override; virtual ErrorOr write(OpenFileDescription&, u64, UserOrKernelBuffer const&, size_t) override; - virtual bool can_write(OpenFileDescription const&, u64) const override; + + // NOTE: Technically we need to query the underlying StorageDevice, + // but since it will always return true in both of these methods, + // we can return true here too. + virtual bool can_read(OpenFileDescription const&, u64) const override { return true; } + virtual bool can_write(OpenFileDescription const&, u64) const override { return true; } Partition::DiskPartitionMetadata const& metadata() const;