mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-20 16:10:29 +00:00
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
This commit is contained in:
@ -96,14 +96,12 @@ class Vfs::Block_file_system::Data_file_system : public Single_file_system
|
|||||||
Block::Packet_descriptor::Opcode op;
|
Block::Packet_descriptor::Opcode op;
|
||||||
op = write ? Block::Packet_descriptor::WRITE : Block::Packet_descriptor::READ;
|
op = write ? Block::Packet_descriptor::WRITE : Block::Packet_descriptor::READ;
|
||||||
|
|
||||||
file_size packet_size = bulk ? sz : _block_size;
|
size_t packet_count = bulk ? (size_t)(sz / _block_size) : 1;
|
||||||
file_size packet_count = bulk ? (sz / _block_size) : 1;
|
|
||||||
|
|
||||||
Block::Packet_descriptor packet;
|
Block::Packet_descriptor packet;
|
||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (packet_count > _block_buffer_count) {
|
if (packet_count > _block_buffer_count) {
|
||||||
packet_size = _block_buffer_count * _block_size;
|
|
||||||
packet_count = _block_buffer_count;
|
packet_count = _block_buffer_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +109,7 @@ class Vfs::Block_file_system::Data_file_system : public Single_file_system
|
|||||||
try {
|
try {
|
||||||
Mutex::Guard guard(_mutex);
|
Mutex::Guard guard(_mutex);
|
||||||
|
|
||||||
packet = _block.alloc_packet((size_t)packet_size);
|
packet = _block.alloc_packet(packet_count * _block_size);
|
||||||
break;
|
break;
|
||||||
} catch (Block::Session::Tx::Source::Packet_alloc_failed) {
|
} 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();
|
_ep.wait_and_dispatch_one_io_signal();
|
||||||
|
|
||||||
if (packet_count > 1) {
|
if (packet_count > 1) {
|
||||||
packet_size /= 2;
|
|
||||||
packet_count /= 2;
|
packet_count /= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Mutex::Guard guard(_mutex);
|
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)
|
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);
|
_tx_source->submit_packet(p);
|
||||||
|
|
||||||
@ -144,10 +141,10 @@ class Vfs::Block_file_system::Data_file_system : public Single_file_system
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!write)
|
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);
|
_tx_source->release_packet(p);
|
||||||
return packet_size;
|
return packet_count * _block_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Reference in New Issue
Block a user