From dd9af56e214204465aed432c4e72dd635d4c0050 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Sat, 9 Sep 2023 22:45:27 +0300 Subject: [PATCH] Kernel: Start work on making inodes more thread safe All inode operations are now locked and thread blocked --- kernel/include/kernel/Device/NullDevice.h | 7 +- kernel/include/kernel/FS/Ext2/FileSystem.h | 2 + kernel/include/kernel/FS/Ext2/Inode.h | 16 ++--- kernel/include/kernel/FS/Inode.h | 38 +++++++--- kernel/include/kernel/FS/Pipe.h | 5 +- kernel/include/kernel/FS/RamFS/Inode.h | 22 +++--- kernel/include/kernel/FS/VirtualFileSystem.h | 6 +- kernel/include/kernel/Input/PS2Keyboard.h | 4 +- kernel/include/kernel/Storage/ATADevice.h | 3 +- kernel/include/kernel/Storage/StorageDevice.h | 3 +- kernel/include/kernel/Terminal/TTY.h | 6 +- kernel/kernel/FS/Ext2/FileSystem.cpp | 15 ++++ kernel/kernel/FS/Ext2/Inode.cpp | 58 ++++++++------- kernel/kernel/FS/Inode.cpp | 72 +++++++++++++++++++ kernel/kernel/FS/Pipe.cpp | 8 +-- kernel/kernel/FS/RamFS/Inode.cpp | 34 ++++----- kernel/kernel/FS/VirtualFileSystem.cpp | 8 +-- kernel/kernel/Input/PS2Keyboard.cpp | 2 +- kernel/kernel/OpenFileDescriptorSet.cpp | 2 +- kernel/kernel/Storage/ATADevice.cpp | 5 +- kernel/kernel/Storage/StorageDevice.cpp | 4 +- kernel/kernel/Terminal/TTY.cpp | 6 +- kernel/kernel/kernel.cpp | 8 +-- 23 files changed, 229 insertions(+), 105 deletions(-) diff --git a/kernel/include/kernel/Device/NullDevice.h b/kernel/include/kernel/Device/NullDevice.h index 60abe67d..76da8b08 100644 --- a/kernel/include/kernel/Device/NullDevice.h +++ b/kernel/include/kernel/Device/NullDevice.h @@ -1,4 +1,3 @@ -#include #include namespace Kernel @@ -11,14 +10,14 @@ namespace Kernel virtual dev_t rdev() const override { return m_rdev; } - virtual BAN::ErrorOr read(size_t, void*, size_t) override { return 0; } - virtual BAN::ErrorOr write(size_t, const void*, size_t size) override { return size; }; - protected: NullDevice(mode_t mode, uid_t uid, gid_t gid, dev_t rdev) : CharacterDevice(mode, uid, gid) , m_rdev(rdev) { } + + virtual BAN::ErrorOr read_impl(off_t, void*, size_t) override { return 0; } + virtual BAN::ErrorOr write_impl(off_t, const void*, size_t size) override { return size; }; private: const dev_t m_rdev; diff --git a/kernel/include/kernel/FS/Ext2/FileSystem.h b/kernel/include/kernel/FS/Ext2/FileSystem.h index e184c4a3..3776032b 100644 --- a/kernel/include/kernel/FS/Ext2/FileSystem.h +++ b/kernel/include/kernel/FS/Ext2/FileSystem.h @@ -45,6 +45,8 @@ namespace Kernel uint32_t block_size() const { return 1024 << superblock().log_block_size; } private: + RecursiveSpinLock m_lock; + Partition& m_partition; BAN::RefPtr m_root_inode; diff --git a/kernel/include/kernel/FS/Ext2/Inode.h b/kernel/include/kernel/FS/Ext2/Inode.h index c706ad35..31a3d772 100644 --- a/kernel/include/kernel/FS/Ext2/Inode.h +++ b/kernel/include/kernel/FS/Ext2/Inode.h @@ -27,16 +27,16 @@ namespace Kernel virtual dev_t dev() const override { return 0; } virtual dev_t rdev() const override { return 0; } - virtual BAN::ErrorOr link_target() override; + protected: + virtual BAN::ErrorOr> find_inode_impl(BAN::StringView) override; + virtual BAN::ErrorOr list_next_inodes_impl(off_t, DirectoryEntryList*, size_t) override; + virtual BAN::ErrorOr create_file_impl(BAN::StringView, mode_t, uid_t, gid_t) override; - virtual BAN::ErrorOr directory_read_next_entries(off_t, DirectoryEntryList*, size_t) override; - virtual BAN::ErrorOr> directory_find_inode(BAN::StringView) override; + virtual BAN::ErrorOr link_target_impl() override; - virtual BAN::ErrorOr read(size_t, void*, size_t) override; - virtual BAN::ErrorOr write(size_t, const void*, size_t) override; - virtual BAN::ErrorOr truncate(size_t) override; - - virtual BAN::ErrorOr create_file(BAN::StringView, mode_t, uid_t, gid_t) override; + virtual BAN::ErrorOr read_impl(off_t, void*, size_t) override; + virtual BAN::ErrorOr write_impl(off_t, const void*, size_t) override; + virtual BAN::ErrorOr truncate_impl(size_t) override; private: BAN::ErrorOr for_data_block_index(uint32_t, const BAN::Function&, bool allocate); diff --git a/kernel/include/kernel/FS/Inode.h b/kernel/include/kernel/FS/Inode.h index c159a642..f722b12e 100644 --- a/kernel/include/kernel/FS/Inode.h +++ b/kernel/include/kernel/FS/Inode.h @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -80,18 +81,37 @@ namespace Kernel virtual bool is_pipe() const { return false; } virtual bool is_tty() const { return false; } - virtual BAN::ErrorOr link_target() { ASSERT_NOT_REACHED(); } + // Directory API + 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); - virtual BAN::ErrorOr> directory_find_inode(BAN::StringView) { if (!mode().ifdir()) return BAN::Error::from_errno(ENOTDIR); ASSERT_NOT_REACHED(); } - virtual BAN::ErrorOr directory_read_next_entries(off_t, DirectoryEntryList*, size_t) { if (!mode().ifdir()) return BAN::Error::from_errno(ENOTDIR); ASSERT_NOT_REACHED(); } + // Link API + BAN::ErrorOr link_target(); - virtual BAN::ErrorOr read(size_t, void*, size_t) { if (mode().ifdir()) return BAN::Error::from_errno(EISDIR); ASSERT_NOT_REACHED(); } - virtual BAN::ErrorOr write(size_t, const void*, size_t) { if (mode().ifdir()) return BAN::Error::from_errno(EISDIR); ASSERT_NOT_REACHED(); } - virtual bool has_data() const { dwarnln("nonblock not supported"); return true; } - - virtual BAN::ErrorOr truncate(size_t) { if (mode().ifdir()) return BAN::Error::from_errno(EISDIR); return BAN::Error::from_errno(ENOTSUP); } + // General API + BAN::ErrorOr read(off_t, void*, size_t); + BAN::ErrorOr write(off_t, const void*, size_t); + BAN::ErrorOr truncate(size_t); + bool has_data() const; - virtual BAN::ErrorOr create_file(BAN::StringView, mode_t, uid_t, gid_t) { if (!mode().ifdir()) return BAN::Error::from_errno(ENOTDIR); ASSERT_NOT_REACHED(); } + protected: + // Directory API + 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); } + + // Link API + virtual BAN::ErrorOr link_target_impl() { return BAN::Error::from_errno(ENOTSUP); } + + // General API + virtual BAN::ErrorOr read_impl(off_t, void*, size_t) { return BAN::Error::from_errno(ENOTSUP); } + virtual BAN::ErrorOr write_impl(off_t, const void*, size_t) { return BAN::Error::from_errno(ENOTSUP); } + virtual BAN::ErrorOr truncate_impl(size_t) { return BAN::Error::from_errno(ENOTSUP); } + virtual bool has_data_impl() const { dwarnln("nonblock not supported"); return true; } + + private: + mutable RecursiveSpinLock m_lock; }; } \ No newline at end of file diff --git a/kernel/include/kernel/FS/Pipe.h b/kernel/include/kernel/FS/Pipe.h index 3c05d08d..8617c9ec 100644 --- a/kernel/include/kernel/FS/Pipe.h +++ b/kernel/include/kernel/FS/Pipe.h @@ -30,8 +30,9 @@ namespace Kernel virtual dev_t dev() const override { return 0; } // FIXME virtual dev_t rdev() const override { return 0; } // FIXME - virtual BAN::ErrorOr read(size_t, void*, size_t) override; - virtual BAN::ErrorOr write(size_t, const void*, size_t) override; + protected: + virtual BAN::ErrorOr read_impl(off_t, void*, size_t) override; + virtual BAN::ErrorOr write_impl(off_t, const void*, size_t) override; private: Pipe(const Credentials&); diff --git a/kernel/include/kernel/FS/RamFS/Inode.h b/kernel/include/kernel/FS/RamFS/Inode.h index 2bf858f1..84282a65 100644 --- a/kernel/include/kernel/FS/RamFS/Inode.h +++ b/kernel/include/kernel/FS/RamFS/Inode.h @@ -29,16 +29,15 @@ namespace Kernel virtual dev_t dev() const override { return m_inode_info.dev; } virtual dev_t rdev() const override { return m_inode_info.rdev; } - virtual BAN::ErrorOr read(size_t, void*, size_t) override; - virtual BAN::ErrorOr write(size_t, const void*, size_t) override; - - virtual BAN::ErrorOr truncate(size_t) override; - void add_link() { m_inode_info.nlink++; } protected: RamInode(RamFileSystem& fs, mode_t, uid_t, gid_t); + virtual BAN::ErrorOr read_impl(off_t, void*, size_t) override; + virtual BAN::ErrorOr write_impl(off_t, const void*, size_t) override; + virtual BAN::ErrorOr truncate_impl(size_t) override; + protected: struct FullInodeInfo { @@ -72,12 +71,13 @@ namespace Kernel static BAN::ErrorOr> create(RamFileSystem&, ino_t parent, mode_t, uid_t, gid_t); ~RamDirectoryInode() = default; - virtual BAN::ErrorOr> directory_find_inode(BAN::StringView) override; - virtual BAN::ErrorOr directory_read_next_entries(off_t, DirectoryEntryList*, size_t) override; - virtual BAN::ErrorOr create_file(BAN::StringView, mode_t, uid_t, gid_t) override; - BAN::ErrorOr add_inode(BAN::StringView, BAN::RefPtr); + protected: + virtual BAN::ErrorOr> find_inode_impl(BAN::StringView) override; + virtual BAN::ErrorOr list_next_inodes_impl(off_t, DirectoryEntryList*, size_t) override; + virtual BAN::ErrorOr create_file_impl(BAN::StringView, mode_t, uid_t, gid_t) override; + private: RamDirectoryInode(RamFileSystem&, ino_t parent, mode_t, uid_t, gid_t); @@ -105,8 +105,10 @@ namespace Kernel virtual off_t size() const override { return m_target.size(); } - virtual BAN::ErrorOr link_target() override; BAN::ErrorOr set_link_target(BAN::StringView); + + protected: + virtual BAN::ErrorOr link_target_impl() override; private: RamSymlinkInode(RamFileSystem&, mode_t, uid_t, gid_t); diff --git a/kernel/include/kernel/FS/VirtualFileSystem.h b/kernel/include/kernel/FS/VirtualFileSystem.h index ec83ec66..94e83e05 100644 --- a/kernel/include/kernel/FS/VirtualFileSystem.h +++ b/kernel/include/kernel/FS/VirtualFileSystem.h @@ -39,9 +39,9 @@ namespace Kernel MountPoint* mount_from_root_inode(BAN::RefPtr); private: - SpinLock m_lock; - FileSystem* m_root_fs = nullptr; - BAN::Vector m_mount_points; + SpinLock m_lock; + FileSystem* m_root_fs = nullptr; + BAN::Vector m_mount_points; }; } \ No newline at end of file diff --git a/kernel/include/kernel/Input/PS2Keyboard.h b/kernel/include/kernel/Input/PS2Keyboard.h index b9a86e0c..10b7a76e 100644 --- a/kernel/include/kernel/Input/PS2Keyboard.h +++ b/kernel/include/kernel/Input/PS2Keyboard.h @@ -61,7 +61,9 @@ namespace Kernel::Input public: virtual dev_t rdev() const override { return m_rdev; } - virtual BAN::ErrorOr read(size_t, void*, size_t) override; + + protected: + virtual BAN::ErrorOr read_impl(off_t, void*, size_t) override; private: const dev_t m_rdev; diff --git a/kernel/include/kernel/Storage/ATADevice.h b/kernel/include/kernel/Storage/ATADevice.h index 3fcf2cd9..e9a3a23a 100644 --- a/kernel/include/kernel/Storage/ATADevice.h +++ b/kernel/include/kernel/Storage/ATADevice.h @@ -41,7 +41,8 @@ namespace Kernel virtual gid_t gid() const override { return 0; } virtual dev_t rdev() const override { return m_rdev; } - virtual BAN::ErrorOr read(size_t, void*, size_t) override; + private: + virtual BAN::ErrorOr read_impl(off_t, void*, size_t) override; public: const dev_t m_rdev; diff --git a/kernel/include/kernel/Storage/StorageDevice.h b/kernel/include/kernel/Storage/StorageDevice.h index c0f74387..392d2c6d 100644 --- a/kernel/include/kernel/Storage/StorageDevice.h +++ b/kernel/include/kernel/Storage/StorageDevice.h @@ -50,7 +50,8 @@ namespace Kernel virtual gid_t gid() const override { return 0; } virtual dev_t rdev() const override { return m_rdev; } - virtual BAN::ErrorOr read(size_t, void*, size_t) override; + protected: + virtual BAN::ErrorOr read_impl(off_t, void*, size_t) override; private: const dev_t m_rdev; diff --git a/kernel/include/kernel/Terminal/TTY.h b/kernel/include/kernel/Terminal/TTY.h index 43040297..f98268c6 100644 --- a/kernel/include/kernel/Terminal/TTY.h +++ b/kernel/include/kernel/Terminal/TTY.h @@ -33,9 +33,6 @@ namespace Kernel virtual bool is_tty() const override { return true; } - virtual BAN::ErrorOr read(size_t, void*, size_t) override; - virtual BAN::ErrorOr write(size_t, const void*, size_t) override; - virtual uint32_t height() const = 0; virtual uint32_t width() const = 0; virtual void putchar(uint8_t ch) = 0; @@ -47,6 +44,9 @@ namespace Kernel : CharacterDevice(mode, uid, gid) { } + virtual BAN::ErrorOr read_impl(off_t, void*, size_t) override; + virtual BAN::ErrorOr write_impl(off_t, const void*, size_t) override; + virtual BAN::StringView name() const = 0; private: diff --git a/kernel/kernel/FS/Ext2/FileSystem.cpp b/kernel/kernel/FS/Ext2/FileSystem.cpp index f2679cf3..d3e9e019 100644 --- a/kernel/kernel/FS/Ext2/FileSystem.cpp +++ b/kernel/kernel/FS/Ext2/FileSystem.cpp @@ -1,5 +1,6 @@ #include #include +#include #define EXT2_DEBUG_PRINT 0 #define EXT2_VERIFY_INODE 0 @@ -135,6 +136,8 @@ namespace Kernel BAN::ErrorOr Ext2FS::create_inode(const Ext2::Inode& ext2_inode) { + LockGuard _(m_lock); + ASSERT(ext2_inode.size == 0); if (m_superblock.free_inodes_count == 0) @@ -213,6 +216,8 @@ namespace Kernel void Ext2FS::read_block(uint32_t block, BAN::Span buffer) { + LockGuard _(m_lock); + const uint32_t sector_size = m_partition.device().sector_size(); const uint32_t block_size = this->block_size(); const uint32_t sectors_per_block = block_size / sector_size; @@ -225,6 +230,8 @@ namespace Kernel void Ext2FS::write_block(uint32_t block, BAN::Span buffer) { + LockGuard _(m_lock); + const uint32_t sector_size = m_partition.device().sector_size(); const uint32_t block_size = this->block_size(); const uint32_t sectors_per_block = block_size / sector_size; @@ -237,6 +244,8 @@ namespace Kernel void Ext2FS::sync_superblock() { + LockGuard _(m_lock); + const uint32_t sector_size = m_partition.device().sector_size(); ASSERT(1024 % sector_size == 0); @@ -261,6 +270,8 @@ namespace Kernel BAN::ErrorOr Ext2FS::reserve_free_block(uint32_t primary_bgd) { + LockGuard _(m_lock); + if (m_superblock.r_blocks_count >= m_superblock.free_blocks_count) return BAN::Error::from_errno(ENOSPC); @@ -325,6 +336,8 @@ namespace Kernel BAN::ErrorOr Ext2FS::locate_inode(uint32_t ino) { + LockGuard _(m_lock); + ASSERT(ino <= superblock().inodes_count); const uint32_t block_size = this->block_size(); @@ -366,6 +379,8 @@ namespace Kernel Ext2FS::BlockLocation Ext2FS::locate_block_group_descriptior(uint32_t group_index) { + LockGuard _(m_lock); + const uint32_t block_size = this->block_size(); const uint32_t block_group_count = BAN::Math::div_round_up(superblock().inodes_count, superblock().inodes_per_group); diff --git a/kernel/kernel/FS/Ext2/Inode.cpp b/kernel/kernel/FS/Ext2/Inode.cpp index c7938f13..236fa6d9 100644 --- a/kernel/kernel/FS/Ext2/Inode.cpp +++ b/kernel/kernel/FS/Ext2/Inode.cpp @@ -159,7 +159,7 @@ namespace Kernel return result; } - BAN::ErrorOr Ext2Inode::link_target() + BAN::ErrorOr Ext2Inode::link_target_impl() { ASSERT(mode().iflnk()); if (m_inode.size < sizeof(m_inode.block)) @@ -167,12 +167,15 @@ namespace Kernel return BAN::Error::from_errno(ENOTSUP); } - BAN::ErrorOr Ext2Inode::read(size_t offset, void* buffer, size_t count) + BAN::ErrorOr Ext2Inode::read_impl(off_t offset, void* buffer, size_t count) { // FIXME: update atime if needed - if (mode().ifdir()) - return BAN::Error::from_errno(EISDIR); + ASSERT(!mode().ifdir()); + ASSERT(offset >= 0); + + if (offset >= UINT32_MAX || count >= UINT32_MAX || offset + count >= UINT32_MAX) + return BAN::Error::from_errno(EOVERFLOW); if (offset >= m_inode.size) return 0; @@ -204,16 +207,18 @@ namespace Kernel return n_read; } - BAN::ErrorOr Ext2Inode::write(size_t offset, const void* buffer, size_t count) + BAN::ErrorOr Ext2Inode::write_impl(off_t offset, const void* buffer, size_t count) { - if (offset >= UINT32_MAX || count == UINT32_MAX || offset + count >= UINT32_MAX) + // FIXME: update atime if needed + + ASSERT(!mode().ifdir()); + ASSERT(offset >= 0); + + if (offset >= UINT32_MAX || count >= UINT32_MAX || offset + count >= UINT32_MAX) return BAN::Error::from_errno(EOVERFLOW); - if (mode().ifdir()) - return BAN::Error::from_errno(EISDIR); - if (m_inode.size < offset + count) - TRY(truncate(offset + count)); + TRY(truncate_impl(offset + count)); const uint32_t block_size = blksize(); @@ -222,6 +227,8 @@ namespace Kernel const uint8_t* u8buffer = (const uint8_t*)buffer; + size_t written = 0; + // Write partial block if (offset % block_size) { @@ -229,7 +236,7 @@ namespace Kernel uint32_t block_offset = offset % block_size; uint32_t data_block_index = TRY(this->data_block_index(block_index)); - uint32_t to_copy = BAN::Math::min(block_size - block_offset, count); + uint32_t to_copy = BAN::Math::min(block_size - block_offset, written); m_fs.read_block(data_block_index, block_buffer.span()); memcpy(block_buffer.data() + block_offset, buffer, to_copy); @@ -237,10 +244,10 @@ namespace Kernel u8buffer += to_copy; offset += to_copy; - count -= to_copy; + written -= to_copy; } - while (count >= block_size) + while (written >= block_size) { uint32_t data_block_index = TRY(this->data_block_index(offset / block_size)); @@ -248,22 +255,22 @@ namespace Kernel u8buffer += block_size; offset += block_size; - count -= block_size; + written -= block_size; } - if (count > 0) + if (written > 0) { uint32_t data_block_index = TRY(this->data_block_index(offset / block_size)); m_fs.read_block(data_block_index, block_buffer.span()); - memcpy(block_buffer.data(), u8buffer, count); + memcpy(block_buffer.data(), u8buffer, written); m_fs.write_block(data_block_index, block_buffer.span()); } return count; } - BAN::ErrorOr Ext2Inode::truncate(size_t new_size) + BAN::ErrorOr Ext2Inode::truncate_impl(size_t new_size) { if (m_inode.size == new_size) return {}; @@ -304,10 +311,10 @@ namespace Kernel return {}; } - BAN::ErrorOr Ext2Inode::directory_read_next_entries(off_t offset, DirectoryEntryList* list, size_t list_size) + BAN::ErrorOr Ext2Inode::list_next_inodes_impl(off_t offset, DirectoryEntryList* list, size_t list_size) { - if (!mode().ifdir()) - return BAN::Error::from_errno(ENOTDIR); + ASSERT(mode().ifdir()); + ASSERT(offset >= 0); const uint32_t data_block_count = blocks(); if (offset >= data_block_count) @@ -369,7 +376,7 @@ namespace Kernel return {}; } - BAN::ErrorOr Ext2Inode::create_file(BAN::StringView name, mode_t mode, uid_t uid, gid_t gid) + BAN::ErrorOr Ext2Inode::create_file_impl(BAN::StringView name, mode_t mode, uid_t uid, gid_t gid) { if (!this->mode().ifdir()) return BAN::Error::from_errno(ENOTDIR); @@ -386,7 +393,7 @@ namespace Kernel return BAN::Error::from_errno(ENOTSUP); } - auto error_or = directory_find_inode(name); + auto error_or = find_inode_impl(name); if (!error_or.is_error()) return BAN::Error::from_errno(EEXISTS); if (error_or.error().get_error_code() != ENOENT) @@ -424,7 +431,7 @@ namespace Kernel auto write_inode = [&](uint32_t entry_offset, uint32_t entry_rec_len) { - auto typed_mode = Mode { mode }; + auto typed_mode = Mode(mode); uint8_t file_type = (m_fs.superblock().rev_level == Ext2::Enum::GOOD_OLD_REV) ? 0 : typed_mode.ifreg() ? Ext2::Enum::REG_FILE : typed_mode.ifdir() ? Ext2::Enum::DIR @@ -542,10 +549,9 @@ needs_new_block: return {}; } - BAN::ErrorOr> Ext2Inode::directory_find_inode(BAN::StringView file_name) + BAN::ErrorOr> Ext2Inode::find_inode_impl(BAN::StringView file_name) { - if (!mode().ifdir()) - return BAN::Error::from_errno(ENOTDIR); + ASSERT(mode().ifdir()); const uint32_t block_size = blksize(); const uint32_t data_block_count = blocks(); diff --git a/kernel/kernel/FS/Inode.cpp b/kernel/kernel/FS/Inode.cpp index efc9dcee..91d85061 100644 --- a/kernel/kernel/FS/Inode.cpp +++ b/kernel/kernel/FS/Inode.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include @@ -55,4 +57,74 @@ namespace Kernel return true; } + BAN::ErrorOr> Inode::find_inode(BAN::StringView name) + { + LockGuard _(m_lock); + Thread::TerminateBlocker blocker(Thread::current()); + if (!mode().ifdir()) + return BAN::Error::from_errno(ENOTDIR); + return find_inode_impl(name); + } + + BAN::ErrorOr Inode::list_next_inodes(off_t offset, DirectoryEntryList* list, size_t list_len) + { + LockGuard _(m_lock); + Thread::TerminateBlocker blocker(Thread::current()); + if (!mode().ifdir()) + return BAN::Error::from_errno(ENOTDIR); + return list_next_inodes_impl(offset, list, list_len); + } + + BAN::ErrorOr Inode::create_file(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); + return create_file_impl(name, mode, uid, gid); + } + + BAN::ErrorOr Inode::link_target() + { + LockGuard _(m_lock); + Thread::TerminateBlocker blocker(Thread::current()); + if (!mode().iflnk()) + return BAN::Error::from_errno(EINVAL); + return link_target_impl(); + } + + BAN::ErrorOr Inode::read(off_t offset, void* buffer, size_t bytes) + { + LockGuard _(m_lock); + Thread::TerminateBlocker blocker(Thread::current()); + if (mode().ifdir()) + return BAN::Error::from_errno(EISDIR); + return read_impl(offset, buffer, bytes); + } + + BAN::ErrorOr Inode::write(off_t offset, const void* buffer, size_t bytes) + { + LockGuard _(m_lock); + Thread::TerminateBlocker blocker(Thread::current()); + if (mode().ifdir()) + return BAN::Error::from_errno(EISDIR); + return write_impl(offset, buffer, bytes); + } + + BAN::ErrorOr Inode::truncate(size_t size) + { + LockGuard _(m_lock); + Thread::TerminateBlocker blocker(Thread::current()); + if (mode().ifdir()) + return BAN::Error::from_errno(EISDIR); + return truncate_impl(size); + } + + bool Inode::has_data() const + { + LockGuard _(m_lock); + Thread::TerminateBlocker blocker(Thread::current()); + return has_data_impl(); + } + } \ No newline at end of file diff --git a/kernel/kernel/FS/Pipe.cpp b/kernel/kernel/FS/Pipe.cpp index 1be5f314..89784235 100644 --- a/kernel/kernel/FS/Pipe.cpp +++ b/kernel/kernel/FS/Pipe.cpp @@ -39,9 +39,9 @@ namespace Kernel m_semaphore.unblock(); } - BAN::ErrorOr Pipe::read(size_t, void* buffer, size_t count) + BAN::ErrorOr Pipe::read_impl(off_t, void* buffer, size_t count) { - m_lock.lock(); + LockGuard _(m_lock); while (m_buffer.empty()) { if (m_writing_count == 0) @@ -61,12 +61,10 @@ namespace Kernel m_semaphore.unblock(); - m_lock.unlock(); - return to_copy; } - BAN::ErrorOr Pipe::write(size_t, const void* buffer, size_t count) + BAN::ErrorOr Pipe::write_impl(off_t, const void* buffer, size_t count) { LockGuard _(m_lock); diff --git a/kernel/kernel/FS/RamFS/Inode.cpp b/kernel/kernel/FS/RamFS/Inode.cpp index 936efb03..e5d8cc78 100644 --- a/kernel/kernel/FS/RamFS/Inode.cpp +++ b/kernel/kernel/FS/RamFS/Inode.cpp @@ -13,7 +13,7 @@ namespace Kernel BAN::ErrorOr> RamInode::create(RamFileSystem& fs, mode_t mode, uid_t uid, gid_t gid) { - ASSERT(Mode{ mode }.ifreg()); + ASSERT(Mode(mode).ifreg()); auto* ram_inode = new RamInode(fs, mode, uid, gid); if (ram_inode == nullptr) return BAN::Error::from_errno(ENOMEM); @@ -40,26 +40,26 @@ namespace Kernel m_inode_info.rdev = 0; } - BAN::ErrorOr RamInode::read(size_t offset, void* buffer, size_t bytes) + BAN::ErrorOr RamInode::read_impl(off_t offset, void* buffer, size_t bytes) { - if (offset >= (size_t)size()) + ASSERT(offset >= 0); + if (offset >= size()) return 0; - size_t to_copy = BAN::Math::min(m_inode_info.size - offset, bytes); memcpy(buffer, m_data.data(), to_copy); - return to_copy; } - BAN::ErrorOr RamInode::write(size_t offset, const void* buffer, size_t bytes) + BAN::ErrorOr RamInode::write_impl(off_t offset, const void* buffer, size_t bytes) { + ASSERT(offset >= 0); if (offset + bytes > (size_t)size()) - TRY(truncate(offset + bytes)); + TRY(truncate_impl(offset + bytes)); memcpy(m_data.data() + offset, buffer, bytes); return bytes; } - BAN::ErrorOr RamInode::truncate(size_t new_size) + BAN::ErrorOr RamInode::truncate_impl(size_t new_size) { TRY(m_data.resize(new_size, 0)); m_inode_info.size = m_data.size(); @@ -75,7 +75,7 @@ namespace Kernel BAN::ErrorOr> RamDirectoryInode::create(RamFileSystem& fs, ino_t parent, mode_t mode, uid_t uid, gid_t gid) { - ASSERT(Mode{ mode }.ifdir()); + ASSERT(Mode(mode).ifdir()); auto* ram_inode = new RamDirectoryInode(fs, parent, mode, uid, gid); if (ram_inode == nullptr) return BAN::Error::from_errno(ENOMEM); @@ -101,7 +101,7 @@ namespace Kernel } } - BAN::ErrorOr> RamDirectoryInode::directory_find_inode(BAN::StringView name) + BAN::ErrorOr> RamDirectoryInode::find_inode_impl(BAN::StringView name) { if (name == "."sv) { @@ -127,8 +127,10 @@ namespace Kernel return BAN::Error::from_errno(ENOENT); } - BAN::ErrorOr RamDirectoryInode::directory_read_next_entries(off_t offset, DirectoryEntryList* list, size_t list_size) + BAN::ErrorOr RamDirectoryInode::list_next_inodes_impl(off_t offset, DirectoryEntryList* list, size_t list_size) { + ASSERT(offset >= 0); + // TODO: don't require memory for all entries on single call if (offset != 0) { @@ -175,12 +177,12 @@ namespace Kernel return {}; } - BAN::ErrorOr RamDirectoryInode::create_file(BAN::StringView name, mode_t mode, uid_t uid, gid_t gid) + BAN::ErrorOr RamDirectoryInode::create_file_impl(BAN::StringView name, mode_t mode, uid_t uid, gid_t gid) { BAN::RefPtr inode; - if (Mode{ mode }.ifreg()) + if (Mode(mode).ifreg()) inode = TRY(RamInode::create(m_fs, mode, uid, gid)); - else if (Mode{ mode }.ifdir()) + else if (Mode(mode).ifdir()) inode = TRY(RamDirectoryInode::create(m_fs, ino(), mode, uid, gid)); else ASSERT_NOT_REACHED(); @@ -222,7 +224,7 @@ namespace Kernel BAN::ErrorOr> RamSymlinkInode::create(RamFileSystem& fs, BAN::StringView target, mode_t mode, uid_t uid, gid_t gid) { - ASSERT(Mode{ mode }.iflnk()); + ASSERT(Mode(mode).iflnk()); auto* ram_inode = new RamSymlinkInode(fs, mode, uid, gid); if (ram_inode == nullptr) return BAN::Error::from_errno(ENOMEM); @@ -235,7 +237,7 @@ namespace Kernel : RamInode(fs, mode, uid, gid) { } - BAN::ErrorOr RamSymlinkInode::link_target() + BAN::ErrorOr RamSymlinkInode::link_target_impl() { BAN::String result; TRY(result.append(m_target)); diff --git a/kernel/kernel/FS/VirtualFileSystem.cpp b/kernel/kernel/FS/VirtualFileSystem.cpp index 32c978d8..f69d70a4 100644 --- a/kernel/kernel/FS/VirtualFileSystem.cpp +++ b/kernel/kernel/FS/VirtualFileSystem.cpp @@ -22,7 +22,7 @@ namespace Kernel ASSERT(root.size() >= 5 && root.substring(0, 5) == "/dev/"sv);; root = root.substring(5); - auto partition_inode = MUST(DevFileSystem::get().root_inode()->directory_find_inode(root)); + auto partition_inode = MUST(DevFileSystem::get().root_inode()->find_inode(root)); s_instance->m_root_fs = MUST(Ext2FS::create(*(Partition*)partition_inode.ptr())); Credentials root_creds { 0, 0, 0, 0 }; @@ -119,9 +119,9 @@ namespace Kernel else if (path_part == ".."sv) { if (auto* mount_point = mount_from_root_inode(inode)) - inode = TRY(mount_point->host.inode->directory_find_inode(".."sv)); + inode = TRY(mount_point->host.inode->find_inode(".."sv)); else - inode = TRY(inode->directory_find_inode(".."sv)); + inode = TRY(inode->find_inode(".."sv)); if (!canonical_path.empty()) { @@ -136,7 +136,7 @@ namespace Kernel if (!inode->can_access(credentials, O_SEARCH)) return BAN::Error::from_errno(EACCES); - inode = TRY(inode->directory_find_inode(path_part)); + inode = TRY(inode->find_inode(path_part)); if (auto* mount_point = mount_from_host_inode(inode)) inode = mount_point->target->root_inode(); diff --git a/kernel/kernel/Input/PS2Keyboard.cpp b/kernel/kernel/Input/PS2Keyboard.cpp index 566e0ffb..ab3d7a20 100644 --- a/kernel/kernel/Input/PS2Keyboard.cpp +++ b/kernel/kernel/Input/PS2Keyboard.cpp @@ -242,7 +242,7 @@ namespace Kernel::Input append_command_queue(Command::SET_LEDS, new_leds); } - BAN::ErrorOr PS2Keyboard::read(size_t, void* buffer, size_t size) + BAN::ErrorOr PS2Keyboard::read_impl(off_t, void* buffer, size_t size) { if (size < sizeof(KeyEvent)) return BAN::Error::from_errno(ENOBUFS); diff --git a/kernel/kernel/OpenFileDescriptorSet.cpp b/kernel/kernel/OpenFileDescriptorSet.cpp index 6c79938c..4c9602b5 100644 --- a/kernel/kernel/OpenFileDescriptorSet.cpp +++ b/kernel/kernel/OpenFileDescriptorSet.cpp @@ -290,7 +290,7 @@ namespace Kernel auto& open_file = m_open_files[fd]; if (!(open_file->flags & O_RDONLY)) return BAN::Error::from_errno(EACCES); - TRY(open_file->inode->directory_read_next_entries(open_file->offset, list, list_size)); + TRY(open_file->inode->list_next_inodes(open_file->offset, list, list_size)); open_file->offset++; return {}; } diff --git a/kernel/kernel/Storage/ATADevice.cpp b/kernel/kernel/Storage/ATADevice.cpp index 1186e895..744cb3d9 100644 --- a/kernel/kernel/Storage/ATADevice.cpp +++ b/kernel/kernel/Storage/ATADevice.cpp @@ -72,11 +72,12 @@ namespace Kernel return {}; } - BAN::ErrorOr ATADevice::read(size_t offset, void* buffer, size_t bytes) + BAN::ErrorOr ATADevice::read_impl(off_t offset, void* buffer, size_t bytes) { + ASSERT(offset >= 0); if (offset % sector_size() || bytes % sector_size()) return BAN::Error::from_errno(EINVAL); - if (offset == total_size()) + if ((size_t)offset == total_size()) return 0; TRY(read_sectors(offset / sector_size(), bytes / sector_size(), (uint8_t*)buffer)); return bytes; diff --git a/kernel/kernel/Storage/StorageDevice.cpp b/kernel/kernel/Storage/StorageDevice.cpp index f59c32ab..01ea322b 100644 --- a/kernel/kernel/Storage/StorageDevice.cpp +++ b/kernel/kernel/Storage/StorageDevice.cpp @@ -231,8 +231,10 @@ namespace Kernel return {}; } - BAN::ErrorOr Partition::read(size_t offset, void* buffer, size_t bytes) + BAN::ErrorOr Partition::read_impl(off_t offset, void* buffer, size_t bytes) { + ASSERT(offset >= 0); + if (offset % m_device.sector_size() || bytes % m_device.sector_size()) return BAN::Error::from_errno(ENOTSUP); diff --git a/kernel/kernel/Terminal/TTY.cpp b/kernel/kernel/Terminal/TTY.cpp index 472343ce..2a7f1734 100644 --- a/kernel/kernel/Terminal/TTY.cpp +++ b/kernel/kernel/Terminal/TTY.cpp @@ -26,7 +26,7 @@ namespace Kernel { s_tty = this; - auto inode_or_error = DevFileSystem::get().root_inode()->directory_find_inode("tty"); + auto inode_or_error = DevFileSystem::get().root_inode()->find_inode("tty"); if (inode_or_error.is_error()) { if (inode_or_error.error().get_error_code() == ENOENT) @@ -249,7 +249,7 @@ namespace Kernel } } - BAN::ErrorOr TTY::read(size_t, void* buffer, size_t count) + BAN::ErrorOr TTY::read_impl(off_t, void* buffer, size_t count) { LockGuard _(m_lock); while (!m_output.flush) @@ -279,7 +279,7 @@ namespace Kernel return to_copy; } - BAN::ErrorOr TTY::write(size_t, const void* buffer, size_t count) + BAN::ErrorOr TTY::write_impl(off_t, const void* buffer, size_t count) { LockGuard _(m_lock); for (size_t i = 0; i < count; i++) diff --git a/kernel/kernel/kernel.cpp b/kernel/kernel/kernel.cpp index 35840d7a..04486921 100644 --- a/kernel/kernel/kernel.cpp +++ b/kernel/kernel/kernel.cpp @@ -144,10 +144,6 @@ extern "C" void kernel_main() auto vtty = MUST(VirtualTTY::create(terminal_driver)); dprintln("Virtual TTY initialized"); - auto console = MUST(DevFileSystem::get().root_inode()->directory_find_inode(cmdline.console)); - ASSERT(console->is_tty()); - ((TTY*)console.ptr())->set_as_current(); - MUST(Scheduler::initialize()); dprintln("Scheduler initialized"); @@ -165,6 +161,10 @@ static void init2(void*) dprintln("Scheduler started"); + auto console = MUST(DevFileSystem::get().root_inode()->find_inode(cmdline.console)); + ASSERT(console->is_tty()); + ((TTY*)console.ptr())->set_as_current(); + DevFileSystem::get().initialize_device_updater(); PCI::initialize();