#include "fs/ext2/Inode.h" namespace Ext2 { Inode::Inode(Badge, FileSystem* fs) : m_fs(fs) { } Result Inode::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 block_size = m_fs->m_block_size; usize to_read = length; if (offset % block_size) { usize block_offset = (offset % block_size); usize block = find_block(offset / block_size); usize size_to_read = block_size - block_offset; usize host_offset = (block * block_size) + block_offset; // FIXME: Cache this data. TRY(m_fs->m_host_device->read(buf, host_offset, size_to_read)); to_read -= size_to_read; buf += size_to_read; offset += size_to_read; } while (to_read >= block_size) { usize block = find_block(offset / block_size); usize host_offset = block * block_size; // FIXME: Cache this data. TRY(m_fs->m_host_device->read(buf, host_offset, block_size)); to_read -= block_size; buf += block_size; offset += block_size; } if (to_read > 0) { usize block = find_block(offset / block_size); usize host_offset = block * block_size; // FIXME: Cache this data. TRY(m_fs->m_host_device->read(buf, host_offset, to_read)); } return length; } usize Inode::find_block(usize index) const { expect(index < 12, "ext2: Finding blocks in the indirect pointers is not yet supported"); return m_raw_inode.direct_pointers[index]; } }