Quellcode durchsuchen

Kernel: Put Process's current directory in a SpinlockProtected

Also let's call it "current_directory" instead of "cwd" everywhere.
Andreas Kling vor 3 Jahren
Ursprung
Commit
24f02bd421
5 geänderte Dateien mit 25 neuen und 19 gelöschten Zeilen
  1. 10 9
      Kernel/Process.cpp
  2. 5 4
      Kernel/Process.h
  3. 1 1
      Kernel/ProcessSpecificExposed.cpp
  4. 8 4
      Kernel/Syscalls/chdir.cpp
  5. 1 1
      Kernel/Syscalls/fork.cpp

+ 10 - 9
Kernel/Process.cpp

@@ -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 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));
     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_is_kernel_process(is_kernel_process)
     , m_executable(move(executable))
-    , m_cwd(move(cwd))
+    , m_current_directory(move(current_directory))
     , m_tty(tty)
     , m_unveiled_paths(move(unveil_tree))
     , m_wait_blocker_set(*this)
@@ -528,11 +528,13 @@ siginfo_t Process::wait_info() const
     return siginfo;
 }
 
-Custody& Process::current_directory()
+NonnullRefPtr<Custody> Process::current_directory()
 {
-    if (!m_cwd)
-        m_cwd = VirtualFileSystem::the().root_custody();
-    return *m_cwd;
+    return m_current_directory.with([&](auto& current_directory) -> NonnullRefPtr<Custody> {
+        if (!current_directory)
+            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)
@@ -629,7 +631,6 @@ void Process::finalize()
     m_fds.with_exclusive([](auto& fds) { fds.clear(); });
     m_tty = nullptr;
     m_executable = nullptr;
-    m_cwd = nullptr;
     m_arguments.clear();
     m_environment.clear();
 

+ 5 - 4
Kernel/Process.h

@@ -432,7 +432,7 @@ public:
     u32 m_ticks_in_user_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(); }
     const Custody* executable() const { return m_executable.ptr(); }
 
@@ -525,8 +525,8 @@ private:
     bool add_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);
-    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);
+    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> 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);
     static ProcessID allocate_pid();
 
@@ -788,7 +788,8 @@ private:
     bool m_should_generate_coredump { false };
 
     RefPtr<Custody> m_executable;
-    RefPtr<Custody> m_cwd;
+
+    SpinlockProtected<RefPtr<Custody>> m_current_directory;
 
     NonnullOwnPtrVector<KString> m_arguments;
     NonnullOwnPtrVector<KString> m_environment;

+ 1 - 1
Kernel/ProcessSpecificExposed.cpp

@@ -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
 {
-    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

+ 8 - 4
Kernel/Syscalls/chdir.cpp

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

+ 1 - 1
Kernel/Syscalls/fork.cpp

@@ -19,7 +19,7 @@ ErrorOr<FlatPtr> Process::sys$fork(RegisterState& regs)
     TRY(require_promise(Pledge::proc));
     RefPtr<Thread> child_first_thread;
     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_unveiled_paths = TRY(m_unveiled_paths.deep_copy());