Serenity Operating System
at master 95 lines 3.8 kB view raw
1/* 2 * Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org> 3 * Copyright (c) 2022-2023, Liav A. <liavalb@hotmail.co.il> 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8#pragma once 9 10#include <Kernel/FileSystem/Inode.h> 11#include <Kernel/FileSystem/RAMFS/FileSystem.h> 12#include <Kernel/Forward.h> 13#include <Kernel/Memory/AnonymousVMObject.h> 14 15namespace Kernel { 16 17class RAMFSInode final : public Inode { 18 friend class RAMFS; 19 20public: 21 virtual ~RAMFSInode() override; 22 23 RAMFS& fs() { return static_cast<RAMFS&>(Inode::fs()); } 24 RAMFS const& fs() const { return static_cast<RAMFS const&>(Inode::fs()); } 25 26 // ^Inode 27 virtual InodeMetadata metadata() const override; 28 virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override; 29 virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override; 30 virtual ErrorOr<void> flush_metadata() override; 31 virtual ErrorOr<NonnullRefPtr<Inode>> create_child(StringView name, mode_t, dev_t, UserID, GroupID) override; 32 virtual ErrorOr<void> add_child(Inode&, StringView name, mode_t) override; 33 virtual ErrorOr<void> remove_child(StringView name) override; 34 virtual ErrorOr<void> replace_child(StringView name, Inode& child) override; 35 virtual ErrorOr<void> chmod(mode_t) override; 36 virtual ErrorOr<void> chown(UserID, GroupID) override; 37 virtual ErrorOr<void> truncate(u64) override; 38 virtual ErrorOr<void> update_timestamps(Optional<Time> atime, Optional<Time> ctime, Optional<Time> mtime) override; 39 40private: 41 RAMFSInode(RAMFS& fs, InodeMetadata const& metadata, LockWeakPtr<RAMFSInode> parent); 42 explicit RAMFSInode(RAMFS& fs); 43 static ErrorOr<NonnullRefPtr<RAMFSInode>> try_create(RAMFS&, InodeMetadata const& metadata, LockWeakPtr<RAMFSInode> parent); 44 static ErrorOr<NonnullRefPtr<RAMFSInode>> try_create_root(RAMFS&); 45 46 // ^Inode 47 virtual ErrorOr<size_t> read_bytes_locked(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override; 48 virtual ErrorOr<size_t> write_bytes_locked(off_t, size_t, UserOrKernelBuffer const& buffer, OpenFileDescription*) override; 49 50 ErrorOr<size_t> do_io_on_content_space(Memory::Region& mapping_region, size_t offset, size_t io_size, UserOrKernelBuffer& buffer, bool write); 51 52 struct Child { 53 NonnullOwnPtr<KString> name; 54 NonnullRefPtr<RAMFSInode> inode; 55 IntrusiveListNode<Child> list_node {}; 56 using List = IntrusiveList<&Child::list_node>; 57 }; 58 59 Child* find_child_by_name(StringView); 60 61 InodeMetadata m_metadata; 62 LockWeakPtr<RAMFSInode> m_parent; 63 64 ErrorOr<void> ensure_allocated_blocks(size_t offset, size_t io_size); 65 ErrorOr<void> truncate_to_block_index(size_t block_index); 66 ErrorOr<size_t> read_bytes_from_content_space(size_t offset, size_t io_size, UserOrKernelBuffer& buffer) const; 67 ErrorOr<size_t> write_bytes_to_content_space(size_t offset, size_t io_size, UserOrKernelBuffer const& buffer); 68 69 struct DataBlock { 70 public: 71 using List = Vector<OwnPtr<DataBlock>>; 72 73 static ErrorOr<NonnullOwnPtr<DataBlock>> create(); 74 75 constexpr static size_t block_size = 128 * KiB; 76 77 Memory::AnonymousVMObject& vmobject() { return *m_content_buffer_vmobject; } 78 Memory::AnonymousVMObject const& vmobject() const { return *m_content_buffer_vmobject; } 79 80 private: 81 explicit DataBlock(NonnullLockRefPtr<Memory::AnonymousVMObject> content_buffer_vmobject) 82 : m_content_buffer_vmobject(move(content_buffer_vmobject)) 83 { 84 } 85 86 NonnullLockRefPtr<Memory::AnonymousVMObject> m_content_buffer_vmobject; 87 }; 88 89 bool const m_root_directory_inode { false }; 90 91 DataBlock::List m_blocks; 92 Child::List m_children; 93}; 94 95}