From fd9648f9192dbe24552a69f02d95cc4f3f78845f Mon Sep 17 00:00:00 2001 From: Christian Helmuth Date: Tue, 5 Apr 2022 14:14:05 +0200 Subject: [PATCH] vfs/block: correct transfer size allocation The calculations of packet_size and packet_count in the block_io() did not consider rounding errors. This resulted in diverging values over several bisecting operations (/= 2) and wrongly-size packet allocations as well as memcpy operations. Related to #2263 (comments about partial block accesses and _block_io()). Fixes #4471 --- repos/os/src/lib/vfs/block_file_system.h | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/repos/os/src/lib/vfs/block_file_system.h b/repos/os/src/lib/vfs/block_file_system.h index d67bccf8e4..6093c965ea 100644 --- a/repos/os/src/lib/vfs/block_file_system.h +++ b/repos/os/src/lib/vfs/block_file_system.h @@ -96,14 +96,12 @@ class Vfs::Block_file_system::Data_file_system : public Single_file_system Block::Packet_descriptor::Opcode op; op = write ? Block::Packet_descriptor::WRITE : Block::Packet_descriptor::READ; - file_size packet_size = bulk ? sz : _block_size; - file_size packet_count = bulk ? (sz / _block_size) : 1; + size_t packet_count = bulk ? (size_t)(sz / _block_size) : 1; Block::Packet_descriptor packet; /* sanity check */ if (packet_count > _block_buffer_count) { - packet_size = _block_buffer_count * _block_size; packet_count = _block_buffer_count; } @@ -111,7 +109,7 @@ class Vfs::Block_file_system::Data_file_system : public Single_file_system try { Mutex::Guard guard(_mutex); - packet = _block.alloc_packet((size_t)packet_size); + packet = _block.alloc_packet(packet_count * _block_size); break; } catch (Block::Session::Tx::Source::Packet_alloc_failed) { @@ -119,17 +117,16 @@ class Vfs::Block_file_system::Data_file_system : public Single_file_system _ep.wait_and_dispatch_one_io_signal(); if (packet_count > 1) { - packet_size /= 2; packet_count /= 2; } } } Mutex::Guard guard(_mutex); - Block::Packet_descriptor p(packet, op, nr, (size_t)packet_count); + Block::Packet_descriptor p(packet, op, nr, packet_count); if (write) - Genode::memcpy(_tx_source->packet_content(p), buf, (size_t)packet_size); + Genode::memcpy(_tx_source->packet_content(p), buf, packet_count * _block_size); _tx_source->submit_packet(p); @@ -144,10 +141,10 @@ class Vfs::Block_file_system::Data_file_system : public Single_file_system } if (!write) - Genode::memcpy(buf, _tx_source->packet_content(p), (size_t)packet_size); + Genode::memcpy(buf, _tx_source->packet_content(p), packet_count * _block_size); _tx_source->release_packet(p); - return packet_size; + return packet_count * _block_size; } public: