kernel/ext2: Add support for files larger than 4MB
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
e029679fba
commit
6065b63801
@ -7,6 +7,13 @@ namespace Ext2
|
||||
{
|
||||
}
|
||||
|
||||
Result<void> Inode::prepare_buffer() const
|
||||
{
|
||||
if (!m_block_buffer.is_empty()) return {};
|
||||
return m_block_buffer.try_resize(m_fs->m_block_size);
|
||||
}
|
||||
|
||||
// FIXME: This code seems awfully similar to BlockDevice::read(). Can this be merged with it in some way?
|
||||
Result<usize> Inode::read(u8* buf, usize offset, usize length) const
|
||||
{
|
||||
if (length == 0) return 0;
|
||||
@ -66,22 +73,47 @@ namespace Ext2
|
||||
{
|
||||
if (index < 12) return m_raw_inode.direct_pointers[index];
|
||||
|
||||
usize block_index = (index - 12) * sizeof(u32);
|
||||
if (block_index >= m_fs->m_block_size)
|
||||
{
|
||||
fail("ext2: Finding blocks beyond the singly indirect pointer block is not yet supported");
|
||||
}
|
||||
const usize block_size = m_fs->m_block_size;
|
||||
const usize blocks_per_indirect_block = block_size / sizeof(u32);
|
||||
|
||||
usize block_size = m_fs->m_block_size;
|
||||
index -= 12;
|
||||
|
||||
if (m_singly_indirect_block.is_empty())
|
||||
TRY(prepare_buffer());
|
||||
|
||||
// Singly indirect block
|
||||
if (index < blocks_per_indirect_block)
|
||||
{
|
||||
TRY(m_singly_indirect_block.try_resize(block_size));
|
||||
TRY(m_fs->m_host_device->read(m_singly_indirect_block.data(), m_raw_inode.singly_indirect_ptr * block_size,
|
||||
TRY(m_fs->m_host_device->read(m_block_buffer.data(), m_raw_inode.singly_indirect_ptr * block_size,
|
||||
block_size));
|
||||
return ((u32*)m_block_buffer.data())[index];
|
||||
}
|
||||
|
||||
return *reinterpret_cast<u32*>(&m_singly_indirect_block.data()[block_index]);
|
||||
index -= blocks_per_indirect_block;
|
||||
|
||||
// Doubly indirect block
|
||||
if (index < blocks_per_indirect_block * blocks_per_indirect_block)
|
||||
{
|
||||
TRY(m_fs->m_host_device->read(m_block_buffer.data(), m_raw_inode.doubly_indirect_ptr * block_size,
|
||||
block_size));
|
||||
const u32 block = ((u32*)m_block_buffer.data())[index / blocks_per_indirect_block];
|
||||
|
||||
TRY(m_fs->m_host_device->read(m_block_buffer.data(), block * block_size, block_size));
|
||||
return ((u32*)m_block_buffer.data())[index % blocks_per_indirect_block];
|
||||
}
|
||||
|
||||
index -= blocks_per_indirect_block * blocks_per_indirect_block;
|
||||
|
||||
check(index < blocks_per_indirect_block * blocks_per_indirect_block * blocks_per_indirect_block);
|
||||
|
||||
// Triply indirect block
|
||||
TRY(m_fs->m_host_device->read(m_block_buffer.data(), m_raw_inode.triply_indirect_ptr * block_size, block_size));
|
||||
u32 block = ((u32*)m_block_buffer.data())[index / (blocks_per_indirect_block * blocks_per_indirect_block)];
|
||||
|
||||
TRY(m_fs->m_host_device->read(m_block_buffer.data(), block * block_size, block_size));
|
||||
block = ((u32*)m_block_buffer.data())[(index / blocks_per_indirect_block) % blocks_per_indirect_block];
|
||||
|
||||
TRY(m_fs->m_host_device->read(m_block_buffer.data(), block * block_size, block_size));
|
||||
return ((u32*)m_block_buffer.data())[index % blocks_per_indirect_block];
|
||||
}
|
||||
|
||||
Result<void> Inode::lazy_initialize_dir() const
|
||||
|
@ -115,7 +115,7 @@ namespace Ext2
|
||||
FileSystem* m_fs;
|
||||
ino_t m_inum;
|
||||
|
||||
mutable Buffer m_singly_indirect_block;
|
||||
mutable Buffer m_block_buffer;
|
||||
|
||||
String m_link;
|
||||
|
||||
@ -123,6 +123,7 @@ namespace Ext2
|
||||
mutable bool m_dir_already_lazily_initialized { false };
|
||||
|
||||
Result<usize> find_block(usize index) const;
|
||||
Result<void> prepare_buffer() const;
|
||||
|
||||
friend class FileSystem;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user