diff --git a/Kernel/FileSystem/SysFS/Component.cpp b/Kernel/FileSystem/SysFS/Component.cpp index af366a5880..38d5de68ab 100644 --- a/Kernel/FileSystem/SysFS/Component.cpp +++ b/Kernel/FileSystem/SysFS/Component.cpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace Kernel { @@ -21,11 +22,36 @@ static size_t allocate_inode_index() return s_next_inode_index.value(); } +SysFSComponent::SysFSComponent(SysFSDirectory const& parent_directory) + : m_parent_directory(parent_directory) + , m_component_index(allocate_inode_index()) +{ +} + SysFSComponent::SysFSComponent() : m_component_index(allocate_inode_index()) { } +ErrorOr> SysFSComponent::relative_path(NonnullOwnPtr name, size_t current_hop) const +{ + if (current_hop >= 128) + return Error::from_errno(ELOOP); + if (!m_parent_directory) + return name; + auto joined_name = TRY(KLexicalPath::try_join(m_parent_directory->name(), name->view())); + return m_parent_directory->relative_path(move(joined_name), current_hop + 1); +} + +ErrorOr SysFSComponent::relative_path_hops_count_from_mountpoint(size_t current_hop) const +{ + if (current_hop >= 128) + return Error::from_errno(ELOOP); + if (!m_parent_directory) + return current_hop; + return m_parent_directory->relative_path_hops_count_from_mountpoint(current_hop + 1); +} + mode_t SysFSComponent::permissions() const { return S_IRUSR | S_IRGRP | S_IROTH; @@ -56,8 +82,7 @@ RefPtr SysFSDirectory::lookup(StringView name) } SysFSDirectory::SysFSDirectory(SysFSDirectory const& parent_directory) - : SysFSComponent() - , m_parent_directory(parent_directory) + : SysFSComponent(parent_directory) { } diff --git a/Kernel/FileSystem/SysFS/Component.h b/Kernel/FileSystem/SysFS/Component.h index b7d1032e8c..62162a29c9 100644 --- a/Kernel/FileSystem/SysFS/Component.h +++ b/Kernel/FileSystem/SysFS/Component.h @@ -23,6 +23,7 @@ struct SysFSInodeData : public OpenFileDescriptionData { OwnPtr buffer; }; +class SysFSDirectory; class SysFSComponent : public RefCounted { public: virtual StringView name() const = 0; @@ -42,9 +43,15 @@ public: virtual ~SysFSComponent() = default; + ErrorOr> relative_path(NonnullOwnPtr, size_t current_hop = 0) const; + ErrorOr relative_path_hops_count_from_mountpoint(size_t current_hop = 0) const; + protected: + explicit SysFSComponent(SysFSDirectory const& parent_directory); SysFSComponent(); + RefPtr m_parent_directory; + private: InodeIndex m_component_index {}; }; @@ -57,10 +64,9 @@ public: virtual ErrorOr> to_inode(SysFS const& sysfs_instance) const override final; protected: - SysFSDirectory() = default; + SysFSDirectory() {}; explicit SysFSDirectory(SysFSDirectory const& parent_directory); NonnullRefPtrVector m_components; - RefPtr m_parent_directory; }; }