From f1a4bbce539bef68793402e79b784419d00b61c2 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Tue, 17 Sep 2024 16:27:11 +0300 Subject: [PATCH] Kernel/LibC: Implement all stat family functions with fstatat This patch gets rid of 2 unnecessary syscalls! --- kernel/include/kernel/Process.h | 2 - kernel/kernel/Process.cpp | 69 +++++++------------ .../libraries/LibC/include/sys/syscall.h | 2 - userspace/libraries/LibC/sys/stat.cpp | 7 +- 4 files changed, 28 insertions(+), 52 deletions(-) diff --git a/kernel/include/kernel/Process.h b/kernel/include/kernel/Process.h index c7ba34b4..82ad05e0 100644 --- a/kernel/include/kernel/Process.h +++ b/kernel/include/kernel/Process.h @@ -146,9 +146,7 @@ namespace Kernel BAN::ErrorOr sys_truncate(int fd, off_t length); - BAN::ErrorOr sys_fstat(int fd, struct stat*); BAN::ErrorOr sys_fstatat(int fd, const char* path, struct stat* buf, int flag); - BAN::ErrorOr sys_stat(const char* path, struct stat* buf, int flag); BAN::ErrorOr sys_realpath(const char* path, char* buffer); diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index bdebc53d..819a9e14 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -1400,33 +1400,6 @@ namespace Kernel return {}; } - static void read_stat_from_inode(BAN::RefPtr inode, struct stat* out) - { - out->st_dev = inode->dev(); - out->st_ino = inode->ino(); - out->st_mode = inode->mode().mode; - out->st_nlink = inode->nlink(); - out->st_uid = inode->uid(); - out->st_gid = inode->gid(); - out->st_rdev = inode->rdev(); - out->st_size = inode->size(); - out->st_atim = inode->atime(); - out->st_mtim = inode->mtime(); - out->st_ctim = inode->ctime(); - out->st_blksize = inode->blksize(); - out->st_blocks = inode->blocks(); - } - - BAN::ErrorOr Process::sys_fstat(int fd, struct stat* buf) - { - LockGuard _(m_process_lock); - TRY(validate_pointer_access(buf, sizeof(struct stat), true)); - - auto inode = TRY(m_open_file_descriptors.inode_of(fd)); - read_stat_from_inode(inode, buf); - return 0; - } - BAN::ErrorOr Process::sys_fstatat(int fd, const char* path, struct stat* buf, int flags) { if (flags & ~AT_SYMLINK_NOFOLLOW) @@ -1435,27 +1408,35 @@ namespace Kernel flags = O_NOFOLLOW; LockGuard _(m_process_lock); + if (path) + TRY(validate_string_access(path)); TRY(validate_pointer_access(buf, sizeof(struct stat), true)); - auto parent_file = TRY(m_open_file_descriptors.file_of(fd)); - auto inode = TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flags)).inode; - read_stat_from_inode(inode, buf); - return 0; - } + VirtualFileSystem::File parent_file; + if (path && path[0] == '/') + parent_file = VirtualFileSystem::get().root_file(); + else if (fd == AT_FDCWD) + parent_file = TRY(m_working_directory.clone()); + else + parent_file = TRY(m_open_file_descriptors.file_of(fd)); - BAN::ErrorOr Process::sys_stat(const char* path, struct stat* buf, int flags) - { - if (flags & ~AT_SYMLINK_NOFOLLOW) - return BAN::Error::from_errno(EINVAL); - if (flags == AT_SYMLINK_NOFOLLOW) - flags = O_NOFOLLOW; + const auto inode = path + ? TRY(VirtualFileSystem::get().file_from_relative_path(parent_file, m_credentials, path, flags)).inode + : parent_file.inode; + buf->st_dev = inode->dev(); + buf->st_ino = inode->ino(); + buf->st_mode = inode->mode().mode; + buf->st_nlink = inode->nlink(); + buf->st_uid = inode->uid(); + buf->st_gid = inode->gid(); + buf->st_rdev = inode->rdev(); + buf->st_size = inode->size(); + buf->st_atim = inode->atime(); + buf->st_mtim = inode->mtime(); + buf->st_ctim = inode->ctime(); + buf->st_blksize = inode->blksize(); + buf->st_blocks = inode->blocks(); - LockGuard _(m_process_lock); - TRY(validate_pointer_access(buf, sizeof(struct stat), true)); - - auto absolute_path = TRY(absolute_path_of(path)); - auto inode = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, flags)).inode; - read_stat_from_inode(inode, buf); return 0; } diff --git a/userspace/libraries/LibC/include/sys/syscall.h b/userspace/libraries/LibC/include/sys/syscall.h index 9f873a88..e4190818 100644 --- a/userspace/libraries/LibC/include/sys/syscall.h +++ b/userspace/libraries/LibC/include/sys/syscall.h @@ -20,7 +20,6 @@ __BEGIN_DECLS O(SYS_EXEC, exec) \ O(SYS_SLEEP, sleep) \ O(SYS_WAIT, wait) \ - O(SYS_FSTAT, fstat) \ O(SYS_READ_DIR, readdir) \ O(SYS_SET_UID, setuid) \ O(SYS_SET_GID, setgid) \ @@ -47,7 +46,6 @@ __BEGIN_DECLS O(SYS_FCNTL, fcntl) \ O(SYS_NANOSLEEP, nanosleep) \ O(SYS_FSTATAT, fstatat) \ - O(SYS_STAT, stat) \ O(SYS_SYNC, sync) \ O(SYS_MMAP, mmap) \ O(SYS_MUNMAP, munmap) \ diff --git a/userspace/libraries/LibC/sys/stat.cpp b/userspace/libraries/LibC/sys/stat.cpp index 69e94b26..ad3189e9 100644 --- a/userspace/libraries/LibC/sys/stat.cpp +++ b/userspace/libraries/LibC/sys/stat.cpp @@ -1,6 +1,5 @@ #include -#include #include #include #include @@ -20,7 +19,7 @@ int fchmod(int fildes, mode_t mode) int fstat(int fildes, struct stat* buf) { - return syscall(SYS_FSTAT, fildes, buf); + return fstatat(fildes, nullptr, buf, 0); } int fstatat(int fd, const char* __restrict path, struct stat* __restrict buf, int flag) @@ -30,12 +29,12 @@ int fstatat(int fd, const char* __restrict path, struct stat* __restrict buf, in int lstat(const char* __restrict path, struct stat* __restrict buf) { - return syscall(SYS_STAT, path, buf, AT_SYMLINK_NOFOLLOW); + return fstatat(AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW); } int stat(const char* __restrict path, struct stat* __restrict buf) { - return syscall(SYS_STAT, path, buf, 0); + return fstatat(AT_FDCWD, path, buf, 0); } mode_t umask(mode_t cmask)