From 18e90d305d4dfe2d73ef9a1b39eef79c094cd2ca Mon Sep 17 00:00:00 2001 From: Bananymous Date: Wed, 25 Oct 2023 19:36:04 +0300 Subject: [PATCH] Kernel: Add Inode API for creating directories --- kernel/include/kernel/FS/Inode.h | 2 ++ kernel/include/kernel/Process.h | 2 +- kernel/kernel/FS/Inode.cpp | 13 +++++++++++++ kernel/kernel/Process.cpp | 19 ++++++++++++++++--- 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/kernel/include/kernel/FS/Inode.h b/kernel/include/kernel/FS/Inode.h index d98d9fdbb1..f5cd27c2a2 100644 --- a/kernel/include/kernel/FS/Inode.h +++ b/kernel/include/kernel/FS/Inode.h @@ -90,6 +90,7 @@ namespace Kernel BAN::ErrorOr> find_inode(BAN::StringView); BAN::ErrorOr list_next_inodes(off_t, DirectoryEntryList*, size_t); BAN::ErrorOr create_file(BAN::StringView, mode_t, uid_t, gid_t); + BAN::ErrorOr create_directory(BAN::StringView, mode_t, uid_t, gid_t); BAN::ErrorOr delete_inode(BAN::StringView); // Link API @@ -107,6 +108,7 @@ namespace Kernel virtual BAN::ErrorOr> find_inode_impl(BAN::StringView) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr list_next_inodes_impl(off_t, DirectoryEntryList*, size_t) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr create_file_impl(BAN::StringView, mode_t, uid_t, gid_t) { return BAN::Error::from_errno(ENOTSUP); } + virtual BAN::ErrorOr create_directory_impl(BAN::StringView, mode_t, uid_t, gid_t) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr delete_inode_impl(BAN::StringView) { return BAN::Error::from_errno(ENOTSUP); } // Link API diff --git a/kernel/include/kernel/Process.h b/kernel/include/kernel/Process.h index 6fde6a6918..9fbe4aadb9 100644 --- a/kernel/include/kernel/Process.h +++ b/kernel/include/kernel/Process.h @@ -89,7 +89,7 @@ namespace Kernel BAN::ErrorOr sys_getegid() const { return m_credentials.egid(); } BAN::ErrorOr sys_getpgid(pid_t); - BAN::ErrorOr create_file(BAN::StringView name, mode_t mode); + BAN::ErrorOr create_file_or_dir(BAN::StringView name, mode_t mode); BAN::ErrorOr open_file(BAN::StringView path, int, mode_t = 0); BAN::ErrorOr sys_open(const char* path, int, mode_t); BAN::ErrorOr sys_openat(int, const char* path, int, mode_t); diff --git a/kernel/kernel/FS/Inode.cpp b/kernel/kernel/FS/Inode.cpp index f846ba4e7e..5712e9801e 100644 --- a/kernel/kernel/FS/Inode.cpp +++ b/kernel/kernel/FS/Inode.cpp @@ -81,9 +81,22 @@ namespace Kernel Thread::TerminateBlocker blocker(Thread::current()); if (!this->mode().ifdir()) return BAN::Error::from_errno(ENOTDIR); + if (Mode(mode).ifdir()) + return BAN::Error::from_errno(EINVAL); return create_file_impl(name, mode, uid, gid); } + BAN::ErrorOr Inode::create_directory(BAN::StringView name, mode_t mode, uid_t uid, gid_t gid) + { + LockGuard _(m_lock); + Thread::TerminateBlocker blocker(Thread::current()); + if (!this->mode().ifdir()) + return BAN::Error::from_errno(ENOTDIR); + if (!Mode(mode).ifdir()) + return BAN::Error::from_errno(EINVAL); + return create_directory_impl(name, mode, uid, gid); + } + BAN::ErrorOr Inode::delete_inode(BAN::StringView name) { LockGuard _(m_lock); diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index a2119eeedf..46083aff78 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -611,8 +611,17 @@ namespace Kernel return 0; } - BAN::ErrorOr Process::create_file(BAN::StringView path, mode_t mode) + BAN::ErrorOr Process::create_file_or_dir(BAN::StringView path, mode_t mode) { + switch (mode & Inode::Mode::TYPE_MASK) + { + case Inode::Mode::IFREG: break; + case Inode::Mode::IFDIR: break; + case Inode::Mode::IFIFO: break; + default: + return BAN::Error::from_errno(EINVAL); + } + LockGuard _(m_lock); auto absolute_path = TRY(absolute_path_of(path)); @@ -626,7 +635,11 @@ namespace Kernel auto file_name = absolute_path.sv().substring(index); auto parent_inode = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, directory, O_WRONLY)).inode; - TRY(parent_inode->create_file(file_name, S_IFREG | (mode & 0777), m_credentials.euid(), m_credentials.egid())); + + if (Inode::Mode(mode).ifdir()) + TRY(parent_inode->create_directory(file_name, mode, m_credentials.euid(), m_credentials.egid())); + else + TRY(parent_inode->create_file(file_name, mode, m_credentials.euid(), m_credentials.egid())); return {}; } @@ -672,7 +685,7 @@ namespace Kernel if (file_or_error.is_error()) { if (file_or_error.error().get_error_code() == ENOENT) - TRY(create_file(path, mode)); + TRY(create_file_or_dir(path, Inode::Mode::IFREG | mode)); else return file_or_error.release_error(); }