/* * Copyright (c) 2024, Liav A. * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include #include #include namespace Kernel { class VFSRootContext : public AtomicRefCounted { AK_MAKE_NONCOPYABLE(VFSRootContext); AK_MAKE_NONMOVABLE(VFSRootContext); public: AK_TYPEDEF_DISTINCT_ORDERED_ID(u64, IndexID); static VFSRootContext const& empty_context_for_kernel_processes(); static Custody const& empty_context_custody_for_kernel_processes(); static void initialize_empty_ramfs_root_context_for_kernel_processes(); static ErrorOr> create_with_empty_ramfs(); static ErrorOr> create_empty(); SpinlockProtected, LockRank::None>& root_custody() { return m_root_custody; } SpinlockProtected, LockRank::None> const& root_custody() const { return m_root_custody; } enum class DoBindMount { Yes, No, }; ErrorOr add_new_mount(DoBindMount, Inode& source, Custody& mount_point, int flags); ErrorOr do_full_teardown(Badge); ErrorOr unmount(FileBackedFileSystem::List& file_backed_file_systems_list, Inode& guest_inode, StringView custody_path); ErrorOr pivot_root(FileBackedFileSystem::List& file_backed_file_systems_list, FileSystem& fs, NonnullOwnPtr new_mount, NonnullRefPtr root_mount_point, int root_mount_flags); ErrorOr apply_to_mount_for_host_custody(Custody const& current_custody, Function); struct CurrentMountState { Mount::Details details; int flags { 0 }; }; ErrorOr current_mount_state_for_host_custody(Custody const& current_custody) const; IndexID id() const { return m_id; } void attach(Badge); void detach(Badge); ErrorOr for_each_mount(Function(Mount const&)>) const; private: VFSRootContext(NonnullRefPtr custody); enum class ValidateImmutableFlag { Yes, No, }; ErrorOr do_on_mount_for_host_custody(ValidateImmutableFlag validate_immutable_flag, Custody const& current_custody, Function callback) const; static void add_to_mounts_list_and_increment_fs_mounted_count(DoBindMount do_bind_mount, IntrusiveList<&Mount::m_vfs_list_node>&, NonnullOwnPtr); struct Details { SetOnce attached_by_process; size_t attach_count { 0 }; IntrusiveList<&Mount::m_vfs_list_node> mounts; }; bool mount_point_exists_at_custody(Custody& mount_point, Details& details); static inline ErrorOr validate_mount_not_immutable_while_being_used(Details& details, Mount& mount) { if (mount.is_immutable() && details.attach_count > 0) return Error::from_errno(EPERM); return {}; } mutable SpinlockProtected m_details {}; SpinlockProtected, LockRank::None> m_root_custody; IntrusiveListNode> m_list_node; IndexID m_id; // NOTE: This method is implemented in Kernel/FileSystem/VirtualFileSystem.cpp static SpinlockProtected, LockRank::FileSystem>& all_root_contexts_list(); public: using List = IntrusiveList<&VFSRootContext::m_list_node>; // NOTE: These methods are implemented in Kernel/FileSystem/VirtualFileSystem.cpp static SpinlockProtected& all_root_contexts_list(Badge); static SpinlockProtected& all_root_contexts_list(Badge); }; }