From a10e63f08e848a648dafa7f75766dda8259caee6 Mon Sep 17 00:00:00 2001 From: Liav A Date: Fri, 5 Jan 2024 11:18:02 +0200 Subject: [PATCH] Kernel/FileSystem: Send proper filetypes when traversing RAM-backed FSes SysFS, ProcFS and DevPtsFS were all sending filetype 0 when traversing their directories, but it is actually very easy to send proper filetypes in these filesystems. This patch binds all RAM backed filesystems to use only one enum for their internal filetype, to simplify the implementation and allow sharing of code. Please note that the Plan9FS case is currently not solved as I am not familiar with this filesystem and its constructs. The ProcFS mostly keeps track of the filetype, and a fix was needed for the /proc root directory - all processes exhibit a directory inside it which makes it very easy to hardcode the directory filetype for them. There's also the `self` symlink inode which is now exposed as DT_LNK. As for SysFS, we could leverage the fact everything inherits from the SysFSComponent class, so we could have a virtual const method to return the proper filetype. Most of the files in SysFS are "regular" files though, so the base class has a non-pure virtual method. Lastly, the DevPtsFS simply hardcodes '.' and '..' as directory file type, and everything else is hardcoded to send the character device file type, as this filesystem is only exposing character pts device files. --- Kernel/FileSystem/DevPtsFS/FileSystem.cpp | 5 ++ Kernel/FileSystem/DevPtsFS/FileSystem.h | 2 + Kernel/FileSystem/DevPtsFS/Inode.cpp | 9 ++- Kernel/FileSystem/ProcFS/Definitions.h | 39 +++++------ Kernel/FileSystem/ProcFS/FileSystem.cpp | 6 ++ Kernel/FileSystem/ProcFS/FileSystem.h | 2 + Kernel/FileSystem/ProcFS/Inode.cpp | 11 ++-- Kernel/FileSystem/ProcFS/ProcessExposed.cpp | 39 +++++------ Kernel/FileSystem/RAMBackedFileType.h | 71 +++++++++++++++++++++ Kernel/FileSystem/RAMFS/FileSystem.cpp | 23 +------ Kernel/FileSystem/RAMFS/FileSystem.h | 13 +--- Kernel/FileSystem/RAMFS/Inode.cpp | 33 ++-------- Kernel/FileSystem/SysFS/Component.cpp | 10 +-- Kernel/FileSystem/SysFS/Component.h | 9 ++- Kernel/FileSystem/SysFS/FileSystem.cpp | 6 ++ Kernel/FileSystem/SysFS/FileSystem.h | 2 + 16 files changed, 169 insertions(+), 111 deletions(-) create mode 100644 Kernel/FileSystem/RAMBackedFileType.h diff --git a/Kernel/FileSystem/DevPtsFS/FileSystem.cpp b/Kernel/FileSystem/DevPtsFS/FileSystem.cpp index 2cffb27f6e..027aa15d0d 100644 --- a/Kernel/FileSystem/DevPtsFS/FileSystem.cpp +++ b/Kernel/FileSystem/DevPtsFS/FileSystem.cpp @@ -44,6 +44,11 @@ Inode& DevPtsFS::root_inode() return *m_root_inode; } +u8 DevPtsFS::internal_file_type_to_directory_entry_type(DirectoryEntryView const& entry) const +{ + return ram_backed_file_type_to_directory_entry_type(entry); +} + ErrorOr> DevPtsFS::get_inode(InodeIdentifier inode_id) const { if (inode_id.index() == 1) diff --git a/Kernel/FileSystem/DevPtsFS/FileSystem.h b/Kernel/FileSystem/DevPtsFS/FileSystem.h index 56dd51f7e5..be2629606b 100644 --- a/Kernel/FileSystem/DevPtsFS/FileSystem.h +++ b/Kernel/FileSystem/DevPtsFS/FileSystem.h @@ -28,6 +28,8 @@ public: virtual Inode& root_inode() override; private: + virtual u8 internal_file_type_to_directory_entry_type(DirectoryEntryView const& entry) const override; + DevPtsFS(); ErrorOr> get_inode(InodeIdentifier) const; diff --git a/Kernel/FileSystem/DevPtsFS/Inode.cpp b/Kernel/FileSystem/DevPtsFS/Inode.cpp index ebfbb16d04..134defca02 100644 --- a/Kernel/FileSystem/DevPtsFS/Inode.cpp +++ b/Kernel/FileSystem/DevPtsFS/Inode.cpp @@ -7,6 +7,7 @@ #include #include +#include namespace Kernel { @@ -49,15 +50,17 @@ ErrorOr DevPtsFSInode::traverse_as_directory(Function(FileSy if (identifier().index() > 1) return ENOTDIR; - TRY(callback({ "."sv, identifier(), 0 })); - TRY(callback({ ".."sv, identifier(), 0 })); + TRY(callback({ "."sv, identifier(), to_underlying(RAMBackedFileType::Directory) })); + TRY(callback({ ".."sv, identifier(), to_underlying(RAMBackedFileType::Directory) })); return SlavePTY::all_instances().with([&](auto& list) -> ErrorOr { StringBuilder builder; for (SlavePTY& slave_pty : list) { builder.clear(); TRY(builder.try_appendff("{}", slave_pty.index())); - TRY(callback({ builder.string_view(), { fsid(), pty_index_to_inode_index(slave_pty.index()) }, 0 })); + // NOTE: We represent directory entries with DT_CHR as all + // inodes in this filesystem are assumed to be char devices. + TRY(callback({ builder.string_view(), { fsid(), pty_index_to_inode_index(slave_pty.index()) }, to_underlying(RAMBackedFileType::Character) })); } return {}; }); diff --git a/Kernel/FileSystem/ProcFS/Definitions.h b/Kernel/FileSystem/ProcFS/Definitions.h index d47ddf0563..63303bc3c6 100644 --- a/Kernel/FileSystem/ProcFS/Definitions.h +++ b/Kernel/FileSystem/ProcFS/Definitions.h @@ -8,45 +8,46 @@ #include #include +#include namespace Kernel { struct segmented_global_inode_index { StringView name; - u8 file_type; + RAMBackedFileType file_type; u32 primary; u16 subdirectory; u32 property; }; constexpr segmented_global_inode_index global_inode_ids[] = { - { "."sv, DT_DIR, 0, 0, 1 }, // NOTE: This is here for the root directory - { "self"sv, DT_DIR, 0, 0, 2 } + { "."sv, RAMBackedFileType::Directory, 0, 0, 1 }, // NOTE: This is here for the root directory + { "self"sv, RAMBackedFileType::Directory, 0, 0, 2 } }; struct segmented_process_directory_entry { StringView name; - u8 file_type; + RAMBackedFileType file_type; u16 subdirectory; u32 property; }; -constexpr segmented_process_directory_entry main_process_directory_root_entry = { "."sv, DT_DIR, 0, 0 }; -constexpr segmented_process_directory_entry process_fd_subdirectory_root_entry = { "."sv, DT_DIR, 1, 0 }; -constexpr segmented_process_directory_entry process_stacks_subdirectory_root_entry = { "."sv, DT_DIR, 2, 0 }; -constexpr segmented_process_directory_entry process_children_subdirectory_root_entry = { "."sv, DT_DIR, 3, 0 }; +constexpr segmented_process_directory_entry main_process_directory_root_entry = { "."sv, RAMBackedFileType::Directory, 0, 0 }; +constexpr segmented_process_directory_entry process_fd_subdirectory_root_entry = { "."sv, RAMBackedFileType::Directory, 1, 0 }; +constexpr segmented_process_directory_entry process_stacks_subdirectory_root_entry = { "."sv, RAMBackedFileType::Directory, 2, 0 }; +constexpr segmented_process_directory_entry process_children_subdirectory_root_entry = { "."sv, RAMBackedFileType::Directory, 3, 0 }; -constexpr segmented_process_directory_entry process_fd_directory_entry = { "fd"sv, DT_DIR, 1, 0 }; -constexpr segmented_process_directory_entry process_stacks_directory_entry = { "stacks"sv, DT_DIR, 2, 0 }; -constexpr segmented_process_directory_entry process_children_directory_entry = { "children"sv, DT_DIR, 3, 0 }; -constexpr segmented_process_directory_entry process_unveil_list_entry = { "unveil"sv, DT_REG, 0, 1 }; -constexpr segmented_process_directory_entry process_pledge_list_entry = { "pledge"sv, DT_REG, 0, 2 }; -constexpr segmented_process_directory_entry process_fds_list_entry = { "fds"sv, DT_REG, 0, 3 }; -constexpr segmented_process_directory_entry process_exe_symlink_entry = { "exe"sv, DT_LNK, 0, 4 }; -constexpr segmented_process_directory_entry process_cwd_symlink_entry = { "cwd"sv, DT_LNK, 0, 5 }; -constexpr segmented_process_directory_entry process_perf_events_entry = { "perf_events"sv, DT_REG, 0, 6 }; -constexpr segmented_process_directory_entry process_vm_entry = { "vm"sv, DT_REG, 0, 7 }; -constexpr segmented_process_directory_entry process_cmdline_entry = { "cmdline"sv, DT_REG, 0, 8 }; +constexpr segmented_process_directory_entry process_fd_directory_entry = { "fd"sv, RAMBackedFileType::Directory, 1, 0 }; +constexpr segmented_process_directory_entry process_stacks_directory_entry = { "stacks"sv, RAMBackedFileType::Directory, 2, 0 }; +constexpr segmented_process_directory_entry process_children_directory_entry = { "children"sv, RAMBackedFileType::Directory, 3, 0 }; +constexpr segmented_process_directory_entry process_unveil_list_entry = { "unveil"sv, RAMBackedFileType::Regular, 0, 1 }; +constexpr segmented_process_directory_entry process_pledge_list_entry = { "pledge"sv, RAMBackedFileType::Regular, 0, 2 }; +constexpr segmented_process_directory_entry process_fds_list_entry = { "fds"sv, RAMBackedFileType::Regular, 0, 3 }; +constexpr segmented_process_directory_entry process_exe_symlink_entry = { "exe"sv, RAMBackedFileType::Link, 0, 4 }; +constexpr segmented_process_directory_entry process_cwd_symlink_entry = { "cwd"sv, RAMBackedFileType::Link, 0, 5 }; +constexpr segmented_process_directory_entry process_perf_events_entry = { "perf_events"sv, RAMBackedFileType::Regular, 0, 6 }; +constexpr segmented_process_directory_entry process_vm_entry = { "vm"sv, RAMBackedFileType::Regular, 0, 7 }; +constexpr segmented_process_directory_entry process_cmdline_entry = { "cmdline"sv, RAMBackedFileType::Regular, 0, 8 }; constexpr segmented_process_directory_entry main_process_directory_entries[] = { process_fd_directory_entry, process_stacks_directory_entry, diff --git a/Kernel/FileSystem/ProcFS/FileSystem.cpp b/Kernel/FileSystem/ProcFS/FileSystem.cpp index d4cec65c1e..bd0f751a76 100644 --- a/Kernel/FileSystem/ProcFS/FileSystem.cpp +++ b/Kernel/FileSystem/ProcFS/FileSystem.cpp @@ -8,6 +8,7 @@ #include #include +#include namespace Kernel { @@ -32,6 +33,11 @@ ErrorOr ProcFS::initialize() return {}; } +u8 ProcFS::internal_file_type_to_directory_entry_type(DirectoryEntryView const& entry) const +{ + return ram_backed_file_type_to_directory_entry_type(entry); +} + Inode& ProcFS::root_inode() { return *m_root_inode; diff --git a/Kernel/FileSystem/ProcFS/FileSystem.h b/Kernel/FileSystem/ProcFS/FileSystem.h index 143c283565..ec48330006 100644 --- a/Kernel/FileSystem/ProcFS/FileSystem.h +++ b/Kernel/FileSystem/ProcFS/FileSystem.h @@ -28,6 +28,8 @@ public: virtual Inode& root_inode() override; private: + virtual u8 internal_file_type_to_directory_entry_type(DirectoryEntryView const& entry) const override; + ProcFS(); ErrorOr> get_inode(InodeIdentifier) const; diff --git a/Kernel/FileSystem/ProcFS/Inode.cpp b/Kernel/FileSystem/ProcFS/Inode.cpp index 83b7c9fda7..8c93ddb756 100644 --- a/Kernel/FileSystem/ProcFS/Inode.cpp +++ b/Kernel/FileSystem/ProcFS/Inode.cpp @@ -1,12 +1,13 @@ /* * Copyright (c) 2018-2021, Andreas Kling * Copyright (c) 2021, Spencer Dixon - * Copyright (c) 2021-2023, Liav A. + * Copyright (c) 2021-2024, Liav A. * * SPDX-License-Identifier: BSD-2-Clause */ #include +#include #include #include @@ -108,16 +109,16 @@ ProcFSInode::ProcFSInode(ProcFS const& procfs_instance, InodeIndex inode_index) ErrorOr ProcFSInode::traverse_as_root_directory(Function(FileSystem::DirectoryEntryView const&)> callback) const { - TRY(callback({ "."sv, { fsid(), 1 }, 0 })); - TRY(callback({ ".."sv, { fsid(), 0 }, 0 })); - TRY(callback({ "self"sv, { fsid(), 2 }, 0 })); + TRY(callback({ "."sv, { fsid(), to_underlying(RAMBackedFileType::Directory) }, 0 })); + TRY(callback({ ".."sv, { fsid(), to_underlying(RAMBackedFileType::Directory) }, 0 })); + TRY(callback({ "self"sv, { fsid(), 2 }, to_underlying(RAMBackedFileType::Link) })); return Process::for_each_in_same_jail([&](Process& process) -> ErrorOr { VERIFY(!(process.pid() < 0)); u64 process_id = (u64)process.pid().value(); InodeIdentifier identifier = { fsid(), static_cast(process_id << 36) }; auto process_id_string = TRY(KString::formatted("{:d}", process_id)); - TRY(callback({ process_id_string->view(), identifier, 0 })); + TRY(callback({ process_id_string->view(), identifier, to_underlying(RAMBackedFileType::Directory) })); return {}; }); } diff --git a/Kernel/FileSystem/ProcFS/ProcessExposed.cpp b/Kernel/FileSystem/ProcFS/ProcessExposed.cpp index 267f5a0708..c1eccd7c64 100644 --- a/Kernel/FileSystem/ProcFS/ProcessExposed.cpp +++ b/Kernel/FileSystem/ProcFS/ProcessExposed.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2023, Liav A. + * Copyright (c) 2021-2024, Liav A. * * SPDX-License-Identifier: BSD-2-Clause */ @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -19,11 +20,11 @@ namespace Kernel { ErrorOr Process::traverse_as_directory(FileSystemID fsid, Function(FileSystem::DirectoryEntryView const&)> callback) const { - TRY(callback({ main_process_directory_root_entry.name, { fsid, ProcFSInode::create_index_from_process_directory_entry(pid(), main_process_directory_root_entry) }, main_process_directory_root_entry.file_type })); - TRY(callback({ ".."sv, { fsid, ProcFSInode::create_index_from_global_directory_entry(global_inode_ids[0]) }, global_inode_ids[0].file_type })); + TRY(callback({ main_process_directory_root_entry.name, { fsid, ProcFSInode::create_index_from_process_directory_entry(pid(), main_process_directory_root_entry) }, to_underlying(main_process_directory_root_entry.file_type) })); + TRY(callback({ ".."sv, { fsid, ProcFSInode::create_index_from_global_directory_entry(global_inode_ids[0]) }, to_underlying(global_inode_ids[0].file_type) })); for (auto& entry : main_process_directory_entries) { - TRY(callback({ entry.name, { fsid, ProcFSInode::create_index_from_process_directory_entry(pid(), entry) }, entry.file_type })); + TRY(callback({ entry.name, { fsid, ProcFSInode::create_index_from_process_directory_entry(pid(), entry) }, to_underlying(entry.file_type) })); } return {}; } @@ -62,16 +63,16 @@ ErrorOr Process::procfs_get_thread_stack(ThreadID thread_id, KBufferBuilde ErrorOr Process::traverse_stacks_directory(FileSystemID fsid, Function(FileSystem::DirectoryEntryView const&)> callback) const { - TRY(callback({ "."sv, { fsid, ProcFSInode::create_index_from_process_directory_entry(pid(), process_stacks_subdirectory_root_entry) }, DT_DIR })); - TRY(callback({ ".."sv, { fsid, ProcFSInode::create_index_from_process_directory_entry(pid(), main_process_directory_root_entry) }, main_process_directory_root_entry.file_type })); + TRY(callback({ "."sv, { fsid, ProcFSInode::create_index_from_process_directory_entry(pid(), process_stacks_subdirectory_root_entry) }, to_underlying(RAMBackedFileType::Directory) })); + TRY(callback({ ".."sv, { fsid, ProcFSInode::create_index_from_process_directory_entry(pid(), main_process_directory_root_entry) }, to_underlying(main_process_directory_root_entry.file_type) })); return thread_list().with([&](auto& list) -> ErrorOr { for (auto const& thread : list) { // NOTE: All property numbers should start from 1 as 0 is reserved for the directory itself. - auto entry = segmented_process_directory_entry { {}, DT_REG, process_stacks_subdirectory_root_entry.subdirectory, static_cast(thread.tid().value() + 1) }; + auto entry = segmented_process_directory_entry { {}, RAMBackedFileType::Regular, process_stacks_subdirectory_root_entry.subdirectory, static_cast(thread.tid().value() + 1) }; InodeIdentifier identifier = { fsid, ProcFSInode::create_index_from_process_directory_entry(pid(), entry) }; auto name = TRY(KString::number(thread.tid().value())); - TRY(callback({ name->view(), identifier, 0 })); + TRY(callback({ name->view(), identifier, to_underlying(RAMBackedFileType::Regular) })); } return {}; }); @@ -90,7 +91,7 @@ ErrorOr> Process::lookup_stacks_directory(ProcFS& procfs, S VERIFY(!(tid < 0)); if (needle == (unsigned)tid) { // NOTE: All property numbers should start from 1 as 0 is reserved for the directory itself. - auto entry = segmented_process_directory_entry { {}, DT_REG, process_stacks_subdirectory_root_entry.subdirectory, static_cast(thread.tid().value() + 1) }; + auto entry = segmented_process_directory_entry { {}, RAMBackedFileType::Regular, process_stacks_subdirectory_root_entry.subdirectory, static_cast(thread.tid().value() + 1) }; thread_stack_inode = procfs.get_inode({ procfs.fsid(), ProcFSInode::create_index_from_process_directory_entry(pid(), entry) }); return IterationDecision::Break; } @@ -104,15 +105,15 @@ ErrorOr> Process::lookup_stacks_directory(ProcFS& procfs, S ErrorOr Process::traverse_children_directory(FileSystemID fsid, Function(FileSystem::DirectoryEntryView const&)> callback) const { - TRY(callback({ "."sv, { fsid, ProcFSInode::create_index_from_process_directory_entry(pid(), process_children_subdirectory_root_entry) }, DT_DIR })); - TRY(callback({ ".."sv, { fsid, ProcFSInode::create_index_from_process_directory_entry(pid(), main_process_directory_root_entry) }, main_process_directory_root_entry.file_type })); + TRY(callback({ "."sv, { fsid, ProcFSInode::create_index_from_process_directory_entry(pid(), process_children_subdirectory_root_entry) }, to_underlying(RAMBackedFileType::Directory) })); + TRY(callback({ ".."sv, { fsid, ProcFSInode::create_index_from_process_directory_entry(pid(), main_process_directory_root_entry) }, to_underlying(main_process_directory_root_entry.file_type) })); return Process::for_each_in_same_jail([&](Process& process) -> ErrorOr { if (process.ppid() == pid()) { auto name = TRY(KString::number(process.pid().value())); // NOTE: All property numbers should start from 1 as 0 is reserved for the directory itself. - auto entry = segmented_process_directory_entry { {}, DT_LNK, process_children_subdirectory_root_entry.subdirectory, static_cast(process.pid().value() + 1) }; + auto entry = segmented_process_directory_entry { {}, RAMBackedFileType::Link, process_children_subdirectory_root_entry.subdirectory, static_cast(process.pid().value() + 1) }; InodeIdentifier identifier = { fsid, ProcFSInode::create_index_from_process_directory_entry(pid(), entry) }; - TRY(callback({ name->view(), identifier, DT_LNK })); + TRY(callback({ name->view(), identifier, to_underlying(RAMBackedFileType::Link) })); } return {}; }); @@ -129,7 +130,7 @@ ErrorOr> Process::lookup_children_directory(ProcFS& procfs, return ENOENT; // NOTE: All property numbers should start from 1 as 0 is reserved for the directory itself. - auto entry = segmented_process_directory_entry { {}, DT_LNK, process_children_subdirectory_root_entry.subdirectory, (maybe_pid.value() + 1) }; + auto entry = segmented_process_directory_entry { {}, RAMBackedFileType::Link, process_children_subdirectory_root_entry.subdirectory, (maybe_pid.value() + 1) }; return procfs.get_inode({ procfs.fsid(), ProcFSInode::create_index_from_process_directory_entry(pid(), entry) }); } @@ -150,8 +151,8 @@ ErrorOr Process::procfs_get_file_description_link(unsigned fd, KBufferBu ErrorOr Process::traverse_file_descriptions_directory(FileSystemID fsid, Function(FileSystem::DirectoryEntryView const&)> callback) const { - TRY(callback({ "."sv, { fsid, ProcFSInode::create_index_from_process_directory_entry(pid(), process_fd_subdirectory_root_entry) }, DT_DIR })); - TRY(callback({ ".."sv, { fsid, ProcFSInode::create_index_from_process_directory_entry(pid(), main_process_directory_root_entry) }, main_process_directory_root_entry.file_type })); + TRY(callback({ "."sv, { fsid, ProcFSInode::create_index_from_process_directory_entry(pid(), process_fd_subdirectory_root_entry) }, to_underlying(RAMBackedFileType::Directory) })); + TRY(callback({ ".."sv, { fsid, ProcFSInode::create_index_from_process_directory_entry(pid(), main_process_directory_root_entry) }, to_underlying(main_process_directory_root_entry.file_type) })); u32 count = 0; TRY(fds().with_shared([&](auto& fds) -> ErrorOr { return fds.try_enumerate([&](auto& file_description_metadata) -> ErrorOr { @@ -161,9 +162,9 @@ ErrorOr Process::traverse_file_descriptions_directory(FileSystemID fsid, F } auto name = TRY(KString::number(count)); // NOTE: All property numbers should start from 1 as 0 is reserved for the directory itself. - auto entry = segmented_process_directory_entry { {}, DT_LNK, process_fd_subdirectory_root_entry.subdirectory, count + 1 }; + auto entry = segmented_process_directory_entry { {}, RAMBackedFileType::Link, process_fd_subdirectory_root_entry.subdirectory, count + 1 }; InodeIdentifier identifier = { fsid, ProcFSInode::create_index_from_process_directory_entry(pid(), entry) }; - TRY(callback({ name->view(), identifier, DT_LNK })); + TRY(callback({ name->view(), identifier, to_underlying(RAMBackedFileType::Link) })); count++; return {}; }); @@ -181,7 +182,7 @@ ErrorOr> Process::lookup_file_descriptions_directory(ProcFS return ENOENT; // NOTE: All property numbers should start from 1 as 0 is reserved for the directory itself. - auto entry = segmented_process_directory_entry { {}, DT_LNK, process_fd_subdirectory_root_entry.subdirectory, (maybe_index.value() + 1) }; + auto entry = segmented_process_directory_entry { {}, RAMBackedFileType::Link, process_fd_subdirectory_root_entry.subdirectory, (maybe_index.value() + 1) }; return procfs.get_inode({ procfs.fsid(), ProcFSInode::create_index_from_process_directory_entry(pid(), entry) }); } diff --git a/Kernel/FileSystem/RAMBackedFileType.h b/Kernel/FileSystem/RAMBackedFileType.h new file mode 100644 index 0000000000..8234c5902d --- /dev/null +++ b/Kernel/FileSystem/RAMBackedFileType.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2024, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include + +namespace Kernel { + +enum class RAMBackedFileType : u8 { + Directory, + Character, + Block, + Regular, + FIFO, + Link, + Socket, + Unknown, +}; + +inline RAMBackedFileType ram_backed_file_type_from_mode(mode_t mode) +{ + switch (mode & S_IFMT) { + case S_IFDIR: + return RAMBackedFileType::Directory; + case S_IFCHR: + return RAMBackedFileType::Character; + case S_IFBLK: + return RAMBackedFileType::Block; + case S_IFREG: + return RAMBackedFileType::Regular; + case S_IFIFO: + return RAMBackedFileType::FIFO; + case S_IFLNK: + return RAMBackedFileType::Link; + case S_IFSOCK: + return RAMBackedFileType::Socket; + default: + return RAMBackedFileType::Unknown; + } +} + +inline u8 ram_backed_file_type_to_directory_entry_type(FileSystem::DirectoryEntryView const& entry) +{ + switch (static_cast(entry.file_type)) { + case RAMBackedFileType::Directory: + return DT_DIR; + case RAMBackedFileType::Character: + return DT_CHR; + case RAMBackedFileType::Block: + return DT_BLK; + case RAMBackedFileType::Regular: + return DT_REG; + case RAMBackedFileType::FIFO: + return DT_FIFO; + case RAMBackedFileType::Link: + return DT_LNK; + case RAMBackedFileType::Socket: + return DT_SOCK; + case RAMBackedFileType::Unknown: + default: + return DT_UNKNOWN; + } +} + +} diff --git a/Kernel/FileSystem/RAMFS/FileSystem.cpp b/Kernel/FileSystem/RAMFS/FileSystem.cpp index 03d79228e4..452648b72a 100644 --- a/Kernel/FileSystem/RAMFS/FileSystem.cpp +++ b/Kernel/FileSystem/RAMFS/FileSystem.cpp @@ -1,10 +1,11 @@ /* * Copyright (c) 2019-2020, Sergey Bugaev - * Copyright (c) 2022-2023, Liav A. + * Copyright (c) 2022-2024, Liav A. * * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include @@ -39,25 +40,7 @@ unsigned RAMFS::next_inode_index() u8 RAMFS::internal_file_type_to_directory_entry_type(DirectoryEntryView const& entry) const { - switch (static_cast(entry.file_type)) { - case FileType::Directory: - return DT_DIR; - case FileType::Character: - return DT_CHR; - case FileType::Block: - return DT_BLK; - case FileType::Regular: - return DT_REG; - case FileType::FIFO: - return DT_FIFO; - case FileType::Link: - return DT_LNK; - case FileType::Socket: - return DT_SOCK; - case FileType::Unknown: - default: - return DT_UNKNOWN; - } + return ram_backed_file_type_to_directory_entry_type(entry); } } diff --git a/Kernel/FileSystem/RAMFS/FileSystem.h b/Kernel/FileSystem/RAMFS/FileSystem.h index 93b57b8038..9033bb7c0c 100644 --- a/Kernel/FileSystem/RAMFS/FileSystem.h +++ b/Kernel/FileSystem/RAMFS/FileSystem.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2019-2020, Sergey Bugaev - * Copyright (c) 2022-2023, Liav A. + * Copyright (c) 2022-2024, Liav A. * * SPDX-License-Identifier: BSD-2-Clause */ @@ -29,17 +29,6 @@ public: virtual u8 internal_file_type_to_directory_entry_type(DirectoryEntryView const& entry) const override; - enum class FileType : u8 { - Directory, - Character, - Block, - Regular, - FIFO, - Link, - Socket, - Unknown, - }; - private: RAMFS(); diff --git a/Kernel/FileSystem/RAMFS/Inode.cpp b/Kernel/FileSystem/RAMFS/Inode.cpp index 184b15ba37..d96bffd4d7 100644 --- a/Kernel/FileSystem/RAMFS/Inode.cpp +++ b/Kernel/FileSystem/RAMFS/Inode.cpp @@ -1,10 +1,11 @@ /* * Copyright (c) 2019-2020, Sergey Bugaev - * Copyright (c) 2022-2023, Liav A. + * Copyright (c) 2022-2024, Liav A. * * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -50,28 +51,6 @@ InodeMetadata RAMFSInode::metadata() const return m_metadata; } -static RAMFS::FileType file_type_from_mode(mode_t mode) -{ - switch (mode & S_IFMT) { - case S_IFDIR: - return RAMFS::FileType::Directory; - case S_IFCHR: - return RAMFS::FileType::Character; - case S_IFBLK: - return RAMFS::FileType::Block; - case S_IFREG: - return RAMFS::FileType::Regular; - case S_IFIFO: - return RAMFS::FileType::FIFO; - case S_IFLNK: - return RAMFS::FileType::Link; - case S_IFSOCK: - return RAMFS::FileType::Socket; - default: - return RAMFS::FileType::Unknown; - } -} - ErrorOr RAMFSInode::traverse_as_directory(Function(FileSystem::DirectoryEntryView const&)> callback) const { MutexLocker locker(m_inode_lock, Mutex::Mode::Shared); @@ -79,15 +58,15 @@ ErrorOr RAMFSInode::traverse_as_directory(Function(FileSyste if (!is_directory()) return ENOTDIR; - TRY(callback({ "."sv, identifier(), to_underlying(RAMFS::FileType::Directory) })); + TRY(callback({ "."sv, identifier(), to_underlying(RAMBackedFileType::Directory) })); if (m_root_directory_inode) { - TRY(callback({ ".."sv, identifier(), to_underlying(RAMFS::FileType::Directory) })); + TRY(callback({ ".."sv, identifier(), to_underlying(RAMBackedFileType::Directory) })); } else if (auto parent = m_parent.strong_ref()) { - TRY(callback({ ".."sv, parent->identifier(), to_underlying(RAMFS::FileType::Directory) })); + TRY(callback({ ".."sv, parent->identifier(), to_underlying(RAMBackedFileType::Directory) })); } for (auto& child : m_children) { - TRY(callback({ child.name->view(), child.inode->identifier(), to_underlying(file_type_from_mode(child.inode->metadata().mode)) })); + TRY(callback({ child.name->view(), child.inode->identifier(), to_underlying(ram_backed_file_type_from_mode(child.inode->metadata().mode)) })); } return {}; } diff --git a/Kernel/FileSystem/SysFS/Component.cpp b/Kernel/FileSystem/SysFS/Component.cpp index e1f6847f40..5df5eb18a3 100644 --- a/Kernel/FileSystem/SysFS/Component.cpp +++ b/Kernel/FileSystem/SysFS/Component.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Liav A. + * Copyright (c) 2021-2024, Liav A. * * SPDX-License-Identifier: BSD-2-Clause */ @@ -107,18 +107,18 @@ SysFSSymbolicLink::SysFSSymbolicLink(SysFSDirectory const& parent_directory, Sys ErrorOr SysFSDirectory::traverse_as_directory(FileSystemID fsid, Function(FileSystem::DirectoryEntryView const&)> callback) const { - TRY(callback({ "."sv, { fsid, component_index() }, 0 })); + TRY(callback({ "."sv, { fsid, component_index() }, to_underlying(RAMBackedFileType::Directory) })); if (is_root_directory()) { - TRY(callback({ ".."sv, { fsid, component_index() }, 0 })); + TRY(callback({ ".."sv, { fsid, component_index() }, to_underlying(RAMBackedFileType::Directory) })); } else { VERIFY(m_parent_directory); - TRY(callback({ ".."sv, { fsid, m_parent_directory->component_index() }, 0 })); + TRY(callback({ ".."sv, { fsid, m_parent_directory->component_index() }, to_underlying(RAMBackedFileType::Directory) })); } return m_child_components.with([&](auto& list) -> ErrorOr { for (auto& child_component : list) { InodeIdentifier identifier = { fsid, child_component.component_index() }; - TRY(callback({ child_component.name(), identifier, 0 })); + TRY(callback({ child_component.name(), identifier, to_underlying(child_component.type()) })); } return {}; }); diff --git a/Kernel/FileSystem/SysFS/Component.h b/Kernel/FileSystem/SysFS/Component.h index 2352420306..c3b0c212f4 100644 --- a/Kernel/FileSystem/SysFS/Component.h +++ b/Kernel/FileSystem/SysFS/Component.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Liav A. + * Copyright (c) 2021-2024, Liav A. * * SPDX-License-Identifier: BSD-2-Clause */ @@ -15,6 +15,7 @@ #include #include #include +#include #include namespace Kernel { @@ -28,6 +29,10 @@ class SysFSComponent : public AtomicRefCounted { friend class SysFSDirectory; public: + // NOTE: It is safe to assume that the regular file type is largely + // the most used file type in the SysFS filesystem. + virtual RAMBackedFileType type() const { return RAMBackedFileType::Regular; } + virtual StringView name() const = 0; virtual ErrorOr read_bytes(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const { return Error::from_errno(ENOTIMPL); } virtual ErrorOr traverse_as_directory(FileSystemID, Function(FileSystem::DirectoryEntryView const&)>) const { VERIFY_NOT_REACHED(); } @@ -61,6 +66,7 @@ private: class SysFSSymbolicLink : public SysFSComponent { public: + virtual RAMBackedFileType type() const override final { return RAMBackedFileType::Link; } virtual ErrorOr read_bytes(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const override final; virtual ErrorOr> to_inode(SysFS const& sysfs_instance) const override final; @@ -75,6 +81,7 @@ protected: class SysFSDirectory : public SysFSComponent { public: + virtual RAMBackedFileType type() const override final { return RAMBackedFileType::Directory; } virtual ErrorOr traverse_as_directory(FileSystemID, Function(FileSystem::DirectoryEntryView const&)>) const override final; virtual RefPtr lookup(StringView name) override final; diff --git a/Kernel/FileSystem/SysFS/FileSystem.cpp b/Kernel/FileSystem/SysFS/FileSystem.cpp index de43a10712..0f01714c76 100644 --- a/Kernel/FileSystem/SysFS/FileSystem.cpp +++ b/Kernel/FileSystem/SysFS/FileSystem.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -25,6 +26,11 @@ ErrorOr SysFS::initialize() return {}; } +u8 SysFS::internal_file_type_to_directory_entry_type(DirectoryEntryView const& entry) const +{ + return ram_backed_file_type_to_directory_entry_type(entry); +} + Inode& SysFS::root_inode() { return *m_root_inode; diff --git a/Kernel/FileSystem/SysFS/FileSystem.h b/Kernel/FileSystem/SysFS/FileSystem.h index fcaf6a8d6b..698249308c 100644 --- a/Kernel/FileSystem/SysFS/FileSystem.h +++ b/Kernel/FileSystem/SysFS/FileSystem.h @@ -28,6 +28,8 @@ public: virtual Inode& root_inode() override; private: + virtual u8 internal_file_type_to_directory_entry_type(DirectoryEntryView const& entry) const override; + SysFS(); RefPtr m_root_inode;