1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-30 23:58:12 +00:00

Kernel: Put Process's current directory in a SpinlockProtected

Also let's call it "current_directory" instead of "cwd" everywhere.
This commit is contained in:
Andreas Kling 2022-03-07 17:56:25 +01:00
parent 71792e4b3f
commit 24f02bd421
5 changed files with 25 additions and 19 deletions

View file

@ -215,20 +215,20 @@ void Process::unprotect_data()
}); });
} }
ErrorOr<NonnullRefPtr<Process>> Process::try_create(RefPtr<Thread>& first_thread, NonnullOwnPtr<KString> name, UserID uid, GroupID gid, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> cwd, RefPtr<Custody> executable, TTY* tty, Process* fork_parent) ErrorOr<NonnullRefPtr<Process>> Process::try_create(RefPtr<Thread>& first_thread, NonnullOwnPtr<KString> name, UserID uid, GroupID gid, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> current_directory, RefPtr<Custody> executable, TTY* tty, Process* fork_parent)
{ {
auto space = TRY(Memory::AddressSpace::try_create(fork_parent ? &fork_parent->address_space() : nullptr)); auto space = TRY(Memory::AddressSpace::try_create(fork_parent ? &fork_parent->address_space() : nullptr));
auto unveil_tree = UnveilNode { TRY(KString::try_create("/"sv)), UnveilMetadata(TRY(KString::try_create("/"sv))) }; auto unveil_tree = UnveilNode { TRY(KString::try_create("/"sv)), UnveilMetadata(TRY(KString::try_create("/"sv))) };
auto process = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) Process(move(name), uid, gid, ppid, is_kernel_process, move(cwd), move(executable), tty, move(unveil_tree)))); auto process = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) Process(move(name), uid, gid, ppid, is_kernel_process, move(current_directory), move(executable), tty, move(unveil_tree))));
TRY(process->attach_resources(move(space), first_thread, fork_parent)); TRY(process->attach_resources(move(space), first_thread, fork_parent));
return process; return process;
} }
Process::Process(NonnullOwnPtr<KString> name, UserID uid, GroupID gid, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> cwd, RefPtr<Custody> executable, TTY* tty, UnveilNode unveil_tree) Process::Process(NonnullOwnPtr<KString> name, UserID uid, GroupID gid, ProcessID ppid, bool is_kernel_process, NonnullRefPtr<Custody> current_directory, RefPtr<Custody> executable, TTY* tty, UnveilNode unveil_tree)
: m_name(move(name)) : m_name(move(name))
, m_is_kernel_process(is_kernel_process) , m_is_kernel_process(is_kernel_process)
, m_executable(move(executable)) , m_executable(move(executable))
, m_cwd(move(cwd)) , m_current_directory(move(current_directory))
, m_tty(tty) , m_tty(tty)
, m_unveiled_paths(move(unveil_tree)) , m_unveiled_paths(move(unveil_tree))
, m_wait_blocker_set(*this) , m_wait_blocker_set(*this)
@ -528,11 +528,13 @@ siginfo_t Process::wait_info() const
return siginfo; return siginfo;
} }
Custody& Process::current_directory() NonnullRefPtr<Custody> Process::current_directory()
{ {
if (!m_cwd) return m_current_directory.with([&](auto& current_directory) -> NonnullRefPtr<Custody> {
m_cwd = VirtualFileSystem::the().root_custody(); if (!current_directory)
return *m_cwd; current_directory = VirtualFileSystem::the().root_custody();
return *current_directory;
});
} }
ErrorOr<NonnullOwnPtr<KString>> Process::get_syscall_path_argument(Userspace<char const*> user_path, size_t path_length) ErrorOr<NonnullOwnPtr<KString>> Process::get_syscall_path_argument(Userspace<char const*> user_path, size_t path_length)
@ -629,7 +631,6 @@ void Process::finalize()
m_fds.with_exclusive([](auto& fds) { fds.clear(); }); m_fds.with_exclusive([](auto& fds) { fds.clear(); });
m_tty = nullptr; m_tty = nullptr;
m_executable = nullptr; m_executable = nullptr;
m_cwd = nullptr;
m_arguments.clear(); m_arguments.clear();
m_environment.clear(); m_environment.clear();

View file

