mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 19:07:35 +00:00
Ext2FS: Don't cache a full Ext2FSInode object for non-existent inodes.
This was a bit silly. We were always creating Ext2FSInode objects when Ext2FSInode::get_inode() was called. They'd then sit and fatten up the inode cache forever, despite not representing allocated inodes. This patch consults the inode bitmap and if get_inode() is called with an unallocated inode index, we simply cache a nullptr to represent the fact that this index is unused. This could be a lot better optimized, it will currently hit the disk for every new inode index encountered.
This commit is contained in:
parent
d07b08a287
commit
8f9542174f
2 changed files with 27 additions and 1 deletions
|
@ -262,6 +262,12 @@ RetainPtr<Inode> Ext2FS::get_inode(InodeIdentifier inode) const
|
||||||
return (*it).value;
|
return (*it).value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!get_inode_allocation_state(inode.index())) {
|
||||||
|
LOCKER(m_inode_cache_lock);
|
||||||
|
m_inode_cache.set(inode.index(), nullptr);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned block_index;
|
unsigned block_index;
|
||||||
unsigned offset;
|
unsigned offset;
|
||||||
auto block = read_block_containing_inode(inode.index(), block_index, offset);
|
auto block = read_block_containing_inode(inode.index(), block_index, offset);
|
||||||
|
@ -688,6 +694,21 @@ unsigned Ext2FS::group_index_from_inode(unsigned inode) const
|
||||||
return (inode - 1) / inodes_per_group() + 1;
|
return (inode - 1) / inodes_per_group() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Ext2FS::get_inode_allocation_state(InodeIndex index) const
|
||||||
|
{
|
||||||
|
if (index == 0)
|
||||||
|
return true;
|
||||||
|
auto& bgd = group_descriptor(group_index_from_inode(index));
|
||||||
|
|
||||||
|
unsigned inodesPerBitmapBlock = blockSize() * 8;
|
||||||
|
unsigned bitmapBlockIndex = (index - 1) / inodesPerBitmapBlock;
|
||||||
|
unsigned bitIndex = (index - 1) % inodesPerBitmapBlock;
|
||||||
|
auto block = readBlock(bgd.bg_inode_bitmap + bitmapBlockIndex);
|
||||||
|
ASSERT(block);
|
||||||
|
auto bitmap = Bitmap::wrap(block.pointer(), block.size());
|
||||||
|
return bitmap.get(bitIndex);
|
||||||
|
}
|
||||||
|
|
||||||
bool Ext2FS::set_inode_allocation_state(unsigned inode, bool newState)
|
bool Ext2FS::set_inode_allocation_state(unsigned inode, bool newState)
|
||||||
{
|
{
|
||||||
auto& bgd = group_descriptor(group_index_from_inode(inode));
|
auto& bgd = group_descriptor(group_index_from_inode(inode));
|
||||||
|
@ -901,6 +922,11 @@ RetainPtr<Inode> Ext2FS::create_inode(InodeIdentifier parent_id, const String& n
|
||||||
success = write_ext2_inode(inode_id, *e2inode);
|
success = write_ext2_inode(inode_id, *e2inode);
|
||||||
ASSERT(success);
|
ASSERT(success);
|
||||||
|
|
||||||
|
{
|
||||||
|
// We might have cached the fact that this inode didn't exist. Wipe the slate.
|
||||||
|
LOCKER(m_inode_cache_lock);
|
||||||
|
m_inode_cache.remove(inode_id);
|
||||||
|
}
|
||||||
return get_inode({ id(), inode_id });
|
return get_inode({ id(), inode_id });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -915,7 +941,6 @@ InodeIdentifier Ext2FS::find_parent_of_inode(InodeIdentifier inode_id) const
|
||||||
Vector<RetainPtr<Ext2FSInode>> directories_in_group;
|
Vector<RetainPtr<Ext2FSInode>> directories_in_group;
|
||||||
|
|
||||||
for (unsigned i = 0; i < inodes_per_group(); ++i) {
|
for (unsigned i = 0; i < inodes_per_group(); ++i) {
|
||||||
// FIXME: Consult the inode bitmap to see which inodes to look into.
|
|
||||||
auto group_member = get_inode({ id(), firstInodeInGroup + i });
|
auto group_member = get_inode({ id(), firstInodeInGroup + i });
|
||||||
if (!group_member)
|
if (!group_member)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -100,6 +100,7 @@ private:
|
||||||
|
|
||||||
bool add_inode_to_directory(InodeIndex parent, InodeIndex child, const String& name, byte fileType, int& error);
|
bool add_inode_to_directory(InodeIndex parent, InodeIndex child, const String& name, byte fileType, int& error);
|
||||||
bool write_directory_inode(unsigned directoryInode, Vector<DirectoryEntry>&&);
|
bool write_directory_inode(unsigned directoryInode, Vector<DirectoryEntry>&&);
|
||||||
|
bool get_inode_allocation_state(InodeIndex) const;
|
||||||
bool set_inode_allocation_state(unsigned inode, bool);
|
bool set_inode_allocation_state(unsigned inode, bool);
|
||||||
bool set_block_allocation_state(GroupIndex, BlockIndex, bool);
|
bool set_block_allocation_state(GroupIndex, BlockIndex, bool);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue