Kernel: Fix ext2 inode deletion cleanup
I now cleanup all blocks (including direct) in i_block array
This commit is contained in:
parent
98d702ac60
commit
99bde9aa49
|
@ -49,6 +49,7 @@ namespace Kernel
|
|||
BAN::ErrorOr<void> link_inode_to_directory(Ext2Inode&, BAN::StringView name);
|
||||
BAN::ErrorOr<bool> is_directory_empty();
|
||||
|
||||
void cleanup_indirect_block(uint32_t block, uint32_t depth);
|
||||
BAN::ErrorOr<void> cleanup_default_links();
|
||||
void cleanup_from_fs();
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#define EXT2_DEBUG_PRINT 0
|
||||
#define EXT2_VERIFY_INODE 0
|
||||
#define EXT2_VERIFY_NO_BLOCKS 1
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
@ -244,6 +245,10 @@ namespace Kernel
|
|||
auto inode_location = locate_inode(ino);
|
||||
read_block(inode_location.block, inode_buffer);
|
||||
auto& inode = inode_buffer.span().slice(inode_location.offset).as<Ext2::Inode>();
|
||||
#if EXT2_VERIFY_NO_BLOCKS
|
||||
static const char zero_buffer[sizeof(inode.block)] {};
|
||||
ASSERT(memcmp(inode.block, zero_buffer, sizeof(inode.block)) == 0);
|
||||
#endif
|
||||
bool is_directory = Inode::Mode(inode.mode).ifdir();
|
||||
memset(&inode, 0x00, m_superblock.inode_size);
|
||||
write_block(inode_location.block, inode_buffer);
|
||||
|
|
|
@ -259,11 +259,54 @@ namespace Kernel
|
|||
return {};
|
||||
}
|
||||
|
||||
void Ext2Inode::cleanup_indirect_block(uint32_t block, uint32_t depth)
|
||||
{
|
||||
ASSERT(block);
|
||||
|
||||
if (depth == 0)
|
||||
{
|
||||
m_fs.release_block(block);
|
||||
return;
|
||||
}
|
||||
|
||||
auto block_buffer = m_fs.get_block_buffer();
|
||||
m_fs.read_block(block, block_buffer);
|
||||
|
||||
const uint32_t ids_per_block = blksize() / sizeof(uint32_t);
|
||||
for (uint32_t i = 0; i < ids_per_block; i++)
|
||||
{
|
||||
const uint32_t idx = ((uint32_t*)block_buffer.data())[i];
|
||||
if (idx > 0)
|
||||
cleanup_indirect_block(idx, depth - 1);
|
||||
}
|
||||
|
||||
m_fs.release_block(block);
|
||||
}
|
||||
|
||||
void Ext2Inode::cleanup_from_fs()
|
||||
{
|
||||
ASSERT(m_inode.links_count == 0);
|
||||
for (uint32_t i = 0; i < blocks(); i++)
|
||||
m_fs.release_block(fs_block_of_data_block_index(i));
|
||||
|
||||
// cleanup direct blocks
|
||||
for (uint32_t i = 0; i < 12; i++)
|
||||
if (m_inode.block[i])
|
||||
m_fs.release_block(m_inode.block[i]);
|
||||
|
||||
// cleanup indirect blocks
|
||||
if (m_inode.block[12])
|
||||
cleanup_indirect_block(m_inode.block[12], 1);
|
||||
if (m_inode.block[13])
|
||||
cleanup_indirect_block(m_inode.block[13], 2);
|
||||
if (m_inode.block[14])
|
||||
cleanup_indirect_block(m_inode.block[14], 3);
|
||||
|
||||
// mark blocks as deleted
|
||||
memset(m_inode.block, 0x00, sizeof(m_inode.block));
|
||||
|
||||
// FIXME: this is only required since fs does not get
|
||||
// deleting inode from its cache
|
||||
sync();
|
||||
|
||||
m_fs.delete_inode(ino());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue