Refactor FS::find_parent_of_inode() into Inode::parent().

This way, Ext2FSInode can cache its parent inode index. This makes absolute
path lookups dramatically faster.
SynthFSInode is also simplified greatly.
This commit is contained in:
Andreas Kling 2019-01-04 18:37:58 +01:00
parent 7731aef7b2
commit 0d36281162
Notes: sideshowbarker 2024-07-19 16:06:06 +09:00
6 changed files with 28 additions and 21 deletions

View file

@ -924,33 +924,33 @@ RetainPtr<Inode> Ext2FS::create_inode(InodeIdentifier parent_id, const String& n
return get_inode({ id(), inode_id });
}
InodeIdentifier Ext2FS::find_parent_of_inode(InodeIdentifier inode_id) const
RetainPtr<Inode> Ext2FSInode::parent() const
{
auto inode = get_inode(inode_id);
ASSERT(inode);
if (m_parent_id.is_valid())
return fs().get_inode(m_parent_id);
unsigned groupIndex = group_index_from_inode(inode->index());
unsigned firstInodeInGroup = inodes_per_group() * (groupIndex - 1);
unsigned group_index = fs().group_index_from_inode(index());
unsigned first_inode_in_group = fs().inodes_per_group() * (group_index - 1);
Vector<RetainPtr<Ext2FSInode>> directories_in_group;
for (unsigned i = 0; i < inodes_per_group(); ++i) {
auto group_member = get_inode({ id(), firstInodeInGroup + i });
for (unsigned i = 0; i < fs().inodes_per_group(); ++i) {
auto group_member = fs().get_inode({ fsid(), first_inode_in_group + i });
if (!group_member)
continue;
if (group_member->is_directory())
directories_in_group.append(move(group_member));
}
InodeIdentifier foundParent;
for (auto& directory : directories_in_group) {
if (!directory->reverse_lookup(inode->identifier()).is_null()) {
foundParent = directory->identifier();
if (!directory->reverse_lookup(identifier()).is_null()) {
m_parent_id = directory->identifier();
break;
}
}
return foundParent;
ASSERT(m_parent_id.is_valid());
return fs().get_inode(m_parent_id);
}
void Ext2FSInode::populate_lookup_cache()

View file

@ -34,6 +34,7 @@ private:
virtual void flush_metadata() override;
virtual bool write(const ByteBuffer&) override;
virtual bool add_child(InodeIdentifier child_id, const String& name, byte file_type, int& error) override;
virtual RetainPtr<Inode> parent() const override;
virtual int set_atime(Unix::time_t) override;
virtual int set_ctime(Unix::time_t) override;
virtual int set_mtime(Unix::time_t) override;
@ -50,6 +51,7 @@ private:
Vector<unsigned> m_block_list;
HashMap<String, unsigned> m_lookup_cache;
ext2_inode m_raw_inode;
mutable InodeIdentifier m_parent_id;
};
class Ext2FS final : public DiskBackedFS {
@ -83,7 +85,6 @@ private:
virtual InodeIdentifier root_inode() const override;
virtual RetainPtr<Inode> create_inode(InodeIdentifier parentInode, const String& name, Unix::mode_t, unsigned size, int& error) override;
virtual RetainPtr<Inode> create_directory(InodeIdentifier parentInode, const String& name, Unix::mode_t, int& error) override;
virtual InodeIdentifier find_parent_of_inode(InodeIdentifier) const override;
virtual RetainPtr<Inode> get_inode(InodeIdentifier) const override;
unsigned allocate_inode(unsigned preferredGroup, unsigned expectedSize);

View file

@ -46,8 +46,6 @@ public:
virtual RetainPtr<Inode> create_inode(InodeIdentifier parentInode, const String& name, Unix::mode_t, unsigned size, int& error) = 0;
virtual RetainPtr<Inode> create_directory(InodeIdentifier parentInode, const String& name, Unix::mode_t, int& error) = 0;
virtual InodeIdentifier find_parent_of_inode(InodeIdentifier) const = 0;
virtual RetainPtr<Inode> get_inode(InodeIdentifier) const = 0;
protected:
@ -85,6 +83,7 @@ public:
virtual String reverse_lookup(InodeIdentifier) = 0;
virtual bool write(const ByteBuffer&) = 0;
virtual bool add_child(InodeIdentifier child_id, const String& name, byte file_type, int& error) = 0;
virtual RetainPtr<Inode> parent() const = 0;
bool is_metadata_dirty() const { return m_metadata_dirty; }

View file

@ -158,12 +158,9 @@ auto SynthFS::generate_inode_index() -> InodeIndex
return m_next_inode_index++;
}
InodeIdentifier SynthFS::find_parent_of_inode(InodeIdentifier inode) const
RetainPtr<Inode> SynthFSInode::parent() const
{
auto it = m_inodes.find(inode.index());
if (it == m_inodes.end())
return { };
return (*it).value->m_parent;
return fs().get_inode(m_parent);
}
RetainPtr<Inode> SynthFS::get_inode(InodeIdentifier inode) const

View file

@ -16,7 +16,6 @@ public:
virtual InodeIdentifier root_inode() const override;
virtual RetainPtr<Inode> create_inode(InodeIdentifier parentInode, const String& name, Unix::mode_t, unsigned size, int& error) override;
virtual RetainPtr<Inode> create_directory(InodeIdentifier parentInode, const String& name, Unix::mode_t, int& error) override;
virtual InodeIdentifier find_parent_of_inode(InodeIdentifier) const override;
virtual RetainPtr<Inode> get_inode(InodeIdentifier) const override;
protected:
@ -54,6 +53,7 @@ private:
virtual void flush_metadata() override;
virtual bool write(const ByteBuffer&) override;
virtual bool add_child(InodeIdentifier child_id, const String& name, byte file_type, int& error) override;
virtual RetainPtr<Inode> parent() const override;
SynthFS& fs();
const SynthFS& fs() const;
@ -66,3 +66,13 @@ private:
Vector<SynthFSInode*> m_children;
InodeMetadata m_metadata;
};
inline SynthFS& SynthFSInode::fs()
{
return static_cast<SynthFS&>(Inode::fs());
}
inline const SynthFS& SynthFSInode::fs() const
{
return static_cast<const SynthFS&>(Inode::fs());
}

View file

@ -346,7 +346,7 @@ String VFS::absolute_path(Inode& core_inode)
if (inode->is_directory()) {
parent_id = resolve_path("..", inode->identifier(), error);
} else {
parent_id = inode->fs().find_parent_of_inode(inode->identifier());
parent_id = inode->parent()->identifier();
}
ASSERT(parent_id.is_valid());
inode = get_inode(parent_id);