diff options
author | Liav A <liavalb@gmail.com> | 2021-06-22 21:22:17 +0300 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-06-29 20:53:59 +0200 |
commit | 7c87891c06e37f217b5fde17a3fc869306da659b (patch) | |
tree | 3017e40cfb6fbbd01e1f0b36b483003d498c189c /Kernel | |
parent | 12b6e6915034a0c0d1981caf419a35c0a8cd247e (diff) | |
download | serenity-7c87891c06e37f217b5fde17a3fc869306da659b.zip |
Kernel: Don't copy a Vector<FileDescriptionAndFlags>
Instead of copying a Vector everytime we need to enumerate a Process'
file descriptions, we can just temporarily lock so it won't change.
Diffstat (limited to 'Kernel')
28 files changed, 198 insertions, 128 deletions
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 1ea0850b53..b6de160f0d 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -159,7 +159,7 @@ RefPtr<Process> Process::create_user_process(RefPtr<Thread>& first_thread, const auto process = Process::create(first_thread, parts.take_last(), uid, gid, parent_pid, false, move(cwd), nullptr, tty); if (!first_thread) return {}; - if (!process->m_fds.try_resize(m_max_open_file_descriptors)) { + if (!process->m_fds.try_resize(process->m_fds.max_open())) { first_thread = nullptr; return {}; } @@ -393,42 +393,68 @@ RefPtr<Process> Process::from_pid(ProcessID pid) return {}; } -RefPtr<FileDescription> Process::file_description(int fd) const +const Process::FileDescriptionAndFlags& Process::FileDescriptions::at(size_t i) const +{ + ScopedSpinLock lock(m_fds_lock); + return m_fds_metadatas[i]; +} +Process::FileDescriptionAndFlags& Process::FileDescriptions::at(size_t i) +{ + ScopedSpinLock lock(m_fds_lock); + return m_fds_metadatas[i]; +} + +RefPtr<FileDescription> Process::FileDescriptions::file_description(int fd) const { ScopedSpinLock lock(m_fds_lock); if (fd < 0) return nullptr; - if (static_cast<size_t>(fd) < m_fds.size()) - return m_fds[fd].description(); + if (static_cast<size_t>(fd) < m_fds_metadatas.size()) + return m_fds_metadatas[fd].description(); return nullptr; } -int Process::fd_flags(int fd) const +int Process::FileDescriptions::fd_flags(int fd) const { ScopedSpinLock lock(m_fds_lock); if (fd < 0) return -1; - if (static_cast<size_t>(fd) < m_fds.size()) - return m_fds[fd].flags(); + if (static_cast<size_t>(fd) < m_fds_metadatas.size()) + return m_fds_metadatas[fd].flags(); return -1; } -int Process::number_of_open_file_descriptors() const +void Process::FileDescriptions::enumerate(Function<void(const FileDescriptionAndFlags&)> callback) const { ScopedSpinLock lock(m_fds_lock); - int count = 0; - for (size_t index = 0; index < m_fds.size(); index++) { - if (m_fds[index].is_valid()) - ++count; + for (auto& file_description_metadata : m_fds_metadatas) { + callback(file_description_metadata); + } +} + +void Process::FileDescriptions::change_each(Function<void(FileDescriptionAndFlags&)> callback) +{ + ScopedSpinLock lock(m_fds_lock); + for (auto& file_description_metadata : m_fds_metadatas) { + callback(file_description_metadata); } +} + +size_t Process::FileDescriptions::open_count() const +{ + size_t count = 0; + enumerate([&](auto& file_description_metadata) { + if (file_description_metadata.is_valid()) + ++count; + }); return count; } -int Process::alloc_fd(int first_candidate_fd) +int Process::FileDescriptions::allocate(int first_candidate_fd) { ScopedSpinLock lock(m_fds_lock); - for (int i = first_candidate_fd; i < (int)m_max_open_file_descriptors; ++i) { - if (!m_fds[i]) + for (size_t i = first_candidate_fd; i < max_open(); ++i) { + if (!m_fds_metadatas[i]) return i; } return -EMFILE; diff --git a/Kernel/Process.h b/Kernel/Process.h index 5b1bc7bd65..69220fe7fe 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -228,9 +228,6 @@ public: bool in_group(gid_t) const; - RefPtr<FileDescription> file_description(int fd) const; - int fd_flags(int fd) const; - // Breakable iteration functions template<IteratorFunction<Process&> Callback> static void for_each(Callback); @@ -443,12 +440,6 @@ public: const Vector<String>& arguments() const { return m_arguments; }; const Vector<String>& environment() const { return m_environment; }; - int number_of_open_file_descriptors() const; - int max_open_file_descriptors() const - { - return m_max_open_file_descriptors; - } - KResult exec(String path, Vector<String> arguments, Vector<String> environment, int recusion_depth = 0); KResultOr<LoadResult> load(NonnullRefPtr<FileDescription> main_program_description, RefPtr<FileDescription> interpreter_description, const ElfW(Ehdr) & main_program_header); @@ -541,8 +532,6 @@ private: KResultOr<RefPtr<FileDescription>> find_elf_interpreter_for_executable(const String& path, const ElfW(Ehdr) & elf_header, int nread, size_t file_size); - int alloc_fd(int first_candidate_fd = 0); - KResult do_kill(Process&, int signal); KResult do_killpg(ProcessGroupID pgrp, int signal); KResult do_killall(int signal); @@ -586,8 +575,6 @@ private: OwnPtr<ThreadTracer> m_tracer; - static constexpr int m_max_open_file_descriptors { FD_SETSIZE }; - public: class FileDescriptionAndFlags { friend class FileDescriptionRegistrar; @@ -616,14 +603,62 @@ public: InodeIndex m_global_procfs_inode_index; }; - // FIXME: We create a copy when trying to iterate the Vector because - // we don't want to put lots of locking when accessing this Vector. - // Maybe try to encapsulate the Vector inside a protective class with locking - // mechanism. - Vector<FileDescriptionAndFlags> fds() const { return m_fds; } + class FileDescriptions { + friend class Process; + + public: + ALWAYS_INLINE const FileDescriptionAndFlags& operator[](size_t i) const { return at(i); } + ALWAYS_INLINE FileDescriptionAndFlags& operator[](size_t i) { return at(i); } + + FileDescriptions& operator=(const Kernel::Process::FileDescriptions& other) + { + ScopedSpinLock lock(m_fds_lock); + ScopedSpinLock lock_other(other.m_fds_lock); + m_fds_metadatas = other.m_fds_metadatas; + for (auto& file_description_metadata : m_fds_metadatas) { + file_description_metadata.refresh_inode_index(); + } + return *this; + } + + const FileDescriptionAndFlags& at(size_t i) const; + FileDescriptionAndFlags& at(size_t i); + + void enumerate(Function<void(const FileDescriptionAndFlags&)>) const; + void change_each(Function<void(FileDescriptionAndFlags&)>); + + int allocate(int first_candidate_fd = 0); + size_t open_count() const; + + bool try_resize(size_t size) { return m_fds_metadatas.try_resize(size); } + + size_t max_open() const + { + return m_max_open_file_descriptors; + } + + void clear() + { + ScopedSpinLock lock(m_fds_lock); + m_fds_metadatas.clear(); + } + + // FIXME: Consider to remove this somehow + RefPtr<FileDescription> file_description(int fd) const; + int fd_flags(int fd) const; + + private: + FileDescriptions() = default; + static constexpr size_t m_max_open_file_descriptors { FD_SETSIZE }; + mutable SpinLock<u8> m_fds_lock; + Vector<FileDescriptionAndFlags> m_fds_metadatas; + }; + + FileDescriptions& fds() { return m_fds; } + const FileDescriptions& fds() const { return m_fds; } private: - Vector<FileDescriptionAndFlags> m_fds; + FileDescriptions m_fds; mutable RecursiveSpinLock m_thread_list_lock; @@ -659,7 +694,6 @@ private: FutexQueues m_futex_queues; SpinLock<u8> m_futex_lock; - mutable SpinLock<u8> m_fds_lock; // This member is used in the implementation of ptrace's PT_TRACEME flag. // If it is set to true, the process will stop at the next execve syscall diff --git a/Kernel/ProcessExposed.cpp b/Kernel/ProcessExposed.cpp index e9f81aa91e..54ba651d24 100644 --- a/Kernel/ProcessExposed.cpp +++ b/Kernel/ProcessExposed.cpp @@ -454,7 +454,7 @@ private: process_object.add("uid", process.uid()); process_object.add("gid", process.gid()); process_object.add("ppid", process.ppid().value()); - process_object.add("nfds", process.number_of_open_file_descriptors()); + process_object.add("nfds", process.fds().open_count()); process_object.add("name", process.name()); process_object.add("executable", process.executable() ? process.executable()->absolute_path() : ""); process_object.add("tty", process.tty() ? process.tty()->tty_name() : "notty"); @@ -1239,7 +1239,7 @@ private: KResultOr<size_t> ProcFSProcessFileDescriptions::entries_count() const { Locker locker(m_lock); - return m_process_folder->m_associated_process->number_of_open_file_descriptors(); + return m_process_folder->m_associated_process->fds().open_count(); } KResult ProcFSProcessFileDescriptions::traverse_as_directory(unsigned fsid, Function<bool(const FS::DirectoryEntryView&)> callback) const { @@ -1248,29 +1248,36 @@ KResult ProcFSProcessFileDescriptions::traverse_as_directory(unsigned fsid, Func callback({ "..", { fsid, m_parent_folder->component_index() }, 0 }); auto process = m_process_folder->m_associated_process; - for (int i = 0; i < process->max_open_file_descriptors(); ++i) { - auto description_metadata = process->fds()[i]; - if (!description_metadata.is_valid()) - continue; - InodeIdentifier identifier = { fsid, description_metadata.global_procfs_inode_index() }; - callback({ String::number(i), identifier, 0 }); - } + size_t count = 0; + m_process_folder->m_associated_process->fds().enumerate([&](auto& file_description_metadata) { + if (!file_description_metadata.is_valid()) { + count++; + return; + } + InodeIdentifier identifier = { fsid, file_description_metadata.global_procfs_inode_index() }; + callback({ String::number(count), identifier, 0 }); + count++; + }); return KSuccess; } RefPtr<ProcFSExposedComponent> ProcFSProcessFileDescriptions::lookup(StringView name) { Locker locker(m_lock); auto process = m_process_folder->m_associated_process; - ScopedSpinLock lock(process->m_fds_lock); - for (int i = 0; i < process->max_open_file_descriptors(); ++i) { - auto description_metadata = process->fds()[i]; - if (!description_metadata.is_valid()) - continue; - if (name == String::number(i)) { - return ProcFSProcessFileDescription::create(i, *description_metadata.description(), description_metadata.global_procfs_inode_index(), *this); + RefPtr<ProcFSProcessFileDescription> procfd_fd; + // FIXME: Try to exit the loop earlier + size_t count = 0; + m_process_folder->m_associated_process->fds().enumerate([&](auto& file_description_metadata) { + if (!file_description_metadata.is_valid()) { + count++; + return; } - } - return nullptr; + if (name == String::number(count)) { + procfd_fd = ProcFSProcessFileDescription::create(count, *file_description_metadata.description(), file_description_metadata.global_procfs_inode_index(), *this); + } + count++; + }); + return procfd_fd; } class ProcFSProcessUnveil final : public ProcFSProcessInformation { @@ -1350,19 +1357,21 @@ private: { JsonArraySerializer array { builder }; auto process = m_parent_folder->m_associated_process; - if (process->number_of_open_file_descriptors() == 0) { + if (process->fds().open_count() == 0) { array.finish(); return true; } - for (int i = 0; i < process->max_open_file_descriptors(); ++i) { - auto description = process->file_description(i); - if (!description) - continue; - bool cloexec = process->fd_flags(i) & FD_CLOEXEC; - + size_t count = 0; + process->fds().enumerate([&](auto& file_description_metadata) { + if (!file_description_metadata.is_valid()) { + count++; + return; + } + bool cloexec = file_description_metadata.flags() & FD_CLOEXEC; + RefPtr<FileDescription> description = file_description_metadata.description(); auto description_object = array.add_object(); - description_object.add("fd", i); + description_object.add("fd", count); description_object.add("absolute_path", description->absolute_path()); description_object.add("seekable", description->file().is_seekable()); description_object.add("class", description->file().class_name()); @@ -1371,7 +1380,9 @@ private: description_object.add("blocking", description->is_blocking()); description_object.add("can_read", description->can_read()); description_object.add("can_write", description->can_write()); - } + count++; + }); + array.finish(); return true; } diff --git a/Kernel/Syscalls/anon_create.cpp b/Kernel/Syscalls/anon_create.cpp index a7d56bad53..a0c57da8b7 100644 --- a/Kernel/Syscalls/anon_create.cpp +++ b/Kernel/Syscalls/anon_create.cpp @@ -24,7 +24,7 @@ KResultOr<FlatPtr> Process::sys$anon_create(size_t size, int options) if (size > NumericLimits<ssize_t>::max()) return EINVAL; - int new_fd = alloc_fd(); + int new_fd = m_fds.allocate(); if (new_fd < 0) return new_fd; diff --git a/Kernel/Syscalls/chdir.cpp b/Kernel/Syscalls/chdir.cpp index 715cb94c97..6d69d91c07 100644 --- a/Kernel/Syscalls/chdir.cpp +++ b/Kernel/Syscalls/chdir.cpp @@ -27,7 +27,7 @@ KResultOr<FlatPtr> Process::sys$chdir(Userspace<const char*> user_path, size_t p KResultOr<FlatPtr> Process::sys$fchdir(int fd) { REQUIRE_PROMISE(stdio); - auto description = file_description(fd); + auto description = fds().file_description(fd); if (!description) return EBADF; diff --git a/Kernel/Syscalls/chmod.cpp b/Kernel/Syscalls/chmod.cpp index 366fb0f0cc..0e8be00b1e 100644 --- a/Kernel/Syscalls/chmod.cpp +++ b/Kernel/Syscalls/chmod.cpp @@ -23,7 +23,7 @@ KResultOr<FlatPtr> Process::sys$chmod(Userspace<const char*> user_path, size_t p KResultOr<FlatPtr> Process::sys$fchmod(int fd, mode_t mode) { REQUIRE_PROMISE(fattr); - auto description = file_description(fd); + auto description = fds().file_description(fd); if (!description) return EBADF; return description->chmod(mode); diff --git a/Kernel/Syscalls/chown.cpp b/Kernel/Syscalls/chown.cpp index 97d9e50e67..ddc0203aca 100644 --- a/Kernel/Syscalls/chown.cpp +++ b/Kernel/Syscalls/chown.cpp @@ -12,7 +12,7 @@ namespace Kernel { KResultOr<FlatPtr> Process::sys$fchown(int fd, uid_t uid, gid_t gid) { REQUIRE_PROMISE(chown); - auto description = file_description(fd); + auto description = fds().file_description(fd); if (!description) return EBADF; return description->chown(uid, gid); diff --git a/Kernel/Syscalls/dup2.cpp b/Kernel/Syscalls/dup2.cpp index 6539b288e6..87a17fbba9 100644 --- a/Kernel/Syscalls/dup2.cpp +++ b/Kernel/Syscalls/dup2.cpp @@ -12,12 +12,12 @@ namespace Kernel { KResultOr<FlatPtr> Process::sys$dup2(int old_fd, int new_fd) { REQUIRE_PROMISE(stdio); - auto description = file_description(old_fd); + auto description = fds().file_description(old_fd); if (!description) return EBADF; if (old_fd == new_fd) return new_fd; - if (new_fd < 0 || new_fd >= m_max_open_file_descriptors) + if (new_fd < 0 || static_cast<size_t>(new_fd) >= fds().max_open()) return EINVAL; m_fds[new_fd].set(*description); return new_fd; diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp index 7539a82b9d..adf31e7a7c 100644 --- a/Kernel/Syscalls/execve.cpp +++ b/Kernel/Syscalls/execve.cpp @@ -573,15 +573,14 @@ KResult Process::do_exec(NonnullRefPtr<FileDescription> main_program_description clear_futex_queues_on_exec(); - for (size_t i = 0; i < m_fds.size(); ++i) { - auto& description_and_flags = m_fds[i]; - if (description_and_flags.description() && description_and_flags.flags() & FD_CLOEXEC) - description_and_flags = {}; - } + fds().change_each([&](auto& file_description_metadata) { + if (file_description_metadata.is_valid() && file_description_metadata.flags() & FD_CLOEXEC) + file_description_metadata = {}; + }); int main_program_fd = -1; if (interpreter_description) { - main_program_fd = alloc_fd(); + main_program_fd = m_fds.allocate(); VERIFY(main_program_fd >= 0); auto seek_result = main_program_description->seek(0, SEEK_SET); VERIFY(!seek_result.is_error()); diff --git a/Kernel/Syscalls/fcntl.cpp b/Kernel/Syscalls/fcntl.cpp index 3f28418c54..7d182583a0 100644 --- a/Kernel/Syscalls/fcntl.cpp +++ b/Kernel/Syscalls/fcntl.cpp @@ -14,7 +14,7 @@ KResultOr<FlatPtr> Process::sys$fcntl(int fd, int cmd, u32 arg) { REQUIRE_PROMISE(stdio); dbgln_if(IO_DEBUG, "sys$fcntl: fd={}, cmd={}, arg={}", fd, cmd, arg); - auto description = file_description(fd); + auto description = fds().file_description(fd); if (!description) return EBADF; // NOTE: The FD flags are not shared between FileDescription objects. @@ -24,7 +24,7 @@ KResultOr<FlatPtr> Process::sys$fcntl(int fd, int cmd, u32 arg) int arg_fd = (int)arg; if (arg_fd < 0) return EINVAL; - int new_fd = alloc_fd(arg_fd); + int new_fd = fds().allocate(arg_fd); if (new_fd < 0) return new_fd; m_fds[new_fd].set(*description); diff --git a/Kernel/Syscalls/ftruncate.cpp b/Kernel/Syscalls/ftruncate.cpp index 3497cb9bf8..21065b06f7 100644 --- a/Kernel/Syscalls/ftruncate.cpp +++ b/Kernel/Syscalls/ftruncate.cpp @@ -17,7 +17,7 @@ KResultOr<FlatPtr> Process::sys$ftruncate(int fd, Userspace<off_t*> userspace_le return EFAULT; if (length < 0) return EINVAL; - auto description = file_description(fd); + auto description = fds().file_description(fd); if (!description) return EBADF; if (!description->is_writable()) diff --git a/Kernel/Syscalls/get_dir_entries.cpp b/Kernel/Syscalls/get_dir_entries.cpp index 6125d08efe..880d4f1ae4 100644 --- a/Kernel/Syscalls/get_dir_entries.cpp +++ b/Kernel/Syscalls/get_dir_entries.cpp @@ -14,7 +14,7 @@ KResultOr<FlatPtr> Process::sys$get_dir_entries(int fd, Userspace<void*> user_bu REQUIRE_PROMISE(stdio); if (user_size > NumericLimits<ssize_t>::max()) return EINVAL; - auto description = file_description(fd); + auto description = fds().file_description(fd); if (!description) return EBADF; auto buffer = UserOrKernelBuffer::for_user_buffer(user_buffer, static_cast<size_t>(user_size)); diff --git a/Kernel/Syscalls/inode_watcher.cpp b/Kernel/Syscalls/inode_watcher.cpp index 38a3b51e79..af765c560e 100644 --- a/Kernel/Syscalls/inode_watcher.cpp +++ b/Kernel/Syscalls/inode_watcher.cpp @@ -17,7 +17,7 @@ KResultOr<FlatPtr> Process::sys$create_inode_watcher(u32 flags) { REQUIRE_PROMISE(rpath); - int fd = alloc_fd(); + int fd = m_fds.allocate(); if (fd < 0) return fd; @@ -48,7 +48,7 @@ KResultOr<FlatPtr> Process::sys$inode_watcher_add_watch(Userspace<const Syscall: if (!copy_from_user(¶ms, user_params)) return EFAULT; - auto description = file_description(params.fd); + auto description = fds().file_description(params.fd); if (!description) return EBADF; if (!description->is_inode_watcher()) @@ -75,7 +75,7 @@ KResultOr<FlatPtr> Process::sys$inode_watcher_add_watch(Userspace<const Syscall: KResultOr<FlatPtr> Process::sys$inode_watcher_remove_watch(int fd, int wd) { - auto description = file_description(fd); + auto description = fds().file_description(fd); if (!description) return EBADF; if (!description->is_inode_watcher()) diff --git a/Kernel/Syscalls/ioctl.cpp b/Kernel/Syscalls/ioctl.cpp index 8c2750b9f7..4c668904e2 100644 --- a/Kernel/Syscalls/ioctl.cpp +++ b/Kernel/Syscalls/ioctl.cpp @@ -12,7 +12,7 @@ namespace Kernel { KResultOr<FlatPtr> Process::sys$ioctl(int fd, unsigned request, FlatPtr arg) { - auto description = file_description(fd); + auto description = fds().file_description(fd); if (!description) return EBADF; if (request == FIONBIO) { diff --git a/Kernel/Syscalls/lseek.cpp b/Kernel/Syscalls/lseek.cpp index 80e5415c89..31d559dc31 100644 --- a/Kernel/Syscalls/lseek.cpp +++ b/Kernel/Syscalls/lseek.cpp @@ -12,7 +12,7 @@ namespace Kernel { KResultOr<FlatPtr> Process::sys$lseek(int fd, Userspace<off_t*> userspace_offset, int whence) { REQUIRE_PROMISE(stdio); - auto description = file_description(fd); + auto description = fds().file_description(fd); if (!description) return EBADF; off_t offset; diff --git a/Kernel/Syscalls/mmap.cpp b/Kernel/Syscalls/mmap.cpp index 79353249ae..f88bc4d51e 100644 --- a/Kernel/Syscalls/mmap.cpp +++ b/Kernel/Syscalls/mmap.cpp @@ -224,7 +224,7 @@ KResultOr<FlatPtr> Process::sys$mmap(Userspace<const Syscall::SC_mmap_params*> u return EINVAL; if (static_cast<size_t>(offset) & ~PAGE_MASK) return EINVAL; - auto description = file_description(fd); + auto description = fds().file_description(fd); if (!description) return EBADF; if (description->is_directory()) diff --git a/Kernel/Syscalls/mount.cpp b/Kernel/Syscalls/mount.cpp index f42c1bb213..9364790119 100644 --- a/Kernel/Syscalls/mount.cpp +++ b/Kernel/Syscalls/mount.cpp @@ -36,7 +36,7 @@ KResultOr<FlatPtr> Process::sys$mount(Userspace<const Syscall::SC_mount_params*> if (fs_type.is_null()) return EFAULT; - auto description = file_description(source_fd); + auto description = fds().file_description(source_fd); if (!description.is_null()) dbgln("mount {}: source fd {} @ {}", fs_type, source_fd, target); else diff --git a/Kernel/Syscalls/open.cpp b/Kernel/Syscalls/open.cpp index 4df12ef4a7..5ab765653c 100644 --- a/Kernel/Syscalls/open.cpp +++ b/Kernel/Syscalls/open.cpp @@ -44,7 +44,7 @@ KResultOr<FlatPtr> Process::sys$open(Userspace<const Syscall::SC_open_params*> u return path.error(); dbgln_if(IO_DEBUG, "sys$open(dirfd={}, path='{}', options={}, mode={})", dirfd, path.value()->view(), options, mode); - int fd = alloc_fd(); + int fd = m_fds.allocate(); if (fd < 0) return fd; @@ -52,7 +52,7 @@ KResultOr<FlatPtr> Process::sys$open(Userspace<const Syscall::SC_open_params*> u if (dirfd == AT_FDCWD) { base = current_directory(); } else { - auto base_description = file_description(dirfd); + auto base_description = fds().file_description(dirfd); if (!base_description) return EBADF; if (!base_description->is_directory()) @@ -78,7 +78,7 @@ KResultOr<FlatPtr> Process::sys$open(Userspace<const Syscall::SC_open_params*> u KResultOr<FlatPtr> Process::sys$close(int fd) { REQUIRE_PROMISE(stdio); - auto description = file_description(fd); + auto description = fds().file_description(fd); dbgln_if(IO_DEBUG, "sys$close({}) {}", fd, description.ptr()); if (!description) return EBADF; diff --git a/Kernel/Syscalls/pipe.cpp b/Kernel/Syscalls/pipe.cpp index b289a3958a..ef70709339 100644 --- a/Kernel/Syscalls/pipe.cpp +++ b/Kernel/Syscalls/pipe.cpp @@ -13,7 +13,7 @@ namespace Kernel { KResultOr<FlatPtr> Process::sys$pipe(int pipefd[2], int flags) { REQUIRE_PROMISE(stdio); - if (number_of_open_file_descriptors() + 2 > max_open_file_descriptors()) + if (fds().open_count() + 2 > fds().max_open()) return EMFILE; // Reject flags other than O_CLOEXEC. if ((flags & O_CLOEXEC) != flags) @@ -29,13 +29,13 @@ KResultOr<FlatPtr> Process::sys$pipe(int pipefd[2], int flags) if (open_writer_result.is_error()) return open_writer_result.error(); - int reader_fd = alloc_fd(); + int reader_fd = m_fds.allocate(); m_fds[reader_fd].set(open_reader_result.release_value(), fd_flags); m_fds[reader_fd].description()->set_readable(true); if (!copy_to_user(&pipefd[0], &reader_fd)) return EFAULT; - int writer_fd = alloc_fd(); + int writer_fd = m_fds.allocate(); m_fds[writer_fd].set(open_writer_result.release_value(), fd_flags); m_fds[writer_fd].description()->set_writable(true); if (!copy_to_user(&pipefd[1], &writer_fd)) diff --git a/Kernel/Syscalls/read.cpp b/Kernel/Syscalls/read.cpp index f37b3d9d32..58ead804c5 100644 --- a/Kernel/Syscalls/read.cpp +++ b/Kernel/Syscalls/read.cpp @@ -34,7 +34,7 @@ KResultOr<FlatPtr> Process::sys$readv(int fd, Userspace<const struct iovec*> iov return EINVAL; } - auto description = file_description(fd); + auto description = fds().file_description(fd); if (!description) return EBADF; @@ -76,7 +76,7 @@ KResultOr<FlatPtr> Process::sys$read(int fd, Userspace<u8*> buffer, size_t size) if (size > NumericLimits<ssize_t>::max()) return EINVAL; dbgln_if(IO_DEBUG, "sys$read({}, {}, {})", fd, buffer.ptr(), size); - auto description = file_description(fd); + auto description = fds().file_description(fd); if (!description) return EBADF; if (!description->is_readable()) diff --git a/Kernel/Syscalls/select.cpp b/Kernel/Syscalls/select.cpp index 87b61a4721..04758cf94f 100644 --- a/Kernel/Syscalls/select.cpp +++ b/Kernel/Syscalls/select.cpp @@ -61,7 +61,7 @@ KResultOr<FlatPtr> Process::sys$select(Userspace<const Syscall::SC_select_params return EFAULT; Thread::SelectBlocker::FDVector fds_info; - Vector<int, FD_SETSIZE> fds; + Vector<int, FD_SETSIZE> selected_fds; for (int fd = 0; fd < params.nfds; fd++) { auto block_flags = BlockFlags::None; if (params.readfds && FD_ISSET(fd, &fds_read)) @@ -73,14 +73,14 @@ KResultOr<FlatPtr> Process::sys$select(Userspace<const Syscall::SC_select_params if (block_flags == BlockFlags::None) continue; - auto description = file_description(fd); + auto description = fds().file_description(fd); if (!description) { dbgln("sys$select: Bad fd number {}", fd); return EBADF; } if (!fds_info.try_append({ description.release_nonnull(), block_flags })) return ENOMEM; - if (!fds.try_append(fd)) + if (!selected_fds.try_append(fd)) return ENOMEM; } @@ -105,15 +105,15 @@ KResultOr<FlatPtr> Process::sys$select(Userspace<const Syscall::SC_select_params if (fd_entry.unblocked_flags == BlockFlags::None) continue; if (params.readfds && has_flag(fd_entry.unblocked_flags, BlockFlags::Read)) { - FD_SET(fds[i], &fds_read); + FD_SET(selected_fds[i], &fds_read); marked_fd_count++; } if (params.writefds && has_flag(fd_entry.unblocked_flags, BlockFlags::Write)) { - FD_SET(fds[i], &fds_write); + FD_SET(selected_fds[i], &fds_write); marked_fd_count++; } if (params.exceptfds && has_flag(fd_entry.unblocked_flags, BlockFlags::Exception)) { - FD_SET(fds[i], &fds_except); + FD_SET(selected_fds[i], &fds_except); marked_fd_count++; } } @@ -135,7 +135,7 @@ KResultOr<FlatPtr> Process::sys$poll(Userspace<const Syscall::SC_poll_params*> u if (!copy_from_user(¶ms, user_params)) return EFAULT; - if (params.nfds >= m_max_open_file_descriptors) + if (params.nfds >= fds().max_open()) return ENOBUFS; Thread::BlockTimeout timeout; @@ -165,7 +165,7 @@ KResultOr<FlatPtr> Process::sys$poll(Userspace<const Syscall::SC_poll_params*> u Thread::SelectBlocker::FDVector fds_info; for (size_t i = 0; i < params.nfds; i++) { auto& pfd = fds_copy[i]; - auto description = file_description(pfd.fd); + auto description = fds().file_description(pfd.fd); if (!description) { dbgln("sys$poll: Bad fd number {}", pfd.fd); return EBADF; diff --git a/Kernel/Syscalls/sendfd.cpp b/Kernel/Syscalls/sendfd.cpp index f4f47e490d..0c82581a13 100644 --- a/Kernel/Syscalls/sendfd.cpp +++ b/Kernel/Syscalls/sendfd.cpp @@ -13,7 +13,7 @@ namespace Kernel { KResultOr<FlatPtr> Process::sys$sendfd(int sockfd, int fd) { REQUIRE_PROMISE(sendfd); - auto socket_description = file_description(sockfd); + auto socket_description = fds().file_description(sockfd); if (!socket_description) return EBADF; if (!socket_description->is_socket()) @@ -24,7 +24,7 @@ KResultOr<FlatPtr> Process::sys$sendfd(int sockfd, int fd) if (!socket.is_connected()) return ENOTCONN; - auto passing_descriptor = file_description(fd); + auto passing_descriptor = fds().file_description(fd); if (!passing_descriptor) return EBADF; @@ -35,7 +35,7 @@ KResultOr<FlatPtr> Process::sys$sendfd(int sockfd, int fd) KResultOr<FlatPtr> Process::sys$recvfd(int sockfd, int options) { REQUIRE_PROMISE(recvfd); - auto socket_description = file_description(sockfd); + auto socket_description = fds().file_description(sockfd); if (!socket_description) return EBADF; if (!socket_description->is_socket()) @@ -44,7 +44,7 @@ KResultOr<FlatPtr> Process::sys$recvfd(int sockfd, int options) if (!socket.is_local()) return EAFNOSUPPORT; - int new_fd = alloc_fd(); + int new_fd = m_fds.allocate(); if (new_fd < 0) return new_fd; diff --git a/Kernel/Syscalls/socket.cpp b/Kernel/Syscalls/socket.cpp index b18906e413..108e3967f1 100644 --- a/Kernel/Syscalls/socket.cpp +++ b/Kernel/Syscalls/socket.cpp @@ -38,7 +38,7 @@ KResultOr<FlatPtr> Process::sys$socket(int domain, int type, int protocol) if ((type & SOCK_TYPE_MASK) == SOCK_RAW && !is_superuser()) return EACCES; - int fd = alloc_fd(); + int fd = m_fds.allocate(); if (fd < 0) return fd; auto result = Socket::create(domain, type, protocol); @@ -53,7 +53,7 @@ KResultOr<FlatPtr> Process::sys$socket(int domain, int type, int protocol) KResultOr<FlatPtr> Process::sys$bind(int sockfd, Userspace<const sockaddr*> address, socklen_t address_length) { - auto description = file_description(sockfd); + auto description = fds().file_description(sockfd); if (!description) return EBADF; if (!description->is_socket()) @@ -67,7 +67,7 @@ KResultOr<FlatPtr> Process::sys$listen(int sockfd, int backlog) { if (backlog < 0) return EINVAL; - auto description = file_description(sockfd); + auto description = fds().file_description(sockfd); if (!description) return EBADF; if (!description->is_socket()) @@ -96,10 +96,10 @@ KResultOr<FlatPtr> Process::sys$accept4(Userspace<const Syscall::SC_accept4_para if (user_address && !copy_from_user(&address_size, static_ptr_cast<const socklen_t*>(user_address_size))) return EFAULT; - int accepted_socket_fd = alloc_fd(); + int accepted_socket_fd = m_fds.allocate(); if (accepted_socket_fd < 0) return accepted_socket_fd; - auto accepting_socket_description = file_description(accepting_socket_fd); + auto accepting_socket_description = fds().file_description(accepting_socket_fd); if (!accepting_socket_description) return EBADF; if (!accepting_socket_description->is_socket()) @@ -148,10 +148,10 @@ KResultOr<FlatPtr> Process::sys$accept4(Userspace<const Syscall::SC_accept4_para KResultOr<FlatPtr> Process::sys$connect(int sockfd, Userspace<const sockaddr*> user_address, socklen_t user_address_size) { - int fd = alloc_fd(); + int fd = m_fds.allocate(); if (fd < 0) return fd; - auto description = file_description(sockfd); + auto description = fds().file_description(sockfd); if (!description) return EBADF; if (!description->is_socket()) @@ -168,7 +168,7 @@ KResultOr<FlatPtr> Process::sys$shutdown(int sockfd, int how) REQUIRE_PROMISE(stdio); if (how & ~SHUT_RDWR) return EINVAL; - auto description = file_description(sockfd); + auto description = fds().file_description(sockfd); if (!description) return EBADF; if (!description->is_socket()) @@ -199,7 +199,7 @@ KResultOr<FlatPtr> Process::sys$sendmsg(int sockfd, Userspace<const struct msghd Userspace<const sockaddr*> user_addr((FlatPtr)msg.msg_name); socklen_t addr_length = msg.msg_namelen; - auto description = file_description(sockfd); + auto description = fds().file_description(sockfd); if (!description) return EBADF; if (!description->is_socket()) @@ -236,7 +236,7 @@ KResultOr<FlatPtr> Process::sys$recvmsg(int sockfd, Userspace<struct msghdr*> us Userspace<sockaddr*> user_addr((FlatPtr)msg.msg_name); Userspace<socklen_t*> user_addr_length(msg.msg_name ? (FlatPtr)&user_msg.unsafe_userspace_ptr()->msg_namelen : 0); - auto description = file_description(sockfd); + auto description = fds().file_description(sockfd); if (!description) return EBADF; if (!description->is_socket()) @@ -301,7 +301,7 @@ int Process::get_sock_or_peer_name(const Params& params) if (addrlen_value <= 0) return EINVAL; - auto description = file_description(params.sockfd); + auto description = fds().file_description(params.sockfd); if (!description) return EBADF; @@ -356,7 +356,7 @@ KResultOr<FlatPtr> Process::sys$getsockopt(Userspace<const Syscall::SC_getsockop if (!copy_from_user(&value_size, params.value_size, sizeof(socklen_t))) return EFAULT; - auto description = file_description(sockfd); + auto description = fds().file_description(sockfd); if (!description) return EBADF; if (!description->is_socket()) @@ -373,7 +373,7 @@ KResultOr<FlatPtr> Process::sys$setsockopt(Userspace<const Syscall::SC_setsockop if (!copy_from_user(¶ms, user_params)) return EFAULT; Userspace<const void*> user_value((FlatPtr)params.value); - auto description = file_description(params.sockfd); + auto description = fds().file_description(params.sockfd); if (!description) return EBADF; if (!description->is_socket()) @@ -401,12 +401,12 @@ KResultOr<FlatPtr> Process::sys$socketpair(Userspace<const Syscall::SC_socketpai auto pair = result.value(); int fds[2]; - fds[0] = alloc_fd(); + fds[0] = m_fds.allocate(); if (fds[0] < 0) return ENFILE; setup_socket_fd(fds[0], pair.description1, params.type); - fds[1] = alloc_fd(); + fds[1] = m_fds.allocate(); if (fds[1] < 0) { // FIXME: This leaks fds[0] return ENFILE; diff --git a/Kernel/Syscalls/stat.cpp b/Kernel/Syscalls/stat.cpp index 60b7ddff3a..409b1b92eb 100644 --- a/Kernel/Syscalls/stat.cpp +++ b/Kernel/Syscalls/stat.cpp @@ -15,7 +15,7 @@ namespace Kernel { KResultOr<FlatPtr> Process::sys$fstat(int fd, Userspace<stat*> user_statbuf) { REQUIRE_PROMISE(stdio); - auto description = file_description(fd); + auto description = fds().file_description(fd); if (!description) return EBADF; stat buffer = {}; @@ -38,7 +38,7 @@ KResultOr<FlatPtr> Process::sys$stat(Userspace<const Syscall::SC_stat_params*> u if (params.dirfd == AT_FDCWD) { base = current_directory(); } else { - auto base_description = file_description(params.dirfd); + auto base_description = fds().file_description(params.dirfd); if (!base_description) return EBADF; if (!base_description->is_directory()) diff --git a/Kernel/Syscalls/statvfs.cpp b/Kernel/Syscalls/statvfs.cpp index 0e6562a7be..6d34369765 100644 --- a/Kernel/Syscalls/statvfs.cpp +++ b/Kernel/Syscalls/statvfs.cpp @@ -87,7 +87,7 @@ KResultOr<FlatPtr> Process::sys$fstatvfs(int fd, statvfs* buf) { REQUIRE_PROMISE(stdio); - auto description = file_description(fd); + auto description = fds().file_description(fd); if (!description) return EBADF; diff --git a/Kernel/Syscalls/sysconf.cpp b/Kernel/Syscalls/sysconf.cpp index 9460b7c585..2a6dae7b52 100644 --- a/Kernel/Syscalls/sysconf.cpp +++ b/Kernel/Syscalls/sysconf.cpp @@ -18,7 +18,7 @@ KResultOr<FlatPtr> Process::sys$sysconf(int name) case _SC_NPROCESSORS_ONLN: return Processor::processor_count(); case _SC_OPEN_MAX: - return max_open_file_descriptors(); + return fds().max_open(); case _SC_PAGESIZE: return PAGE_SIZE; case _SC_TTY_NAME_MAX: diff --git a/Kernel/Syscalls/ttyname.cpp b/Kernel/Syscalls/ttyname.cpp index c544b52a13..01f8776b93 100644 --- a/Kernel/Syscalls/ttyname.cpp +++ b/Kernel/Syscalls/ttyname.cpp @@ -14,7 +14,7 @@ namespace Kernel { KResultOr<FlatPtr> Process::sys$ttyname(int fd, Userspace<char*> buffer, size_t size) { REQUIRE_PROMISE(tty); - auto description = file_description(fd); + auto description = fds().file_description(fd); if (!description) return EBADF; if (!description->is_tty()) @@ -30,7 +30,7 @@ KResultOr<FlatPtr> Process::sys$ttyname(int fd, Userspace<char*> buffer, size_t KResultOr<FlatPtr> Process::sys$ptsname(int fd, Userspace<char*> buffer, size_t size) { REQUIRE_PROMISE(tty); - auto description = file_description(fd); + auto description = fds().file_description(fd); if (!description) return EBADF; auto* master_pty = description->master_pty(); diff --git a/Kernel/Syscalls/write.cpp b/Kernel/Syscalls/write.cpp index fece780d9c..2ede957a53 100644 --- a/Kernel/Syscalls/write.cpp +++ b/Kernel/Syscalls/write.cpp @@ -33,7 +33,7 @@ KResultOr<FlatPtr> Process::sys$writev(int fd, Userspace<const struct iovec*> io return EINVAL; } - auto description = file_description(fd); + auto description = fds().file_description(fd); if (!description) return EBADF; @@ -105,7 +105,7 @@ KResultOr<FlatPtr> Process::sys$write(int fd, Userspace<const u8*> data, size_t return EINVAL; dbgln_if(IO_DEBUG, "sys$write({}, {}, {})", fd, data.ptr(), size); - auto description = file_description(fd); + auto description = fds().file_description(fd); if (!description) return EBADF; if (!description->is_writable()) |