From 8ebec2938cd43d16655404ba86b20c73bfb724a7 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 29 Jan 2022 01:22:28 +0100 Subject: [PATCH] Kernel: Convert process file descriptor table to a SpinlockProtected Instead of manually locking in the various member functions of Process::OpenFileDescriptions, simply wrap it in a SpinlockProtected. --- Kernel/GlobalProcessExposed.cpp | 2 +- Kernel/Process.cpp | 35 ++++----- Kernel/Process.h | 40 +++++++--- Kernel/ProcessSpecificExposed.cpp | 95 ++++++++++++----------- Kernel/Syscalls/anon_create.cpp | 4 +- Kernel/Syscalls/chdir.cpp | 2 +- Kernel/Syscalls/chmod.cpp | 4 +- Kernel/Syscalls/chown.cpp | 4 +- Kernel/Syscalls/dup2.cpp | 18 +++-- Kernel/Syscalls/execve.cpp | 12 +-- Kernel/Syscalls/fcntl.cpp | 14 ++-- Kernel/Syscalls/fork.cpp | 6 +- Kernel/Syscalls/fsync.cpp | 2 +- Kernel/Syscalls/ftruncate.cpp | 2 +- Kernel/Syscalls/get_dir_entries.cpp | 2 +- Kernel/Syscalls/inode_watcher.cpp | 16 ++-- Kernel/Syscalls/ioctl.cpp | 2 +- Kernel/Syscalls/lseek.cpp | 2 +- Kernel/Syscalls/mmap.cpp | 2 +- Kernel/Syscalls/mount.cpp | 2 +- Kernel/Syscalls/open.cpp | 16 ++-- Kernel/Syscalls/pipe.cpp | 20 +++-- Kernel/Syscalls/poll.cpp | 2 +- Kernel/Syscalls/read.cpp | 4 +- Kernel/Syscalls/sendfd.cpp | 10 +-- Kernel/Syscalls/socket.cpp | 115 ++++++++++++++++------------ Kernel/Syscalls/stat.cpp | 4 +- Kernel/Syscalls/statvfs.cpp | 2 +- Kernel/Syscalls/ttyname.cpp | 4 +- Kernel/Syscalls/write.cpp | 4 +- 30 files changed, 257 insertions(+), 190 deletions(-) diff --git a/Kernel/GlobalProcessExposed.cpp b/Kernel/GlobalProcessExposed.cpp index 9f4cd2d32a..800cdeaefb 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().open_count()); + process_object.add("nfds", process.fds().with([](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 7f59b5bd83..2bf8d13fd8 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -139,17 +139,21 @@ 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.try_resize(Process::OpenFileDescriptions::max_open())); + TRY(process->m_fds.with([&](auto& fds) -> ErrorOr { + TRY(fds.try_resize(Process::OpenFileDescriptions::max_open())); - auto& device_to_use_as_tty = tty ? (CharacterDevice&)*tty : DeviceManagement::the().null_device(); - auto description = TRY(device_to_use_as_tty.open(O_RDWR)); - auto setup_description = [&process, &description](int fd) { - process->m_fds.m_fds_metadatas[fd].allocate(); - process->m_fds[fd].set(*description); - }; - setup_description(0); - setup_description(1); - setup_description(2); + auto& device_to_use_as_tty = tty ? (CharacterDevice&)*tty : DeviceManagement::the().null_device(); + auto description = TRY(device_to_use_as_tty.open(O_RDWR)); + auto setup_description = [&](int fd) { + fds.m_fds_metadatas[fd].allocate(); + fds[fd].set(*description); + }; + setup_description(0); + setup_description(1); + setup_description(2); + + return {}; + })); Thread* new_main_thread = nullptr; u32 prev_flags = 0; @@ -387,7 +391,6 @@ RefPtr Process::from_pid(ProcessID pid) const Process::OpenFileDescriptionAndFlags* Process::OpenFileDescriptions::get_if_valid(size_t i) const { - SpinlockLocker lock(m_fds_lock); if (m_fds_metadatas.size() <= i) return nullptr; @@ -398,7 +401,6 @@ const Process::OpenFileDescriptionAndFlags* Process::OpenFileDescriptions::get_i } Process::OpenFileDescriptionAndFlags* Process::OpenFileDescriptions::get_if_valid(size_t i) { - SpinlockLocker lock(m_fds_lock); if (m_fds_metadatas.size() <= i) return nullptr; @@ -410,20 +412,18 @@ Process::OpenFileDescriptionAndFlags* Process::OpenFileDescriptions::get_if_vali const Process::OpenFileDescriptionAndFlags& Process::OpenFileDescriptions::at(size_t i) const { - SpinlockLocker lock(m_fds_lock); VERIFY(m_fds_metadatas[i].is_allocated()); return m_fds_metadatas[i]; } + Process::OpenFileDescriptionAndFlags& Process::OpenFileDescriptions::at(size_t i) { - SpinlockLocker lock(m_fds_lock); VERIFY(m_fds_metadatas[i].is_allocated()); return m_fds_metadatas[i]; } ErrorOr> Process::OpenFileDescriptions::open_file_description(int fd) const { - SpinlockLocker lock(m_fds_lock); if (fd < 0) return EBADF; if (static_cast(fd) >= m_fds_metadatas.size()) @@ -436,7 +436,6 @@ ErrorOr> Process::OpenFileDescriptions::open_ void Process::OpenFileDescriptions::enumerate(Function callback) const { - SpinlockLocker lock(m_fds_lock); for (auto const& file_description_metadata : m_fds_metadatas) { callback(file_description_metadata); } @@ -444,7 +443,6 @@ void Process::OpenFileDescriptions::enumerate(Function callback) { - SpinlockLocker lock(m_fds_lock); for (auto& file_description_metadata : m_fds_metadatas) { callback(file_description_metadata); } @@ -462,7 +460,6 @@ size_t Process::OpenFileDescriptions::open_count() const ErrorOr Process::OpenFileDescriptions::allocate(int first_candidate_fd) { - SpinlockLocker lock(m_fds_lock); for (size_t i = first_candidate_fd; i < max_open(); ++i) { if (!m_fds_metadatas[i].is_allocated()) { m_fds_metadatas[i].allocate(); @@ -592,7 +589,7 @@ void Process::finalize() if (m_alarm_timer) TimerQueue::the().cancel_timer(m_alarm_timer.release_nonnull()); - m_fds.clear(); + m_fds.with([](auto& fds) { fds.clear(); }); m_tty = nullptr; m_executable = nullptr; m_cwd = nullptr; diff --git a/Kernel/Process.h b/Kernel/Process.h index 80a1374aea..f9b85ca785 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -552,8 +552,6 @@ private: void clear_futex_queues_on_exec(); - void setup_socket_fd(int fd, NonnullRefPtr description, int type); - ErrorOr remap_range_as_stack(FlatPtr address, size_t size); public: @@ -633,15 +631,16 @@ public: class ScopedDescriptionAllocation; class OpenFileDescriptions { AK_MAKE_NONCOPYABLE(OpenFileDescriptions); + AK_MAKE_NONMOVABLE(OpenFileDescriptions); friend class Process; public: + OpenFileDescriptions() { } ALWAYS_INLINE const OpenFileDescriptionAndFlags& operator[](size_t i) const { return at(i); } ALWAYS_INLINE OpenFileDescriptionAndFlags& operator[](size_t i) { return at(i); } ErrorOr try_clone(const Kernel::Process::OpenFileDescriptions& other) { - SpinlockLocker lock_other(other.m_fds_lock); TRY(try_resize(other.m_fds_metadatas.size())); for (size_t i = 0; i < other.m_fds_metadatas.size(); ++i) { @@ -671,16 +670,13 @@ public: void clear() { - SpinlockLocker lock(m_fds_lock); m_fds_metadatas.clear(); } ErrorOr> open_file_description(int fd) const; private: - OpenFileDescriptions() = default; static constexpr size_t s_max_open_file_descriptors { FD_SETSIZE }; - mutable Spinlock m_fds_lock; Vector m_fds_metadatas; }; @@ -702,6 +698,15 @@ public: swap(m_description, other.m_description); } + ScopedDescriptionAllocation& operator=(ScopedDescriptionAllocation&& other) + { + if (this != &other) { + m_description = exchange(other.m_description, nullptr); + fd = exchange(other.fd, -1); + } + return *this; + } + ~ScopedDescriptionAllocation() { if (m_description && m_description->is_allocated() && !m_description->is_valid()) { @@ -709,7 +714,7 @@ public: } } - const int fd { -1 }; + int fd { -1 }; private: OpenFileDescriptionAndFlags* m_description { nullptr }; @@ -741,8 +746,23 @@ public: WeakPtr m_process; }; - OpenFileDescriptions& fds() { return m_fds; } - const OpenFileDescriptions& fds() const { return m_fds; } + SpinlockProtected& fds() { return m_fds; } + SpinlockProtected 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); }); + } + + ErrorOr> open_file_description(int fd) const + { + return m_fds.with([fd](auto& fds) { return fds.open_file_description(fd); }); + } + + ErrorOr allocate_fd() + { + return m_fds.with([](auto& fds) { return fds.allocate(); }); + } private: SpinlockProtected& thread_list() { return m_thread_list; } @@ -750,7 +770,7 @@ private: SpinlockProtected m_thread_list; - OpenFileDescriptions m_fds; + SpinlockProtected m_fds; const bool m_is_kernel_process; Atomic m_state { State::Running }; diff --git a/Kernel/ProcessSpecificExposed.cpp b/Kernel/ProcessSpecificExposed.cpp index e6fd94f028..0fe5ac73a7 100644 --- a/Kernel/ProcessSpecificExposed.cpp +++ b/Kernel/ProcessSpecificExposed.cpp @@ -83,7 +83,7 @@ ErrorOr> Process::lookup_stacks_directory(const ProcFS& pro ErrorOr Process::procfs_get_file_description_link(unsigned fd, KBufferBuilder& builder) const { - auto file_description = TRY(m_fds.open_file_description(fd)); + auto file_description = TRY(open_file_description(fd)); // Note: These links are not guaranteed to point to actual VFS paths, just like in other kernels. auto data = TRY(file_description->pseudo_path()); TRY(builder.append(data->view())); @@ -95,16 +95,18 @@ 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().enumerate([&](auto& file_description_metadata) { - if (!file_description_metadata.is_valid()) { + fds().with([&](auto& fds) { + fds.enumerate([&](auto& file_description_metadata) { + if (!file_description_metadata.is_valid()) { + count++; + return; + } + StringBuilder builder; + builder.appendff("{}", count); + // FIXME: Propagate errors from callback. + (void)callback({ builder.string_view(), { fsid, SegmentedProcFSIndex::build_segmented_index_for_file_description(pid(), count) }, DT_LNK }); count++; - return; - } - StringBuilder builder; - builder.appendff("{}", count); - // FIXME: Propagate errors from callback. - (void)callback({ builder.string_view(), { fsid, SegmentedProcFSIndex::build_segmented_index_for_file_description(pid(), count) }, DT_LNK }); - count++; + }); }); return {}; } @@ -115,7 +117,7 @@ ErrorOr> Process::lookup_file_descriptions_directory(const if (!maybe_index.has_value()) return ENOENT; - if (!fds().get_if_valid(*maybe_index)) + if (!fds().with([&](auto& fds) { return fds.get_if_valid(*maybe_index); })) return ENOENT; return TRY(ProcFSProcessPropertyInode::try_create_for_file_description_link(procfs, *maybe_index, pid())); @@ -178,43 +180,46 @@ ErrorOr Process::procfs_get_perf_events(KBufferBuilder& builder) const ErrorOr Process::procfs_get_fds_stats(KBufferBuilder& builder) const { JsonArraySerializer array { builder }; - if (fds().open_count() == 0) { + + return fds().with([&](auto& fds) -> ErrorOr { + if (fds.open_count() == 0) { + array.finish(); + return {}; + } + + size_t count = 0; + fds.enumerate([&](auto& file_description_metadata) { + if (!file_description_metadata.is_valid()) { + count++; + return; + } + bool cloexec = file_description_metadata.flags() & FD_CLOEXEC; + RefPtr description = file_description_metadata.description(); + auto description_object = array.add_object(); + description_object.add("fd", count); + // TODO: Better OOM handling. + auto pseudo_path_or_error = description->pseudo_path(); + description_object.add("absolute_path", pseudo_path_or_error.is_error() ? "???"sv : pseudo_path_or_error.value()->view()); + description_object.add("seekable", description->file().is_seekable()); + description_object.add("class", description->file().class_name()); + description_object.add("offset", description->offset()); + description_object.add("cloexec", cloexec); + description_object.add("blocking", description->is_blocking()); + description_object.add("can_read", description->can_read()); + description_object.add("can_write", description->can_write()); + Inode* inode = description->inode(); + if (inode != nullptr) { + auto inode_object = description_object.add_object("inode"); + inode_object.add("fsid", inode->fsid().value()); + inode_object.add("index", inode->index().value()); + inode_object.finish(); + } + count++; + }); + array.finish(); return {}; - } - - size_t count = 0; - fds().enumerate([&](auto& file_description_metadata) { - if (!file_description_metadata.is_valid()) { - count++; - return; - } - bool cloexec = file_description_metadata.flags() & FD_CLOEXEC; - RefPtr description = file_description_metadata.description(); - auto description_object = array.add_object(); - description_object.add("fd", count); - // TODO: Better OOM handling. - auto pseudo_path_or_error = description->pseudo_path(); - description_object.add("absolute_path", pseudo_path_or_error.is_error() ? "???"sv : pseudo_path_or_error.value()->view()); - description_object.add("seekable", description->file().is_seekable()); - description_object.add("class", description->file().class_name()); - description_object.add("offset", description->offset()); - description_object.add("cloexec", cloexec); - description_object.add("blocking", description->is_blocking()); - description_object.add("can_read", description->can_read()); - description_object.add("can_write", description->can_write()); - Inode* inode = description->inode(); - if (inode != nullptr) { - auto inode_object = description_object.add_object("inode"); - inode_object.add("fsid", inode->fsid().value()); - inode_object.add("index", inode->index().value()); - inode_object.finish(); - } - count++; }); - - array.finish(); - return {}; } ErrorOr Process::procfs_get_virtual_memory_stats(KBufferBuilder& builder) const diff --git a/Kernel/Syscalls/anon_create.cpp b/Kernel/Syscalls/anon_create.cpp index e4f3a93512..02b948df2c 100644 --- a/Kernel/Syscalls/anon_create.cpp +++ b/Kernel/Syscalls/anon_create.cpp @@ -25,7 +25,7 @@ ErrorOr Process::sys$anon_create(size_t size, int options) if (size > NumericLimits::max()) return EINVAL; - auto new_fd = TRY(m_fds.allocate()); + auto new_fd = TRY(allocate_fd()); auto vmobject = TRY(Memory::AnonymousVMObject::try_create_purgeable_with_size(size, AllocationStrategy::Reserve)); auto anon_file = TRY(AnonymousFile::try_create(move(vmobject))); auto description = TRY(OpenFileDescription::try_create(move(anon_file))); @@ -37,7 +37,7 @@ ErrorOr Process::sys$anon_create(size_t size, int options) if (options & O_CLOEXEC) fd_flags |= FD_CLOEXEC; - m_fds[new_fd.fd].set(move(description), fd_flags); + m_fds.with([&](auto& fds) { fds[new_fd.fd].set(move(description), fd_flags); }); return new_fd.fd; } diff --git a/Kernel/Syscalls/chdir.cpp b/Kernel/Syscalls/chdir.cpp index b12829c161..fa64c69487 100644 --- a/Kernel/Syscalls/chdir.cpp +++ b/Kernel/Syscalls/chdir.cpp @@ -23,7 +23,7 @@ ErrorOr Process::sys$fchdir(int fd) { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this); TRY(require_promise(Pledge::stdio)); - auto description = TRY(fds().open_file_description(fd)); + auto description = TRY(open_file_description(fd)); if (!description->is_directory()) return ENOTDIR; if (!description->metadata().may_execute(*this)) diff --git a/Kernel/Syscalls/chmod.cpp b/Kernel/Syscalls/chmod.cpp index 9b79682afd..ac86e262bc 100644 --- a/Kernel/Syscalls/chmod.cpp +++ b/Kernel/Syscalls/chmod.cpp @@ -22,7 +22,7 @@ ErrorOr Process::sys$chmod(Userspace u if (params.dirfd == AT_FDCWD) { base = current_directory(); } else { - auto base_description = TRY(fds().open_file_description(params.dirfd)); + auto base_description = TRY(open_file_description(params.dirfd)); if (!base_description->custody()) return EINVAL; base = base_description->custody(); @@ -36,7 +36,7 @@ ErrorOr Process::sys$fchmod(int fd, mode_t mode) { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this); TRY(require_promise(Pledge::fattr)); - auto description = TRY(fds().open_file_description(fd)); + auto description = TRY(open_file_description(fd)); TRY(description->chmod(mode)); return 0; } diff --git a/Kernel/Syscalls/chown.cpp b/Kernel/Syscalls/chown.cpp index 0db2c9cccc..00b4755567 100644 --- a/Kernel/Syscalls/chown.cpp +++ b/Kernel/Syscalls/chown.cpp @@ -15,7 +15,7 @@ ErrorOr Process::sys$fchown(int fd, UserID uid, GroupID gid) { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this); TRY(require_promise(Pledge::chown)); - auto description = TRY(fds().open_file_description(fd)); + auto description = TRY(open_file_description(fd)); TRY(description->chown(uid, gid)); return 0; } @@ -31,7 +31,7 @@ ErrorOr Process::sys$chown(Userspace u if (params.dirfd == AT_FDCWD) { base = current_directory(); } else { - auto base_description = TRY(fds().open_file_description(params.dirfd)); + auto base_description = TRY(open_file_description(params.dirfd)); if (!base_description->custody()) return EINVAL; base = base_description->custody(); diff --git a/Kernel/Syscalls/dup2.cpp b/Kernel/Syscalls/dup2.cpp index 43c642b517..74273b56f0 100644 --- a/Kernel/Syscalls/dup2.cpp +++ b/Kernel/Syscalls/dup2.cpp @@ -13,15 +13,17 @@ ErrorOr Process::sys$dup2(int old_fd, int new_fd) { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this); TRY(require_promise(Pledge::stdio)); - auto description = TRY(fds().open_file_description(old_fd)); - if (old_fd == new_fd) + return m_fds.with([&](auto& fds) -> ErrorOr { + auto description = TRY(fds.open_file_description(old_fd)); + if (old_fd == new_fd) + return new_fd; + if (new_fd < 0 || static_cast(new_fd) >= OpenFileDescriptions::max_open()) + return EINVAL; + if (!fds.m_fds_metadatas[new_fd].is_allocated()) + fds.m_fds_metadatas[new_fd].allocate(); + fds[new_fd].set(move(description)); return new_fd; - if (new_fd < 0 || static_cast(new_fd) >= OpenFileDescriptions::max_open()) - return EINVAL; - if (!m_fds.m_fds_metadatas[new_fd].is_allocated()) - m_fds.m_fds_metadatas[new_fd].allocate(); - m_fds[new_fd].set(move(description)); - return new_fd; + }); } } diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp index 14c04ee798..c9d765dc80 100644 --- a/Kernel/Syscalls/execve.cpp +++ b/Kernel/Syscalls/execve.cpp @@ -481,7 +481,7 @@ ErrorOr Process::do_exec(NonnullRefPtr main_program_d // (For dynamically linked executable) Allocate an FD for passing the main executable to the dynamic loader. Optional main_program_fd_allocation; if (has_interpreter) - main_program_fd_allocation = TRY(m_fds.allocate()); + main_program_fd_allocation = TRY(allocate_fd()); // We commit to the new executable at this point. There is no turning back! @@ -536,14 +536,16 @@ ErrorOr Process::do_exec(NonnullRefPtr main_program_d clear_futex_queues_on_exec(); - fds().change_each([&](auto& file_description_metadata) { - if (file_description_metadata.is_valid() && file_description_metadata.flags() & FD_CLOEXEC) - file_description_metadata = {}; + m_fds.with([&](auto& fds) { + fds.change_each([&](auto& file_description_metadata) { + if (file_description_metadata.is_valid() && file_description_metadata.flags() & FD_CLOEXEC) + file_description_metadata = {}; + }); }); if (main_program_fd_allocation.has_value()) { main_program_description->set_readable(true); - m_fds[main_program_fd_allocation->fd].set(move(main_program_description), FD_CLOEXEC); + m_fds.with([&](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 c7b83e89a7..0e01c9acd5 100644 --- a/Kernel/Syscalls/fcntl.cpp +++ b/Kernel/Syscalls/fcntl.cpp @@ -15,7 +15,7 @@ ErrorOr Process::sys$fcntl(int fd, int cmd, u32 arg) VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this); TRY(require_promise(Pledge::stdio)); dbgln_if(IO_DEBUG, "sys$fcntl: fd={}, cmd={}, arg={}", fd, cmd, arg); - auto description = TRY(fds().open_file_description(fd)); + auto description = TRY(open_file_description(fd)); // NOTE: The FD flags are not shared between OpenFileDescription objects. // This means that dup() doesn't copy the FD_CLOEXEC flag! switch (cmd) { @@ -23,14 +23,16 @@ ErrorOr Process::sys$fcntl(int fd, int cmd, u32 arg) int arg_fd = (int)arg; if (arg_fd < 0) return EINVAL; - auto fd_allocation = TRY(m_fds.allocate(arg_fd)); - m_fds[fd_allocation.fd].set(*description); - return fd_allocation.fd; + return m_fds.with([&](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[fd].flags(); + return m_fds.with([fd](auto& fds) { return fds[fd].flags(); }); case F_SETFD: - m_fds[fd].set_flags(arg); + m_fds.with([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 711f0d4947..8ae899b168 100644 --- a/Kernel/Syscalls/fork.cpp +++ b/Kernel/Syscalls/fork.cpp @@ -23,7 +23,11 @@ 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.try_clone(m_fds)); + TRY(child->m_fds.with([&](auto& child_fds) { + return m_fds.with([&](auto& parent_fds) { + return child_fds.try_clone(parent_fds); + }); + })); child->m_pg = m_pg; diff --git a/Kernel/Syscalls/fsync.cpp b/Kernel/Syscalls/fsync.cpp index 15fda4ac2e..f726c4cfb6 100644 --- a/Kernel/Syscalls/fsync.cpp +++ b/Kernel/Syscalls/fsync.cpp @@ -12,7 +12,7 @@ ErrorOr Process::sys$fsync(int fd) { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this); TRY(require_promise(Pledge::stdio)); - auto description = TRY(fds().open_file_description(fd)); + auto description = TRY(open_file_description(fd)); TRY(description->sync()); return 0; } diff --git a/Kernel/Syscalls/ftruncate.cpp b/Kernel/Syscalls/ftruncate.cpp index ad32a4ad76..bd8cbd6b5f 100644 --- a/Kernel/Syscalls/ftruncate.cpp +++ b/Kernel/Syscalls/ftruncate.cpp @@ -18,7 +18,7 @@ ErrorOr Process::sys$ftruncate(int fd, Userspace userspac auto length = TRY(copy_typed_from_user(userspace_length)); if (length < 0) return EINVAL; - auto description = TRY(fds().open_file_description(fd)); + auto description = TRY(open_file_description(fd)); if (!description->is_writable()) return EBADF; TRY(description->truncate(static_cast(length))); diff --git a/Kernel/Syscalls/get_dir_entries.cpp b/Kernel/Syscalls/get_dir_entries.cpp index 763326b0f6..47929675ce 100644 --- a/Kernel/Syscalls/get_dir_entries.cpp +++ b/Kernel/Syscalls/get_dir_entries.cpp @@ -15,7 +15,7 @@ ErrorOr Process::sys$get_dir_entries(int fd, Userspace user_buff TRY(require_promise(Pledge::stdio)); if (user_size > NumericLimits::max()) return EINVAL; - auto description = TRY(fds().open_file_description(fd)); + auto description = TRY(open_file_description(fd)); auto buffer = TRY(UserOrKernelBuffer::for_user_buffer(user_buffer, static_cast(user_size))); auto count = TRY(description->get_dir_entries(buffer, user_size)); return count; diff --git a/Kernel/Syscalls/inode_watcher.cpp b/Kernel/Syscalls/inode_watcher.cpp index 6dc8b387bb..2123a44eb0 100644 --- a/Kernel/Syscalls/inode_watcher.cpp +++ b/Kernel/Syscalls/inode_watcher.cpp @@ -18,7 +18,7 @@ ErrorOr Process::sys$create_inode_watcher(u32 flags) VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this) TRY(require_promise(Pledge::rpath)); - auto fd_allocation = TRY(m_fds.allocate()); + auto fd_allocation = TRY(allocate_fd()); auto watcher = TRY(InodeWatcher::try_create()); auto description = TRY(OpenFileDescription::try_create(move(watcher))); @@ -26,12 +26,14 @@ ErrorOr Process::sys$create_inode_watcher(u32 flags) if (flags & static_cast(InodeWatcherFlags::Nonblock)) description->set_blocking(false); - m_fds[fd_allocation.fd].set(move(description)); + return m_fds.with([&](auto& fds) -> ErrorOr { + fds[fd_allocation.fd].set(move(description)); - if (flags & static_cast(InodeWatcherFlags::CloseOnExec)) - m_fds[fd_allocation.fd].set_flags(m_fds[fd_allocation.fd].flags() | FD_CLOEXEC); + if (flags & static_cast(InodeWatcherFlags::CloseOnExec)) + fds[fd_allocation.fd].set_flags(fds[fd_allocation.fd].flags() | FD_CLOEXEC); - return fd_allocation.fd; + return fd_allocation.fd; + }); } ErrorOr Process::sys$inode_watcher_add_watch(Userspace user_params) @@ -40,7 +42,7 @@ ErrorOr Process::sys$inode_watcher_add_watch(Userspaceis_inode_watcher()) return EBADF; auto* inode_watcher = description->inode_watcher(); @@ -55,7 +57,7 @@ ErrorOr Process::sys$inode_watcher_add_watch(Userspace Process::sys$inode_watcher_remove_watch(int fd, int wd) { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this) - auto description = TRY(fds().open_file_description(fd)); + auto description = TRY(open_file_description(fd)); if (!description->is_inode_watcher()) return EBADF; TRY(description->inode_watcher()->unregister_by_wd(wd)); diff --git a/Kernel/Syscalls/ioctl.cpp b/Kernel/Syscalls/ioctl.cpp index 4ba008d42f..9b333c61d9 100644 --- a/Kernel/Syscalls/ioctl.cpp +++ b/Kernel/Syscalls/ioctl.cpp @@ -14,7 +14,7 @@ namespace Kernel { ErrorOr Process::sys$ioctl(int fd, unsigned request, FlatPtr arg) { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this) - auto description = TRY(fds().open_file_description(fd)); + auto description = TRY(open_file_description(fd)); if (request == FIONBIO) { description->set_blocking(TRY(copy_typed_from_user(Userspace(arg))) == 0); return 0; diff --git a/Kernel/Syscalls/lseek.cpp b/Kernel/Syscalls/lseek.cpp index e2ed624f80..2422dce950 100644 --- a/Kernel/Syscalls/lseek.cpp +++ b/Kernel/Syscalls/lseek.cpp @@ -13,7 +13,7 @@ ErrorOr Process::sys$lseek(int fd, Userspace userspace_offset, { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this) TRY(require_promise(Pledge::stdio)); - auto description = TRY(fds().open_file_description(fd)); + auto description = TRY(open_file_description(fd)); off_t offset; TRY(copy_from_user(&offset, userspace_offset)); auto seek_result = TRY(description->seek(offset, whence)); diff --git a/Kernel/Syscalls/mmap.cpp b/Kernel/Syscalls/mmap.cpp index 776c105442..30f1c90e79 100644 --- a/Kernel/Syscalls/mmap.cpp +++ b/Kernel/Syscalls/mmap.cpp @@ -217,7 +217,7 @@ ErrorOr Process::sys$mmap(Userspace use return EINVAL; if (static_cast(offset) & ~PAGE_MASK) return EINVAL; - auto description = TRY(fds().open_file_description(fd)); + auto description = TRY(open_file_description(fd)); if (description->is_directory()) return ENODEV; // Require read access even when read protection is not requested. diff --git a/Kernel/Syscalls/mount.cpp b/Kernel/Syscalls/mount.cpp index 73c1976e3c..c78c3076a8 100644 --- a/Kernel/Syscalls/mount.cpp +++ b/Kernel/Syscalls/mount.cpp @@ -32,7 +32,7 @@ ErrorOr Process::sys$mount(Userspace u auto fs_type_string = TRY(try_copy_kstring_from_user(params.fs_type)); auto fs_type = fs_type_string->view(); - auto description_or_error = fds().open_file_description(source_fd); + auto description_or_error = open_file_description(source_fd); if (!description_or_error.is_error()) dbgln("mount {}: source fd {} @ {}", fs_type, source_fd, target); else diff --git a/Kernel/Syscalls/open.cpp b/Kernel/Syscalls/open.cpp index 26dc679976..567925b317 100644 --- a/Kernel/Syscalls/open.cpp +++ b/Kernel/Syscalls/open.cpp @@ -41,12 +41,12 @@ ErrorOr Process::sys$open(Userspace use dbgln_if(IO_DEBUG, "sys$open(dirfd={}, path='{}', options={}, mode={})", dirfd, path->view(), options, mode); - auto fd_allocation = TRY(m_fds.allocate()); + auto fd_allocation = TRY(allocate_fd()); RefPtr base; if (dirfd == AT_FDCWD) { base = current_directory(); } else { - auto base_description = TRY(fds().open_file_description(dirfd)); + auto base_description = TRY(open_file_description(dirfd)); if (!base_description->is_directory()) return ENOTDIR; if (!base_description->custody()) @@ -59,18 +59,20 @@ ErrorOr Process::sys$open(Userspace use if (description->inode() && description->inode()->socket()) return ENXIO; - u32 fd_flags = (options & O_CLOEXEC) ? FD_CLOEXEC : 0; - m_fds[fd_allocation.fd].set(move(description), fd_flags); - return fd_allocation.fd; + return m_fds.with([&](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; + }); } ErrorOr Process::sys$close(int fd) { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this) TRY(require_promise(Pledge::stdio)); - auto description = TRY(fds().open_file_description(fd)); + auto description = TRY(open_file_description(fd)); auto result = description->close(); - m_fds[fd] = {}; + m_fds.with([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 90cd2ddb49..cde5fd2944 100644 --- a/Kernel/Syscalls/pipe.cpp +++ b/Kernel/Syscalls/pipe.cpp @@ -13,7 +13,8 @@ ErrorOr Process::sys$pipe(int pipefd[2], int flags) { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this) TRY(require_promise(Pledge::stdio)); - if (fds().open_count() + 2 > OpenFileDescriptions::max_open()) + auto open_count = fds().with([](auto& fds) { return fds.open_count(); }); + if (open_count + 2 > OpenFileDescriptions::max_open()) return EMFILE; // Reject flags other than O_CLOEXEC, O_NONBLOCK if ((flags & (O_CLOEXEC | O_NONBLOCK)) != flags) @@ -22,8 +23,14 @@ ErrorOr Process::sys$pipe(int pipefd[2], int flags) u32 fd_flags = (flags & O_CLOEXEC) ? FD_CLOEXEC : 0; auto fifo = TRY(FIFO::try_create(uid())); - auto reader_fd_allocation = TRY(m_fds.allocate()); - auto writer_fd_allocation = TRY(m_fds.allocate()); + ScopedDescriptionAllocation reader_fd_allocation; + ScopedDescriptionAllocation writer_fd_allocation; + + TRY(m_fds.with([&](auto& fds) -> ErrorOr { + reader_fd_allocation = TRY(fds.allocate()); + writer_fd_allocation = TRY(fds.allocate()); + return {}; + })); auto reader_description = TRY(fifo->open_direction(FIFO::Direction::Reader)); auto writer_description = TRY(fifo->open_direction(FIFO::Direction::Writer)); @@ -35,8 +42,11 @@ ErrorOr Process::sys$pipe(int pipefd[2], int flags) writer_description->set_blocking(false); } - m_fds[reader_fd_allocation.fd].set(move(reader_description), fd_flags); - m_fds[writer_fd_allocation.fd].set(move(writer_description), fd_flags); + TRY(m_fds.with([&](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 {}; + })); TRY(copy_to_user(&pipefd[0], &reader_fd_allocation.fd)); TRY(copy_to_user(&pipefd[1], &writer_fd_allocation.fd)); diff --git a/Kernel/Syscalls/poll.cpp b/Kernel/Syscalls/poll.cpp index 3619b7bb10..42cf36e005 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(fds().open_file_description(pfd.fd)); + auto description = TRY(m_fds.with([&](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 21916c7a57..a19106a7f5 100644 --- a/Kernel/Syscalls/read.cpp +++ b/Kernel/Syscalls/read.cpp @@ -12,9 +12,9 @@ namespace Kernel { using BlockFlags = Thread::FileBlocker::BlockFlags; -static ErrorOr> open_readable_file_description(Process::OpenFileDescriptions const& fds, int fd) +static ErrorOr> open_readable_file_description(auto& fds, int fd) { - auto description = TRY(fds.open_file_description(fd)); + auto description = TRY(fds.with([&](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 4c1dd274ee..f0ac59ea6b 100644 --- a/Kernel/Syscalls/sendfd.cpp +++ b/Kernel/Syscalls/sendfd.cpp @@ -14,7 +14,7 @@ ErrorOr Process::sys$sendfd(int sockfd, int fd) { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this) TRY(require_promise(Pledge::sendfd)); - auto socket_description = TRY(fds().open_file_description(sockfd)); + auto socket_description = TRY(open_file_description(sockfd)); if (!socket_description->is_socket()) return ENOTSOCK; auto& socket = *socket_description->socket(); @@ -23,7 +23,7 @@ ErrorOr Process::sys$sendfd(int sockfd, int fd) if (!socket.is_connected()) return ENOTCONN; - auto passing_description = TRY(fds().open_file_description(fd)); + auto passing_description = TRY(open_file_description(fd)); auto& local_socket = static_cast(socket); TRY(local_socket.sendfd(*socket_description, move(passing_description))); return 0; @@ -33,14 +33,14 @@ ErrorOr Process::sys$recvfd(int sockfd, int options) { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this) TRY(require_promise(Pledge::recvfd)); - auto socket_description = TRY(fds().open_file_description(sockfd)); + auto socket_description = TRY(open_file_description(sockfd)); if (!socket_description->is_socket()) return ENOTSOCK; auto& socket = *socket_description->socket(); if (!socket.is_local()) return EAFNOSUPPORT; - auto fd_allocation = TRY(m_fds.allocate()); + auto fd_allocation = TRY(m_fds.with([](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[fd_allocation.fd].set(move(received_description), fd_flags); + m_fds.with([&](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 bca00d5209..8ea4f61fc5 100644 --- a/Kernel/Syscalls/socket.cpp +++ b/Kernel/Syscalls/socket.cpp @@ -19,7 +19,7 @@ namespace Kernel { TRY(require_promise(Pledge::unix)); \ } while (0) -void Process::setup_socket_fd(int fd, NonnullRefPtr description, int type) +static void setup_socket_fd(Process::OpenFileDescriptions& fds, int fd, NonnullRefPtr description, int type) { description->set_readable(true); description->set_writable(true); @@ -28,7 +28,7 @@ void Process::setup_socket_fd(int fd, NonnullRefPtr descrip flags |= FD_CLOEXEC; if (type & SOCK_NONBLOCK) description->set_blocking(false); - m_fds[fd].set(*description, flags); + fds[fd].set(*description, flags); } ErrorOr Process::sys$socket(int domain, int type, int protocol) @@ -38,23 +38,28 @@ ErrorOr Process::sys$socket(int domain, int type, int protocol) if ((type & SOCK_TYPE_MASK) == SOCK_RAW && !is_superuser()) return EACCES; - auto fd_allocation = TRY(m_fds.allocate()); - auto socket = TRY(Socket::create(domain, type, protocol)); - auto description = TRY(OpenFileDescription::try_create(socket)); - setup_socket_fd(fd_allocation.fd, move(description), type); - return fd_allocation.fd; + + return m_fds.with([&](auto& fds) -> ErrorOr { + auto fd_allocation = TRY(fds.allocate()); + auto socket = TRY(Socket::create(domain, type, protocol)); + auto description = TRY(OpenFileDescription::try_create(socket)); + setup_socket_fd(fds, fd_allocation.fd, move(description), type); + return fd_allocation.fd; + }); } ErrorOr Process::sys$bind(int sockfd, Userspace address, socklen_t address_length) { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this) - auto description = TRY(fds().open_file_description(sockfd)); - if (!description->is_socket()) - return ENOTSOCK; - auto& socket = *description->socket(); - REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain()); - TRY(socket.bind(address, address_length)); - return 0; + return m_fds.with([&](auto& fds) -> ErrorOr { + auto description = TRY(fds.open_file_description(sockfd)); + if (!description->is_socket()) + return ENOTSOCK; + auto& socket = *description->socket(); + REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain()); + TRY(socket.bind(address, address_length)); + return 0; + }); } ErrorOr Process::sys$listen(int sockfd, int backlog) @@ -62,15 +67,17 @@ ErrorOr Process::sys$listen(int sockfd, int backlog) VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this) if (backlog < 0) return EINVAL; - auto description = TRY(fds().open_file_description(sockfd)); - if (!description->is_socket()) - return ENOTSOCK; - auto& socket = *description->socket(); - REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain()); - if (socket.is_connected()) - return EINVAL; - TRY(socket.listen(backlog)); - return 0; + return m_fds.with([&](auto& fds) -> ErrorOr { + auto description = TRY(fds.open_file_description(sockfd)); + if (!description->is_socket()) + return ENOTSOCK; + auto& socket = *description->socket(); + REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain()); + if (socket.is_connected()) + return EINVAL; + TRY(socket.listen(backlog)); + return 0; + }); } ErrorOr Process::sys$accept4(Userspace user_params) @@ -89,8 +96,14 @@ ErrorOr Process::sys$accept4(Userspace(user_address_size))); } - auto fd_allocation = TRY(m_fds.allocate()); - auto accepting_socket_description = TRY(fds().open_file_description(accepting_socket_fd)); + ScopedDescriptionAllocation fd_allocation; + RefPtr accepting_socket_description; + + TRY(m_fds.with([&](auto& fds) -> ErrorOr { + fd_allocation = TRY(fds.allocate()); + accepting_socket_description = TRY(fds.open_file_description(accepting_socket_fd)); + return {}; + })); if (!accepting_socket_description->is_socket()) return ENOTSOCK; auto& socket = *accepting_socket_description->socket(); @@ -124,7 +137,11 @@ ErrorOr Process::sys$accept4(Userspace ErrorOr { + fds[fd_allocation.fd].set(move(accepted_socket_description), fd_flags); + return {}; + })); // NOTE: Moving this state to Completed is what causes connect() to unblock on the client side. accepted_socket->set_setup_state(Socket::SetupState::Completed); @@ -134,7 +151,8 @@ ErrorOr Process::sys$accept4(Userspace Process::sys$connect(int sockfd, Userspace user_address, socklen_t user_address_size) { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this) - auto description = TRY(fds().open_file_description(sockfd)); + + auto description = TRY(open_file_description(sockfd)); if (!description->is_socket()) return ENOTSOCK; auto& socket = *description->socket(); @@ -149,7 +167,7 @@ ErrorOr Process::sys$shutdown(int sockfd, int how) TRY(require_promise(Pledge::stdio)); if (how & ~SHUT_RDWR) return EINVAL; - auto description = TRY(fds().open_file_description(sockfd)); + auto description = TRY(open_file_description(sockfd)); if (!description->is_socket()) return ENOTSOCK; auto& socket = *description->socket(); @@ -175,7 +193,7 @@ ErrorOr Process::sys$sendmsg(int sockfd, Userspace user_addr((FlatPtr)msg.msg_name); socklen_t addr_length = msg.msg_namelen; - auto description = TRY(fds().open_file_description(sockfd)); + auto description = TRY(open_file_description(sockfd)); if (!description->is_socket()) return ENOTSOCK; auto& socket = *description->socket(); @@ -203,7 +221,7 @@ ErrorOr Process::sys$recvmsg(int sockfd, Userspace user Userspace user_addr((FlatPtr)msg.msg_name); Userspace user_addr_length(msg.msg_name ? (FlatPtr)&user_msg.unsafe_userspace_ptr()->msg_namelen : 0); - auto description = TRY(fds().open_file_description(sockfd)); + auto description = TRY(open_file_description(sockfd)); if (!description->is_socket()) return ENOTSOCK; auto& socket = *description->socket(); @@ -259,7 +277,7 @@ ErrorOr Process::get_sock_or_peer_name(const Params& params) if (addrlen_value <= 0) return EINVAL; - auto description = TRY(fds().open_file_description(params.sockfd)); + auto description = TRY(open_file_description(params.sockfd)); if (!description->is_socket()) return ENOTSOCK; @@ -306,7 +324,7 @@ ErrorOr Process::sys$getsockopt(Userspaceis_socket()) return ENOTSOCK; auto& socket = *description->socket(); @@ -321,7 +339,7 @@ ErrorOr Process::sys$setsockopt(Userspace user_value((FlatPtr)params.value); - auto description = TRY(fds().open_file_description(params.sockfd)); + auto description = TRY(open_file_description(params.sockfd)); if (!description->is_socket()) return ENOTSOCK; auto& socket = *description->socket(); @@ -343,21 +361,24 @@ ErrorOr Process::sys$socketpair(Userspace ErrorOr { + auto fd_allocation0 = TRY(fds.allocate()); + auto fd_allocation1 = TRY(fds.allocate()); - int fds[2]; - fds[0] = fd_allocation0.fd; - fds[1] = fd_allocation1.fd; - setup_socket_fd(fds[0], pair.description0, params.type); - setup_socket_fd(fds[1], pair.description1, params.type); + int allocated_fds[2]; + allocated_fds[0] = fd_allocation0.fd; + allocated_fds[1] = fd_allocation1.fd; + setup_socket_fd(fds, allocated_fds[0], pair.description0, params.type); + setup_socket_fd(fds, allocated_fds[1], pair.description1, params.type); - if (copy_to_user(params.sv, fds, sizeof(fds)).is_error()) { - // Avoid leaking both file descriptors on error. - m_fds[fds[0]] = {}; - m_fds[fds[1]] = {}; - return EFAULT; - } - return 0; + if (copy_to_user(params.sv, allocated_fds, sizeof(allocated_fds)).is_error()) { + // Avoid leaking both file descriptors on error. + fds[allocated_fds[0]] = {}; + fds[allocated_fds[1]] = {}; + return EFAULT; + } + return 0; + }); } + } diff --git a/Kernel/Syscalls/stat.cpp b/Kernel/Syscalls/stat.cpp index eb027ada40..8b7a18cc9d 100644 --- a/Kernel/Syscalls/stat.cpp +++ b/Kernel/Syscalls/stat.cpp @@ -15,7 +15,7 @@ ErrorOr Process::sys$fstat(int fd, Userspace user_statbuf) { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this) TRY(require_promise(Pledge::stdio)); - auto description = TRY(fds().open_file_description(fd)); + auto description = TRY(open_file_description(fd)); auto buffer = TRY(description->stat()); TRY(copy_to_user(user_statbuf, &buffer)); return 0; @@ -33,7 +33,7 @@ ErrorOr Process::sys$stat(Userspace use if (params.dirfd == AT_FDCWD) { base = current_directory(); } else { - auto base_description = TRY(fds().open_file_description(params.dirfd)); + auto base_description = TRY(open_file_description(params.dirfd)); if (!base_description->is_directory()) return ENOTDIR; if (!base_description->custody()) diff --git a/Kernel/Syscalls/statvfs.cpp b/Kernel/Syscalls/statvfs.cpp index b78145c367..82b38d336d 100644 --- a/Kernel/Syscalls/statvfs.cpp +++ b/Kernel/Syscalls/statvfs.cpp @@ -57,7 +57,7 @@ ErrorOr Process::sys$fstatvfs(int fd, statvfs* buf) VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this) TRY(require_promise(Pledge::stdio)); - auto description = TRY(fds().open_file_description(fd)); + auto description = TRY(open_file_description(fd)); auto const* inode = description->inode(); if (inode == nullptr) return ENOENT; diff --git a/Kernel/Syscalls/ttyname.cpp b/Kernel/Syscalls/ttyname.cpp index b1f04a3c02..ec95137dea 100644 --- a/Kernel/Syscalls/ttyname.cpp +++ b/Kernel/Syscalls/ttyname.cpp @@ -15,7 +15,7 @@ ErrorOr Process::sys$ttyname(int fd, Userspace buffer, size_t si { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this) TRY(require_promise(Pledge::tty)); - auto description = TRY(fds().open_file_description(fd)); + auto description = TRY(open_file_description(fd)); if (!description->is_tty()) return ENOTTY; auto const& tty_name = description->tty()->tty_name(); @@ -29,7 +29,7 @@ ErrorOr Process::sys$ptsname(int fd, Userspace buffer, size_t si { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this) TRY(require_promise(Pledge::tty)); - auto description = TRY(fds().open_file_description(fd)); + auto description = TRY(open_file_description(fd)); auto* master_pty = description->master_pty(); if (!master_pty) return ENOTTY; diff --git a/Kernel/Syscalls/write.cpp b/Kernel/Syscalls/write.cpp index 0cbc764a41..bc7903cf69 100644 --- a/Kernel/Syscalls/write.cpp +++ b/Kernel/Syscalls/write.cpp @@ -32,7 +32,7 @@ ErrorOr Process::sys$writev(int fd, Userspace iov, return EINVAL; } - auto description = TRY(fds().open_file_description(fd)); + auto description = TRY(open_file_description(fd)); if (!description->is_writable()) return EBADF; @@ -97,7 +97,7 @@ ErrorOr Process::sys$write(int fd, Userspace data, size_t si return EINVAL; dbgln_if(IO_DEBUG, "sys$write({}, {}, {})", fd, data.ptr(), size); - auto description = TRY(fds().open_file_description(fd)); + auto description = TRY(open_file_description(fd)); if (!description->is_writable()) return EBADF;