@ -432,7 +432,7 @@ public:
u32 m_ticks_in_user_for_dead_children { 0 }; u32 m_ticks_in_user_for_dead_children { 0 };
u32 m_ticks_in_kernel_for_dead_children { 0 }; u32 m_ticks_in_kernel_for_dead_children { 0 };
Custody& current_directory(); NonnullRefPtr<Custody> current_directory();
Custody* executable() { return m_executable.ptr(); } Custody* executable() { return m_executable.ptr(); }
const Custody* executable() const { return m_executable.ptr(); } const Custody* executable() const { return m_executable.ptr(); }
@ -525,8 +525,8 @@ private:
bool add_thread(Thread&); bool add_thread(Thread&);
bool remove_thread(Thread&); bool remove_thread(Thread&);
Process(NonnullOwnPtr<KString> name, UserID, GroupID, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> cwd, RefPtr<Custody> executable, TTY* tty, UnveilNode unveil_tree); Process(NonnullOwnPtr<KString> name, UserID, GroupID, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> current_directory, RefPtr<Custody> executable, TTY* tty, UnveilNode unveil_tree);
static ErrorOr<NonnullRefPtr<Process>> try_create(RefPtr<Thread>& first_thread, NonnullOwnPtr<KString> name, UserID, GroupID, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> cwd = nullptr, RefPtr<Custody> executable = nullptr, TTY* = nullptr, Process* fork_parent = nullptr); static ErrorOr<NonnullRefPtr<Process>> try_create(RefPtr<Thread>& first_thread, NonnullOwnPtr<KString> name, UserID, GroupID, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> current_directory = nullptr, RefPtr<Custody> executable = nullptr, TTY* = nullptr, Process* fork_parent = nullptr);
ErrorOr<void> attach_resources(NonnullOwnPtr<Memory::AddressSpace>&&, RefPtr<Thread>& first_thread, Process* fork_parent); ErrorOr<void> attach_resources(NonnullOwnPtr<Memory::AddressSpace>&&, RefPtr<Thread>& first_thread, Process* fork_parent);
static ProcessID allocate_pid(); static ProcessID allocate_pid();
@ -788,7 +788,8 @@ private:
bool m_should_generate_coredump { false }; bool m_should_generate_coredump { false };
RefPtr<Custody> m_executable; RefPtr<Custody> m_executable;
RefPtr<Custody> m_cwd;
SpinlockProtected<RefPtr<Custody>> m_current_directory;
NonnullOwnPtrVector<KString> m_arguments; NonnullOwnPtrVector<KString> m_arguments;
NonnullOwnPtrVector<KString> m_environment; NonnullOwnPtrVector<KString> m_environment;

View file

@ -274,7 +274,7 @@ ErrorOr<void> Process::procfs_get_virtual_memory_stats(KBufferBuilder& builder)
ErrorOr<void> Process::procfs_get_current_work_directory_link(KBufferBuilder& builder) const ErrorOr<void> Process::procfs_get_current_work_directory_link(KBufferBuilder& builder) const
{ {
return builder.append(TRY(const_cast<Process&>(*this).current_directory().try_serialize_absolute_path())->view()); return builder.append(TRY(const_cast<Process&>(*this).current_directory()->try_serialize_absolute_path())->view());
} }
mode_t Process::binary_link_required_mode() const mode_t Process::binary_link_required_mode() const

View file

@ -15,8 +15,10 @@ ErrorOr<FlatPtr> Process::sys$chdir(Userspace<const char*> user_path, size_t pat
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this); VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
TRY(require_promise(Pledge::rpath)); TRY(require_promise(Pledge::rpath));
auto path = TRY(get_syscall_path_argument(user_path, path_length)); auto path = TRY(get_syscall_path_argument(user_path, path_length));
m_cwd = TRY(VirtualFileSystem::the().open_directory(path->view(), current_directory())); return m_current_directory.with([&](auto& current_directory) -> ErrorOr<FlatPtr> {
return 0; current_directory = TRY(VirtualFileSystem::the().open_directory(path->view(), *current_directory));
return 0;
});
} }
ErrorOr<FlatPtr> Process::sys$fchdir(int fd) ErrorOr<FlatPtr> Process::sys$fchdir(int fd)
@ -28,7 +30,9 @@ ErrorOr<FlatPtr> Process::sys$fchdir(int fd)
return ENOTDIR; return ENOTDIR;
if (!description->metadata().may_execute(*this)) if (!description->metadata().may_execute(*this))
return EACCES; return EACCES;
m_cwd = description->custody(); m_current_directory.with([&](auto& current_directory) {
current_directory = description->custody();
});
return 0; return 0;
} }
@ -40,7 +44,7 @@ ErrorOr<FlatPtr> Process::sys$getcwd(Userspace<char*> buffer, size_t size)
if (size > NumericLimits<ssize_t>::max()) if (size > NumericLimits<ssize_t>::max())
return EINVAL; return EINVAL;
auto path = TRY(current_directory().try_serialize_absolute_path()); auto path = TRY(current_directory()->try_serialize_absolute_path());
size_t ideal_size = path->length() + 1; size_t ideal_size = path->length() + 1;
auto size_to_copy = min(ideal_size, size); auto size_to_copy = min(ideal_size, size);
TRY(copy_to_user(buffer, path->characters(), size_to_copy)); TRY(copy_to_user(buffer, path->characters(), size_to_copy));

View file

@ -19,7 +19,7 @@ ErrorOr<FlatPtr> Process::sys$fork(RegisterState& regs)
TRY(require_promise(Pledge::proc)); TRY(require_promise(Pledge::proc));
RefPtr<Thread> child_first_thread; RefPtr<Thread> child_first_thread;
auto child_name = TRY(m_name->try_clone()); auto child_name = TRY(m_name->try_clone());
auto child = TRY(Process::try_create(child_first_thread, move(child_name), uid(), gid(), pid(), m_is_kernel_process, m_cwd, m_executable, m_tty, this)); auto child = TRY(Process::try_create(child_first_thread, move(child_name), uid(), gid(), pid(), m_is_kernel_process, current_directory(), m_executable, m_tty, this));
child->m_veil_state = m_veil_state; child->m_veil_state = m_veil_state;
child->m_unveiled_paths = TRY(m_unveiled_paths.deep_copy()); child->m_unveiled_paths = TRY(m_unveiled_paths.deep_copy());