Some checks failed
continuous-integration/drone/push Build is failing
The trick being caching lol.
52 lines
1.4 KiB
C++
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;
|
|
}
|