Luna/kernel/src/fs/devices/BlockDevice.cpp
apio d43590e68c
Some checks failed
continuous-integration/drone/push Build is failing
kernel: Improve Your Disk IO performance by 500% with this One Trick!
The trick being caching lol.
2023-08-16 14:54:13 +02:00

52 lines
1.4 KiB
C++

#include "fs/devices/BlockDevice.h"
#include "arch/MMU.h"
#include <luna/Common.h>
BlockDevice::BlockDevice(u64 block_size, u64 num_blocks) : m_cache(), m_block_size(block_size), m_num_blocks(num_blocks)
{
}
Result<usize> BlockDevice::read(u8* buf, usize offset, usize length) const
{
if (length == 0) return 0;
if (offset > size()) return 0;
if (offset + length > size()) length = size() - offset;
const usize saved = length;
auto read_data = [&](u64 off, u64 len) -> Result<void> {
const u64 block = offset / m_block_size;
m_cache.lock();
auto guard = make_scope_guard([&] { m_cache.unlock(); });
auto* entry = TRY(m_cache.fetch_entry(block));
if (entry->buffer.is_empty())
{
// TODO: What if the cache needs clearing in the middle of try_resize()? That could lead to some weird
// state...
TRY(entry->buffer.try_resize(m_block_size));
TRY(read_block(entry->buffer, block));
}
memcpy(buf, entry->buffer.data() + off, len);
offset += len;
length -= len;
buf += len;
return {};
};
if (offset % m_block_size)
{
const u64 off = offset % m_block_size;
const u64 len = min(m_block_size - off, length);
TRY(read_data(off, len));
}
while (length >= m_block_size) { TRY(read_data(0, m_block_size)); }
if (length) { TRY(read_data(0, length)); }
return saved;
}