diff options
author | Andreas Kling <kling@serenityos.org> | 2021-01-17 16:56:07 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-01-17 16:56:07 +0100 |
commit | 6613cef2f8c63eb033c73a70654213f2b18aa078 (patch) | |
tree | c4278cdf6c96b6027e13868ba8244d557e7a3294 /Kernel/FileSystem | |
parent | 1382bbfc57abfc6d3e89d53c837ffefc0f72b13d (diff) | |
download | serenity-6613cef2f8c63eb033c73a70654213f2b18aa078.zip |
Ext2FS: Update block group directory count after directory removal
When freeing an inode, we were checking if it's a directory *after*
wiping the inode metadata. This caused us to forget updating the block
group descriptor with the new directory count.
Diffstat (limited to 'Kernel/FileSystem')
-rw-r--r-- | Kernel/FileSystem/Ext2FileSystem.cpp | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/Kernel/FileSystem/Ext2FileSystem.cpp b/Kernel/FileSystem/Ext2FileSystem.cpp index 2037c75313..a097d05d9f 100644 --- a/Kernel/FileSystem/Ext2FileSystem.cpp +++ b/Kernel/FileSystem/Ext2FileSystem.cpp @@ -531,28 +531,29 @@ void Ext2FS::free_inode(Ext2FSInode& inode) dbgln("Ext2FS: Inode {} has no more links, time to delete!", inode.index()); #endif + // Mark all blocks used by this inode as free. auto block_list = block_list_for_inode(inode.m_raw_inode, true); - for (auto block_index : block_list) { ASSERT(block_index <= super_block().s_blocks_count); if (block_index) set_block_allocation_state(block_index, false); } - struct timeval now; - kgettimeofday(now); - memset(&inode.m_raw_inode, 0, sizeof(ext2_inode)); - inode.m_raw_inode.i_dtime = now.tv_sec; - write_ext2_inode(inode.index(), inode.m_raw_inode); - - set_inode_allocation_state(inode.index(), false); - + // If the inode being freed is a directory, update block group directory counter. if (inode.is_directory()) { auto& bgd = const_cast<ext2_group_desc&>(group_descriptor(group_index_from_inode(inode.index()))); --bgd.bg_used_dirs_count; dbgln("Ext2FS: Decremented bg_used_dirs_count to {}", bgd.bg_used_dirs_count); m_block_group_descriptors_dirty = true; } + + // NOTE: After this point, the inode metadata is wiped. + memset(&inode.m_raw_inode, 0, sizeof(ext2_inode)); + inode.m_raw_inode.i_dtime = kgettimeofday().tv_sec; + write_ext2_inode(inode.index(), inode.m_raw_inode); + + // Mark the inode as free. + set_inode_allocation_state(inode.index(), false); } void Ext2FS::flush_block_group_descriptor_table() |