diff --git a/VirtualFileSystem/Ext2FileSystem.cpp b/VirtualFileSystem/Ext2FileSystem.cpp index d616b448fe..56d01a08cf 100644 --- a/VirtualFileSystem/Ext2FileSystem.cpp +++ b/VirtualFileSystem/Ext2FileSystem.cpp @@ -924,33 +924,33 @@ RetainPtr 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 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> 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() diff --git a/VirtualFileSystem/Ext2FileSystem.h b/VirtualFileSystem/Ext2FileSystem.h index d531231b96..a9c279c3af 100644 --- a/VirtualFileSystem/Ext2FileSystem.h +++ b/VirtualFileSystem/Ext2FileSystem.h @@ -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 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 m_block_list; HashMap 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 create_inode(InodeIdentifier parentInode, const String& name, Unix::mode_t, unsigned size, int& error) override; virtual RetainPtr create_directory(InodeIdentifier parentInode, const String& name, Unix::mode_t, int& error) override; - virtual InodeIdentifier find_parent_of_inode(InodeIdentifier) const override; virtual RetainPtr get_inode(InodeIdentifier) const override; unsigned allocate_inode(unsigned preferredGroup, unsigned expectedSize); diff --git a/VirtualFileSystem/FileSystem.h b/VirtualFileSystem/FileSystem.h index 9a5a81e49d..ae147bca98 100644 --- a/VirtualFileSystem/FileSystem.h +++ b/VirtualFileSystem/FileSystem.h @@ -46,8 +46,6 @@ public: virtual RetainPtr create_inode(InodeIdentifier parentInode, const String& name, Unix::mode_t, unsigned size, int& error) = 0; virtual RetainPtr create_directory(InodeIdentifier parentInode, const String& name, Unix::mode_t, int& error) = 0; - virtual InodeIdentifier find_parent_of_inode(InodeIdentifier) const = 0; - virtual RetainPtr 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 parent() const = 0; bool is_metadata_dirty() const { return m_metadata_dirty; } diff --git a/VirtualFileSystem/SyntheticFileSystem.cpp b/VirtualFileSystem/SyntheticFileSystem.cpp index aaa1abf16c..b3afec2445 100644 --- a/VirtualFileSystem/SyntheticFileSystem.cpp +++ b/VirtualFileSystem/SyntheticFileSystem.cpp @@ -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 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 SynthFS::get_inode(InodeIdentifier inode) const diff --git a/VirtualFileSystem/SyntheticFileSystem.h b/VirtualFileSystem/SyntheticFileSystem.h index fa6bf9eb7a..c1b43fdee1 100644 --- a/VirtualFileSystem/SyntheticFileSystem.h +++ b/VirtualFileSystem/SyntheticFileSystem.h @@ -16,7 +16,6 @@ public: virtual InodeIdentifier root_inode() const override; virtual RetainPtr create_inode(InodeIdentifier parentInode, const String& name, Unix::mode_t, unsigned size, int& error) override; virtual RetainPtr create_directory(InodeIdentifier parentInode, const String& name, Unix::mode_t, int& error) override; - virtual InodeIdentifier find_parent_of_inode(InodeIdentifier) const override; virtual RetainPtr 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 parent() const override; SynthFS& fs(); const SynthFS& fs() const; @@ -66,3 +66,13 @@ private: Vector m_children; InodeMetadata m_metadata; }; + +inline SynthFS& SynthFSInode::fs() +{ + return static_cast(Inode::fs()); +} + +inline const SynthFS& SynthFSInode::fs() const +{ + return static_cast(Inode::fs()); +} diff --git a/VirtualFileSystem/VirtualFileSystem.cpp b/VirtualFileSystem/VirtualFileSystem.cpp index dea9972dc1..9144017d63 100644 --- a/VirtualFileSystem/VirtualFileSystem.cpp +++ b/VirtualFileSystem/VirtualFileSystem.cpp @@ -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);