diff --git a/Kernel/GlobalProcessExposed.cpp b/Kernel/GlobalProcessExposed.cpp index 800cdeaefb..8038387354 100644 --- a/Kernel/GlobalProcessExposed.cpp +++ b/Kernel/GlobalProcessExposed.cpp @@ -490,7 +490,7 @@ private: process_object.add("uid", process.uid().value()); process_object.add("gid", process.gid().value()); process_object.add("ppid", process.ppid().value()); - process_object.add("nfds", process.fds().with([](auto& fds) { return fds.open_count(); })); + process_object.add("nfds", process.fds().with_shared([](auto& fds) { return fds.open_count(); })); process_object.add("name", process.name()); process_object.add("executable", process.executable() ? TRY(process.executable()->try_serialize_absolute_path())->view() : ""sv); process_object.add("tty", process.tty() ? process.tty()->tty_name().view() : "notty"sv); diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 2bf8d13fd8..ccebd03bf9 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -139,7 +139,7 @@ ErrorOr> Process::try_create_user_process(RefPtr& auto name = TRY(KString::try_create(parts.last())); auto process = TRY(Process::try_create(first_thread, move(name), uid, gid, ProcessID(0), false, VirtualFileSystem::the().root_custody(), nullptr, tty)); - TRY(process->m_fds.with([&](auto& fds) -> ErrorOr { + TRY(process->m_fds.with_exclusive([&](auto& fds) -> ErrorOr { TRY(fds.try_resize(Process::OpenFileDescriptions::max_open())); auto& device_to_use_as_tty = tty ? (CharacterDevice&)*tty : DeviceManagement::the().null_device(); @@ -589,7 +589,7 @@ void Process::finalize() if (m_alarm_timer) TimerQueue::the().cancel_timer(m_alarm_timer.release_nonnull()); - m_fds.with([](auto& fds) { fds.clear(); }); + m_fds.with_exclusive([](auto& fds) { fds.clear(); }); m_tty = nullptr; m_executable = nullptr; m_cwd = nullptr; diff --git a/Kernel/Process.h b/Kernel/Process.h index f9b85ca785..f774857404 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -746,22 +746,22 @@ public: WeakPtr m_process; }; - SpinlockProtected& fds() { return m_fds; } - SpinlockProtected const& fds() const { return m_fds; } + MutexProtected& fds() { return m_fds; } + MutexProtected const& fds() const { return m_fds; } ErrorOr> open_file_description(int fd) { - return m_fds.with([fd](auto& fds) { return fds.open_file_description(fd); }); + return m_fds.with_shared([fd](auto& fds) { return fds.open_file_description(fd); }); } ErrorOr> open_file_description(int fd) const { - return m_fds.with([fd](auto& fds) { return fds.open_file_description(fd); }); + return m_fds.with_shared([fd](auto& fds) { return fds.open_file_description(fd); }); } ErrorOr allocate_fd() { - return m_fds.with([](auto& fds) { return fds.allocate(); }); + return m_fds.with_exclusive([](auto& fds) { return fds.allocate(); }); } private: @@ -770,7 +770,7 @@ private: SpinlockProtected m_thread_list; - SpinlockProtected m_fds; + MutexProtected m_fds; const bool m_is_kernel_process; Atomic m_state { State::Running }; diff --git a/Kernel/ProcessSpecificExposed.cpp b/Kernel/ProcessSpecificExposed.cpp index 0fe5ac73a7..5d2169ee40 100644 --- a/Kernel/ProcessSpecificExposed.cpp +++ b/Kernel/ProcessSpecificExposed.cpp @@ -95,7 +95,7 @@ ErrorOr Process::traverse_file_descriptions_directory(FileSystemID fsid, F TRY(callback({ ".", { fsid, m_procfs_traits->component_index() }, 0 })); TRY(callback({ "..", { fsid, m_procfs_traits->component_index() }, 0 })); size_t count = 0; - fds().with([&](auto& fds) { + fds().with_shared([&](auto& fds) { fds.enumerate([&](auto& file_description_metadata) { if (!file_description_metadata.is_valid()) { count++; @@ -117,7 +117,7 @@ ErrorOr> Process::lookup_file_descriptions_directory(const if (!maybe_index.has_value()) return ENOENT; - if (!fds().with([&](auto& fds) { return fds.get_if_valid(*maybe_index); })) + if (!m_fds.with_shared([&](auto& fds) { return fds.get_if_valid(*maybe_index); })) return ENOENT; return TRY(ProcFSProcessPropertyInode::try_create_for_file_description_link(procfs, *maybe_index, pid())); @@ -181,7 +181,7 @@ ErrorOr Process::procfs_get_fds_stats(KBufferBuilder& builder) const { JsonArraySerializer array { builder }; - return fds().with([&](auto& fds) -> ErrorOr { + return fds().with_shared([&](auto& fds) -> ErrorOr { if (fds.open_count() == 0) { array.finish(); return {}; diff --git a/Kernel/Syscalls/anon_create.cpp b/Kernel/Syscalls/anon_create.cpp index 02b948df2c..0b3fb06c70 100644 --- a/Kernel/Syscalls/anon_create.cpp +++ b/Kernel/Syscalls/anon_create.cpp @@ -37,7 +37,7 @@ ErrorOr Process::sys$anon_create(size_t size, int options) if (options & O_CLOEXEC) fd_flags |= FD_CLOEXEC; - m_fds.with([&](auto& fds) { fds[new_fd.fd].set(move(description), fd_flags); }); + m_fds.with_exclusive([&](auto& fds) { fds[new_fd.fd].set(move(description), fd_flags); }); return new_fd.fd; } diff --git a/Kernel/Syscalls/dup2.cpp b/Kernel/Syscalls/dup2.cpp index 74273b56f0..9ddf754934 100644 --- a/Kernel/Syscalls/dup2.cpp +++ b/Kernel/Syscalls/dup2.cpp @@ -13,7 +13,7 @@ ErrorOr Process::sys$dup2(int old_fd, int new_fd) { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this); TRY(require_promise(Pledge::stdio)); - return m_fds.with([&](auto& fds) -> ErrorOr { + return m_fds.with_exclusive([&](auto& fds) -> ErrorOr { auto description = TRY(fds.open_file_description(old_fd)); if (old_fd == new_fd) return new_fd; diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp index c9d765dc80..b47a9fb65b 100644 --- a/Kernel/Syscalls/execve.cpp +++ b/Kernel/Syscalls/execve.cpp @@ -536,7 +536,7 @@ ErrorOr Process::do_exec(NonnullRefPtr main_program_d clear_futex_queues_on_exec(); - m_fds.with([&](auto& fds) { + m_fds.with_exclusive([&](auto& fds) { fds.change_each([&](auto& file_description_metadata) { if (file_description_metadata.is_valid() && file_description_metadata.flags() & FD_CLOEXEC) file_description_metadata = {}; @@ -545,7 +545,7 @@ ErrorOr Process::do_exec(NonnullRefPtr main_program_d if (main_program_fd_allocation.has_value()) { main_program_description->set_readable(true); - m_fds.with([&](auto& fds) { fds[main_program_fd_allocation->fd].set(move(main_program_description), FD_CLOEXEC); }); + m_fds.with_exclusive([&](auto& fds) { fds[main_program_fd_allocation->fd].set(move(main_program_description), FD_CLOEXEC); }); } new_main_thread = nullptr; diff --git a/Kernel/Syscalls/fcntl.cpp b/Kernel/Syscalls/fcntl.cpp index 0e01c9acd5..7a9e039dff 100644 --- a/Kernel/Syscalls/fcntl.cpp +++ b/Kernel/Syscalls/fcntl.cpp @@ -23,16 +23,16 @@ ErrorOr Process::sys$fcntl(int fd, int cmd, u32 arg) int arg_fd = (int)arg; if (arg_fd < 0) return EINVAL; - return m_fds.with([&](auto& fds) -> ErrorOr { + return m_fds.with_exclusive([&](auto& fds) -> ErrorOr { auto fd_allocation = TRY(fds.allocate(arg_fd)); fds[fd_allocation.fd].set(*description); return fd_allocation.fd; }); } case F_GETFD: - return m_fds.with([fd](auto& fds) { return fds[fd].flags(); }); + return m_fds.with_exclusive([fd](auto& fds) { return fds[fd].flags(); }); case F_SETFD: - m_fds.with([fd, arg](auto& fds) { fds[fd].set_flags(arg); }); + m_fds.with_exclusive([fd, arg](auto& fds) { fds[fd].set_flags(arg); }); break; case F_GETFL: return description->file_flags(); diff --git a/Kernel/Syscalls/fork.cpp b/Kernel/Syscalls/fork.cpp index 8ae899b168..7593db7e49 100644 --- a/Kernel/Syscalls/fork.cpp +++ b/Kernel/Syscalls/fork.cpp @@ -23,8 +23,8 @@ ErrorOr Process::sys$fork(RegisterState& regs) child->m_veil_state = m_veil_state; child->m_unveiled_paths = m_unveiled_paths.deep_copy(); - TRY(child->m_fds.with([&](auto& child_fds) { - return m_fds.with([&](auto& parent_fds) { + TRY(child->m_fds.with_exclusive([&](auto& child_fds) { + return m_fds.with_exclusive([&](auto& parent_fds) { return child_fds.try_clone(parent_fds); }); })); diff --git a/Kernel/Syscalls/inode_watcher.cpp b/Kernel/Syscalls/inode_watcher.cpp index 2123a44eb0..2f7e574828 100644 --- a/Kernel/Syscalls/inode_watcher.cpp +++ b/Kernel/Syscalls/inode_watcher.cpp @@ -26,7 +26,7 @@ ErrorOr Process::sys$create_inode_watcher(u32 flags) if (flags & static_cast(InodeWatcherFlags::Nonblock)) description->set_blocking(false); - return m_fds.with([&](auto& fds) -> ErrorOr { + return m_fds.with_exclusive([&](auto& fds) -> ErrorOr { fds[fd_allocation.fd].set(move(description)); if (flags & static_cast(InodeWatcherFlags::CloseOnExec)) diff --git a/Kernel/Syscalls/open.cpp b/Kernel/Syscalls/open.cpp index 567925b317..8943ad8086 100644 --- a/Kernel/Syscalls/open.cpp +++ b/Kernel/Syscalls/open.cpp @@ -59,7 +59,7 @@ ErrorOr Process::sys$open(Userspace use if (description->inode() && description->inode()->socket()) return ENXIO; - return m_fds.with([&](auto& fds) -> ErrorOr { + return m_fds.with_exclusive([&](auto& fds) -> ErrorOr { u32 fd_flags = (options & O_CLOEXEC) ? FD_CLOEXEC : 0; fds[fd_allocation.fd].set(move(description), fd_flags); return fd_allocation.fd; @@ -72,7 +72,7 @@ ErrorOr Process::sys$close(int fd) TRY(require_promise(Pledge::stdio)); auto description = TRY(open_file_description(fd)); auto result = description->close(); - m_fds.with([fd](auto& fds) { fds[fd] = {}; }); + m_fds.with_exclusive([fd](auto& fds) { fds[fd] = {}; }); if (result.is_error()) return result.release_error(); return 0; diff --git a/Kernel/Syscalls/pipe.cpp b/Kernel/Syscalls/pipe.cpp index cde5fd2944..50f497555a 100644 --- a/Kernel/Syscalls/pipe.cpp +++ b/Kernel/Syscalls/pipe.cpp @@ -13,7 +13,7 @@ ErrorOr Process::sys$pipe(int pipefd[2], int flags) { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this) TRY(require_promise(Pledge::stdio)); - auto open_count = fds().with([](auto& fds) { return fds.open_count(); }); + auto open_count = fds().with_shared([](auto& fds) { return fds.open_count(); }); if (open_count + 2 > OpenFileDescriptions::max_open()) return EMFILE; // Reject flags other than O_CLOEXEC, O_NONBLOCK @@ -26,7 +26,7 @@ ErrorOr Process::sys$pipe(int pipefd[2], int flags) ScopedDescriptionAllocation reader_fd_allocation; ScopedDescriptionAllocation writer_fd_allocation; - TRY(m_fds.with([&](auto& fds) -> ErrorOr { + TRY(m_fds.with_exclusive([&](auto& fds) -> ErrorOr { reader_fd_allocation = TRY(fds.allocate()); writer_fd_allocation = TRY(fds.allocate()); return {}; @@ -42,7 +42,7 @@ ErrorOr Process::sys$pipe(int pipefd[2], int flags) writer_description->set_blocking(false); } - TRY(m_fds.with([&](auto& fds) -> ErrorOr { + TRY(m_fds.with_exclusive([&](auto& fds) -> ErrorOr { fds[reader_fd_allocation.fd].set(move(reader_description), fd_flags); fds[writer_fd_allocation.fd].set(move(writer_description), fd_flags); return {}; diff --git a/Kernel/Syscalls/poll.cpp b/Kernel/Syscalls/poll.cpp index 42cf36e005..a783b72f4d 100644 --- a/Kernel/Syscalls/poll.cpp +++ b/Kernel/Syscalls/poll.cpp @@ -49,7 +49,7 @@ ErrorOr Process::sys$poll(Userspace use for (size_t i = 0; i < params.nfds; i++) { auto& pfd = fds_copy[i]; - auto description = TRY(m_fds.with([&](auto& fds) { return fds.open_file_description(pfd.fd); })); + auto description = TRY(m_fds.with_shared([&](auto& fds) { return fds.open_file_description(pfd.fd); })); BlockFlags block_flags = BlockFlags::Exception; // always want POLLERR, POLLHUP, POLLNVAL if (pfd.events & POLLIN) block_flags |= BlockFlags::Read; diff --git a/Kernel/Syscalls/read.cpp b/Kernel/Syscalls/read.cpp index a19106a7f5..935daf1206 100644 --- a/Kernel/Syscalls/read.cpp +++ b/Kernel/Syscalls/read.cpp @@ -14,7 +14,7 @@ using BlockFlags = Thread::FileBlocker::BlockFlags; static ErrorOr> open_readable_file_description(auto& fds, int fd) { - auto description = TRY(fds.with([&](auto& fds) { return fds.open_file_description(fd); })); + auto description = TRY(fds.with_shared([&](auto& fds) { return fds.open_file_description(fd); })); if (!description->is_readable()) return EBADF; if (description->is_directory()) diff --git a/Kernel/Syscalls/sendfd.cpp b/Kernel/Syscalls/sendfd.cpp index f0ac59ea6b..4ab52dece9 100644 --- a/Kernel/Syscalls/sendfd.cpp +++ b/Kernel/Syscalls/sendfd.cpp @@ -40,7 +40,7 @@ ErrorOr Process::sys$recvfd(int sockfd, int options) if (!socket.is_local()) return EAFNOSUPPORT; - auto fd_allocation = TRY(m_fds.with([](auto& fds) { return fds.allocate(); })); + auto fd_allocation = TRY(m_fds.with_exclusive([](auto& fds) { return fds.allocate(); })); auto& local_socket = static_cast(socket); auto received_description = TRY(local_socket.recvfd(*socket_description)); @@ -49,7 +49,7 @@ ErrorOr Process::sys$recvfd(int sockfd, int options) if (options & O_CLOEXEC) fd_flags |= FD_CLOEXEC; - m_fds.with([&](auto& fds) { fds[fd_allocation.fd].set(move(received_description), fd_flags); }); + m_fds.with_exclusive([&](auto& fds) { fds[fd_allocation.fd].set(move(received_description), fd_flags); }); return fd_allocation.fd; } diff --git a/Kernel/Syscalls/socket.cpp b/Kernel/Syscalls/socket.cpp index 8ea4f61fc5..a8f15e02ab 100644 --- a/Kernel/Syscalls/socket.cpp +++ b/Kernel/Syscalls/socket.cpp @@ -39,7 +39,7 @@ ErrorOr Process::sys$socket(int domain, int type, int protocol) if ((type & SOCK_TYPE_MASK) == SOCK_RAW && !is_superuser()) return EACCES; - return m_fds.with([&](auto& fds) -> ErrorOr { + return m_fds.with_exclusive([&](auto& fds) -> ErrorOr { auto fd_allocation = TRY(fds.allocate()); auto socket = TRY(Socket::create(domain, type, protocol)); auto description = TRY(OpenFileDescription::try_create(socket)); @@ -51,7 +51,7 @@ ErrorOr Process::sys$socket(int domain, int type, int protocol) ErrorOr Process::sys$bind(int sockfd, Userspace address, socklen_t address_length) { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this) - return m_fds.with([&](auto& fds) -> ErrorOr { + return m_fds.with_exclusive([&](auto& fds) -> ErrorOr { auto description = TRY(fds.open_file_description(sockfd)); if (!description->is_socket()) return ENOTSOCK; @@ -67,7 +67,7 @@ ErrorOr Process::sys$listen(int sockfd, int backlog) VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this) if (backlog < 0) return EINVAL; - return m_fds.with([&](auto& fds) -> ErrorOr { + return m_fds.with_exclusive([&](auto& fds) -> ErrorOr { auto description = TRY(fds.open_file_description(sockfd)); if (!description->is_socket()) return ENOTSOCK; @@ -99,7 +99,7 @@ ErrorOr Process::sys$accept4(Userspace accepting_socket_description; - TRY(m_fds.with([&](auto& fds) -> ErrorOr { + TRY(m_fds.with_exclusive([&](auto& fds) -> ErrorOr { fd_allocation = TRY(fds.allocate()); accepting_socket_description = TRY(fds.open_file_description(accepting_socket_fd)); return {}; @@ -138,7 +138,7 @@ ErrorOr Process::sys$accept4(Userspace ErrorOr { + TRY(m_fds.with_exclusive([&](auto& fds) -> ErrorOr { fds[fd_allocation.fd].set(move(accepted_socket_description), fd_flags); return {}; })); @@ -361,7 +361,7 @@ ErrorOr Process::sys$socketpair(Userspace ErrorOr { + return m_fds.with_exclusive([&](auto& fds) -> ErrorOr { auto fd_allocation0 = TRY(fds.allocate()); auto fd_allocation1 = TRY(fds.allocate());