mirror of
https://github.com/SerenityOS/serenity
synced 2026-05-10 17:12:55 +02:00
111 lines
4.0 KiB
C++
111 lines
4.0 KiB
C++
/*
|
|
* Copyright (c) 2024, Liav A. <liavalb@hotmail.co.il>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/IntrusiveList.h>
|
|
#include <AK/Noncopyable.h>
|
|
#include <AK/RefPtr.h>
|
|
#include <AK/SetOnce.h>
|
|
#include <Kernel/FileSystem/Custody.h>
|
|
#include <Kernel/FileSystem/FileBackedFileSystem.h>
|
|
#include <Kernel/FileSystem/FileSystem.h>
|
|
#include <Kernel/FileSystem/Mount.h>
|
|
#include <Kernel/Forward.h>
|
|
#include <Kernel/Locking/SpinlockProtected.h>
|
|
|
|
namespace Kernel {
|
|
|
|
class VFSRootContext : public AtomicRefCounted<VFSRootContext> {
|
|
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<NonnullRefPtr<VFSRootContext>> create_with_empty_ramfs();
|
|
static ErrorOr<NonnullRefPtr<VFSRootContext>> create_empty();
|
|
|
|
SpinlockProtected<NonnullRefPtr<Custody>, LockRank::None>& root_custody() { return m_root_custody; }
|
|
SpinlockProtected<NonnullRefPtr<Custody>, LockRank::None> const& root_custody() const { return m_root_custody; }
|
|
|
|
enum class DoBindMount {
|
|
Yes,
|
|
No,
|
|
};
|
|
ErrorOr<void> add_new_mount(DoBindMount, Inode& source, Custody& mount_point, int flags);
|
|
|
|
ErrorOr<void> do_full_teardown(Badge<PowerStateSwitchTask>);
|
|
|
|
ErrorOr<void> unmount(FileBackedFileSystem::List& file_backed_file_systems_list, Inode& guest_inode, StringView custody_path);
|
|
ErrorOr<void> pivot_root(FileBackedFileSystem::List& file_backed_file_systems_list, FileSystem& fs, NonnullOwnPtr<Mount> new_mount, NonnullRefPtr<Custody> root_mount_point, int root_mount_flags);
|
|
|
|
ErrorOr<void> apply_to_mount_for_host_custody(Custody const& current_custody, Function<void(Mount&)>);
|
|
|
|
struct CurrentMountState {
|
|
Mount::Details details;
|
|
int flags { 0 };
|
|
};
|
|
ErrorOr<CurrentMountState> current_mount_state_for_host_custody(Custody const& current_custody) const;
|
|
|
|
IndexID id() const { return m_id; }
|
|
|
|
void attach(Badge<Process>);
|
|
void detach(Badge<Process>);
|
|
|
|
ErrorOr<void> for_each_mount(Function<ErrorOr<void>(Mount const&)>) const;
|
|
|
|
private:
|
|
VFSRootContext(NonnullRefPtr<Custody> custody);
|
|
|
|
enum class ValidateImmutableFlag {
|
|
Yes,
|
|
No,
|
|
};
|
|
ErrorOr<void> do_on_mount_for_host_custody(ValidateImmutableFlag validate_immutable_flag, Custody const& current_custody, Function<void(Mount&)> callback) const;
|
|
|
|
static void add_to_mounts_list_and_increment_fs_mounted_count(DoBindMount do_bind_mount, IntrusiveList<&Mount::m_vfs_list_node>&, NonnullOwnPtr<Mount>);
|
|
|
|
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<void> 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<Details, LockRank::None> m_details {};
|
|
|
|
SpinlockProtected<NonnullRefPtr<Custody>, LockRank::None> m_root_custody;
|
|
|
|
IntrusiveListNode<VFSRootContext, NonnullRefPtr<VFSRootContext>> m_list_node;
|
|
|
|
IndexID m_id;
|
|
|
|
// NOTE: This method is implemented in Kernel/FileSystem/VirtualFileSystem.cpp
|
|
static SpinlockProtected<IntrusiveList<&VFSRootContext::m_list_node>, 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<VFSRootContext::List, LockRank::FileSystem>& all_root_contexts_list(Badge<PowerStateSwitchTask>);
|
|
static SpinlockProtected<VFSRootContext::List, LockRank::FileSystem>& all_root_contexts_list(Badge<Process>);
|
|
};
|
|
|
|
}
|