Serenity Operating System
at master 93 lines 3.5 kB view raw
1/* 2 * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <AK/AtomicRefCounted.h> 10#include <AK/Error.h> 11#include <AK/Function.h> 12#include <AK/StringView.h> 13#include <AK/Types.h> 14#include <Kernel/FileSystem/File.h> 15#include <Kernel/FileSystem/FileSystem.h> 16#include <Kernel/FileSystem/OpenFileDescription.h> 17#include <Kernel/Forward.h> 18#include <Kernel/Library/LockRefPtr.h> 19 20namespace Kernel { 21 22struct SysFSInodeData : public OpenFileDescriptionData { 23 OwnPtr<KBuffer> buffer; 24}; 25 26class SysFSDirectory; 27class SysFSComponent : public AtomicRefCounted<SysFSComponent> { 28 friend class SysFSDirectory; 29 30public: 31 virtual StringView name() const = 0; 32 virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const { return Error::from_errno(ENOTIMPL); } 33 virtual ErrorOr<void> traverse_as_directory(FileSystemID, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const { VERIFY_NOT_REACHED(); } 34 virtual LockRefPtr<SysFSComponent> lookup(StringView) { VERIFY_NOT_REACHED(); }; 35 virtual mode_t permissions() const; 36 virtual ErrorOr<void> truncate(u64) { return EPERM; } 37 virtual size_t size() const { return 0; } 38 virtual ErrorOr<size_t> write_bytes(off_t, size_t, UserOrKernelBuffer const&, OpenFileDescription*) { return EROFS; } 39 virtual ErrorOr<void> refresh_data(OpenFileDescription&) const { return {}; } 40 41 virtual ErrorOr<NonnullRefPtr<SysFSInode>> to_inode(SysFS const&) const; 42 43 InodeIndex component_index() const { return m_component_index; }; 44 45 virtual ~SysFSComponent() = default; 46 47 ErrorOr<NonnullOwnPtr<KString>> relative_path(NonnullOwnPtr<KString>, size_t current_hop = 0) const; 48 ErrorOr<size_t> relative_path_hops_count_from_mountpoint(size_t current_hop = 0) const; 49 50protected: 51 explicit SysFSComponent(SysFSDirectory const& parent_directory); 52 SysFSComponent(); 53 54 LockRefPtr<SysFSDirectory> m_parent_directory; 55 56 IntrusiveListNode<SysFSComponent, NonnullLockRefPtr<SysFSComponent>> m_list_node; 57 58private: 59 InodeIndex m_component_index {}; 60}; 61 62class SysFSSymbolicLink : public SysFSComponent { 63public: 64 virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const override final; 65 virtual ErrorOr<NonnullRefPtr<SysFSInode>> to_inode(SysFS const& sysfs_instance) const override final; 66 67protected: 68 ErrorOr<NonnullOwnPtr<KString>> try_generate_return_path_to_mount_point() const; 69 ErrorOr<NonnullOwnPtr<KBuffer>> try_to_generate_buffer() const; 70 71 explicit SysFSSymbolicLink(SysFSDirectory const& parent_directory, SysFSComponent const& pointed_component); 72 73 LockRefPtr<SysFSComponent> m_pointed_component; 74}; 75 76class SysFSDirectory : public SysFSComponent { 77public: 78 virtual ErrorOr<void> traverse_as_directory(FileSystemID, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override final; 79 virtual LockRefPtr<SysFSComponent> lookup(StringView name) override final; 80 81 virtual ErrorOr<NonnullRefPtr<SysFSInode>> to_inode(SysFS const& sysfs_instance) const override final; 82 83 using ChildList = SpinlockProtected<IntrusiveList<&SysFSComponent::m_list_node>, LockRank::None>; 84 85protected: 86 virtual bool is_root_directory() const { return false; } 87 88 SysFSDirectory() {}; 89 explicit SysFSDirectory(SysFSDirectory const& parent_directory); 90 ChildList m_child_components {}; 91}; 92 93}