diff options
author | Liav A <liavalb@gmail.com> | 2021-08-10 20:51:28 +0300 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-08-12 20:57:32 +0200 |
commit | 7ba991dc371ecd055829699852f7cb821472667f (patch) | |
tree | 1c53f16ae0de005e8f539a15f12329453b5d4f4a /Kernel/FileSystem/ProcFS.h | |
parent | bf1adc2d5d383c0421f19ccb36a0358ff2ee0ce5 (diff) | |
download | serenity-7ba991dc371ecd055829699852f7cb821472667f.zip |
Kernel: Steer away from heap allocations for ProcFS process data
Instead, use more static patterns to acquire that sort of data.
Diffstat (limited to 'Kernel/FileSystem/ProcFS.h')
-rw-r--r-- | Kernel/FileSystem/ProcFS.h | 139 |
1 files changed, 119 insertions, 20 deletions
diff --git a/Kernel/FileSystem/ProcFS.h b/Kernel/FileSystem/ProcFS.h index 9ffecfedf8..49b4d89b44 100644 --- a/Kernel/FileSystem/ProcFS.h +++ b/Kernel/FileSystem/ProcFS.h @@ -14,12 +14,17 @@ #include <Kernel/KBufferBuilder.h> #include <Kernel/Locking/Mutex.h> #include <Kernel/ProcessExposed.h> +#include <Kernel/UnixTypes.h> namespace Kernel { class ProcFS final : public FileSystem { friend class ProcFSInode; friend class ProcFSDirectoryInode; + friend class ProcFSProcessDirectoryInode; + friend class ProcFSGlobalInode; + friend class ProcFSAssociatedProcessInode; + friend class ProcFSProcessSubDirectoryInode; public: virtual ~ProcFS() override; @@ -40,33 +45,50 @@ class ProcFSInode : public Inode { friend class ProcFS; public: - static NonnullRefPtr<ProcFSInode> create(const ProcFS&, const ProcFSExposedComponent&); virtual ~ProcFSInode() override; + +protected: + ProcFSInode(const ProcFS&, InodeIndex); + + ProcFS& procfs() { return static_cast<ProcFS&>(Inode::fs()); } + ProcFS const& procfs() const { return static_cast<ProcFS const&>(Inode::fs()); } + + // ^Inode + virtual KResult attach(FileDescription& description) = 0; + virtual void did_seek(FileDescription&, off_t) = 0; + virtual void flush_metadata() override final; + virtual KResultOr<NonnullRefPtr<Inode>> create_child(StringView name, mode_t, dev_t, uid_t, gid_t) override final; + virtual KResult add_child(Inode&, const StringView& name, mode_t) override final; + virtual KResult remove_child(const StringView& name) override final; + virtual KResult chmod(mode_t) override final; + virtual KResult chown(uid_t, gid_t) override final; + virtual KResult truncate(u64) override final; +}; + +class ProcFSGlobalInode : public ProcFSInode { + friend class ProcFS; + +public: + static NonnullRefPtr<ProcFSGlobalInode> create(const ProcFS&, const ProcFSExposedComponent&); + virtual ~ProcFSGlobalInode() override {}; StringView name() const; protected: - ProcFSInode(const ProcFS&, const ProcFSExposedComponent&); + ProcFSGlobalInode(const ProcFS&, const ProcFSExposedComponent&); // ^Inode - virtual KResult attach(FileDescription& description) override; - virtual KResultOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, FileDescription*) const override; - virtual KResult traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override; - virtual RefPtr<Inode> lookup(StringView name) override; - virtual void flush_metadata() override; + virtual KResult attach(FileDescription& description) override final; + virtual KResultOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, FileDescription*) const override final; + virtual KResultOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer& buffer, FileDescription*) override final; + virtual void did_seek(FileDescription&, off_t) override final; virtual InodeMetadata metadata() const override; - virtual KResultOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer& buffer, FileDescription*) override; - virtual KResultOr<NonnullRefPtr<Inode>> create_child(StringView name, mode_t, dev_t, uid_t, gid_t) override; - virtual KResult add_child(Inode&, const StringView& name, mode_t) override; - virtual KResult remove_child(const StringView& name) override; - virtual void did_seek(FileDescription&, off_t) override; - virtual KResult chmod(mode_t) override; - virtual KResult chown(uid_t, gid_t) override; - virtual KResult truncate(u64) override; + virtual KResult traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override; + virtual RefPtr<Inode> lookup(StringView) override; NonnullRefPtr<ProcFSExposedComponent> m_associated_component; }; -class ProcFSLinkInode : public ProcFSInode { +class ProcFSLinkInode : public ProcFSGlobalInode { friend class ProcFS; public: @@ -77,16 +99,13 @@ protected: virtual InodeMetadata metadata() const override; }; -class ProcFSDirectoryInode : public ProcFSInode { +class ProcFSDirectoryInode final : public ProcFSGlobalInode { friend class ProcFS; public: static NonnullRefPtr<ProcFSDirectoryInode> create(const ProcFS&, const ProcFSExposedComponent&); virtual ~ProcFSDirectoryInode() override; - ProcFS& fs() { return static_cast<ProcFS&>(Inode::fs()); } - ProcFS const& fs() const { return static_cast<ProcFS const&>(Inode::fs()); } - protected: ProcFSDirectoryInode(const ProcFS&, const ProcFSExposedComponent&); // ^Inode @@ -95,4 +114,84 @@ protected: virtual RefPtr<Inode> lookup(StringView name) override; }; +class ProcFSProcessAssociatedInode : public ProcFSInode { + friend class ProcFS; + +protected: + ProcFSProcessAssociatedInode(const ProcFS&, ProcessID, InodeIndex); + ProcessID associated_pid() const { return m_pid; } + + // ^Inode + virtual KResultOr<size_t> write_bytes(off_t, size_t, const UserOrKernelBuffer& buffer, FileDescription*) override final; + +private: + const ProcessID m_pid; +}; + +class ProcFSProcessDirectoryInode final : public ProcFSProcessAssociatedInode { + friend class ProcFS; + +public: + static NonnullRefPtr<ProcFSProcessDirectoryInode> create(const ProcFS&, ProcessID); + +private: + ProcFSProcessDirectoryInode(const ProcFS&, ProcessID); + // ^Inode + virtual KResult attach(FileDescription& description) override; + virtual void did_seek(FileDescription&, off_t) override { } + virtual InodeMetadata metadata() const override; + virtual KResult traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override; + virtual KResultOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, FileDescription*) const override final; + virtual RefPtr<Inode> lookup(StringView name) override; +}; + +class ProcFSProcessSubDirectoryInode final : public ProcFSProcessAssociatedInode { + friend class ProcFS; + +public: + static NonnullRefPtr<ProcFSProcessSubDirectoryInode> create(const ProcFS&, SegmentedProcFSIndex::ProcessSubDirectory, ProcessID); + +private: + ProcFSProcessSubDirectoryInode(const ProcFS&, SegmentedProcFSIndex::ProcessSubDirectory, ProcessID); + // ^Inode + virtual KResult attach(FileDescription& description) override; + virtual void did_seek(FileDescription&, off_t) override; + virtual InodeMetadata metadata() const override; + virtual KResult traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override; + virtual KResultOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, FileDescription*) const override final; + virtual RefPtr<Inode> lookup(StringView name) override; + + const SegmentedProcFSIndex::ProcessSubDirectory m_sub_directory_type; +}; + +class ProcFSProcessPropertyInode final : public ProcFSProcessAssociatedInode { + friend class ProcFS; + +public: + static NonnullRefPtr<ProcFSProcessPropertyInode> create_for_file_description_link(const ProcFS&, unsigned, ProcessID); + static NonnullRefPtr<ProcFSProcessPropertyInode> create_for_thread_stack(const ProcFS&, ThreadID, ProcessID); + static NonnullRefPtr<ProcFSProcessPropertyInode> create_for_pid_property(const ProcFS&, SegmentedProcFSIndex::MainProcessProperty, ProcessID); + +private: + ProcFSProcessPropertyInode(const ProcFS&, SegmentedProcFSIndex::MainProcessProperty, ProcessID); + ProcFSProcessPropertyInode(const ProcFS&, ThreadID, ProcessID); + ProcFSProcessPropertyInode(const ProcFS&, unsigned, ProcessID); + // ^Inode + virtual KResult attach(FileDescription& description) override; + virtual void did_seek(FileDescription&, off_t) override; + virtual InodeMetadata metadata() const override; + virtual KResult traverse_as_directory(Function<bool(FileSystem::DirectoryEntryView const&)>) const override; + virtual KResultOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, FileDescription*) const override final; + virtual RefPtr<Inode> lookup(StringView name) override final; + + KResult refresh_data(FileDescription& description); + KResult try_to_acquire_data(Process& process, KBufferBuilder& builder) const; + + const SegmentedProcFSIndex::ProcessSubDirectory m_parent_sub_directory_type; + union { + SegmentedProcFSIndex::MainProcessProperty property_type; + unsigned property_index; + } m_possible_data; + mutable Mutex m_refresh_lock; +}; } |