Compare commits
74 Commits
3a13017ede
...
26623f8a0d
Author | SHA1 | Date | |
---|---|---|---|
26623f8a0d | |||
0cc2b64cee | |||
1a79a3beda | |||
b415e9a81a | |||
77da94339d | |||
072793ce43 | |||
ffc7274272 | |||
2fbf75a8b5 | |||
f79515ed00 | |||
7d4d797d01 | |||
c7c7d7b751 | |||
fd77ec4fab | |||
a3751d9ce5 | |||
869bbbe122 | |||
17dde92c7b | |||
f60ab19ed1 | |||
364556911f | |||
d26ef849d9 | |||
03cdd125d1 | |||
815c2321a1 | |||
a044b14b75 | |||
6701530f7f | |||
0000bdaac5 | |||
b870cd1f8b | |||
21da3c7bda | |||
113fce5792 | |||
ec61bdbfc5 | |||
b9967cd0a7 | |||
af78427228 | |||
89f156ad64 | |||
8536752646 | |||
3359a8be90 | |||
f4cd33a94a | |||
8966690b34 | |||
841de6efcb | |||
39d6128095 | |||
faaea22d11 | |||
fe5936e507 | |||
7570724525 | |||
e21b7d645d | |||
3750c1da57 | |||
ca8306bc35 | |||
a5b3b10a98 | |||
20f6ef04d3 | |||
37332b2a67 | |||
01cf9735eb | |||
fc35c32671 | |||
889588599b | |||
47ea92536a | |||
33a4cd0616 | |||
d23df0672c | |||
8cc882b4e2 | |||
d30a40f3bf | |||
a8d3c0b400 | |||
c66330d319 | |||
cb54c16852 | |||
8d2f5f1de0 | |||
de72ae340b | |||
0dcd890a5a | |||
9c1e85dbdd | |||
943677f2e5 | |||
3287f4fe55 | |||
aa9abdcd5a | |||
f6e60bd715 | |||
b7ecc9e776 | |||
731601cc13 | |||
d43f33e289 | |||
60a292c12c | |||
ad3446e82b | |||
ad888ebf3e | |||
ef26e7400e | |||
bd4e2ba351 | |||
66e3d71dbc | |||
6065b63801 |
@ -503,11 +503,17 @@ namespace ATA
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_identify_data.big_lba) m_is_lba48 = true;
|
u8 buf[8];
|
||||||
|
memcpy(buf, &m_identify_words[100], 8);
|
||||||
|
|
||||||
if (m_is_lba48) m_block_count = m_identify_data.sectors_48;
|
m_block_count = *reinterpret_cast<u64*>(buf);
|
||||||
else
|
|
||||||
m_block_count = m_identify_data.sectors_28;
|
if (!m_block_count)
|
||||||
|
{
|
||||||
|
memcpy(buf, &m_identify_words[60], 4);
|
||||||
|
m_block_count = *reinterpret_cast<u32*>(buf);
|
||||||
|
}
|
||||||
|
else { m_is_lba48 = true; }
|
||||||
|
|
||||||
// FIXME: Should we check for CHS?
|
// FIXME: Should we check for CHS?
|
||||||
|
|
||||||
|
@ -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
|
Result<usize> Inode::read(u8* buf, usize offset, usize length) const
|
||||||
{
|
{
|
||||||
if (length == 0) return 0;
|
if (length == 0) return 0;
|
||||||
@ -66,22 +73,47 @@ namespace Ext2
|
|||||||
{
|
{
|
||||||
if (index < 12) return m_raw_inode.direct_pointers[index];
|
if (index < 12) return m_raw_inode.direct_pointers[index];
|
||||||
|
|
||||||
usize block_index = (index - 12) * sizeof(u32);
|
const usize block_size = m_fs->m_block_size;
|
||||||
if (block_index >= m_fs->m_block_size)
|
const usize blocks_per_indirect_block = block_size / sizeof(u32);
|
||||||
{
|
|
||||||
fail("ext2: Finding blocks beyond the singly indirect pointer block is not yet supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
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_block_buffer.data(), m_raw_inode.singly_indirect_ptr * block_size,
|
||||||
TRY(m_fs->m_host_device->read(m_singly_indirect_block.data(), m_raw_inode.singly_indirect_ptr * block_size,
|
|
||||||
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
|
Result<void> Inode::lazy_initialize_dir() const
|
||||||
|
@ -115,7 +115,7 @@ namespace Ext2
|
|||||||
FileSystem* m_fs;
|
FileSystem* m_fs;
|
||||||
ino_t m_inum;
|
ino_t m_inum;
|
||||||
|
|
||||||
mutable Buffer m_singly_indirect_block;
|
mutable Buffer m_block_buffer;
|
||||||
|
|
||||||
String m_link;
|
String m_link;
|
||||||
|
|
||||||
@ -123,6 +123,7 @@ namespace Ext2
|
|||||||
mutable bool m_dir_already_lazily_initialized { false };
|
mutable bool m_dir_already_lazily_initialized { false };
|
||||||
|
|
||||||
Result<usize> find_block(usize index) const;
|
Result<usize> find_block(usize index) const;
|
||||||
|
Result<void> prepare_buffer() const;
|
||||||
|
|
||||||
friend class FileSystem;
|
friend class FileSystem;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user