From e8c9b5e8701527402af659da5db4eb483fcc2de8 Mon Sep 17 00:00:00 2001 From: Brian Gianforcaro Date: Wed, 5 Aug 2020 01:00:18 -0700 Subject: [PATCH] Kernel: Make Inode::directory_entry_count errors observable. Certain implementations of Inode::directory_entry_count were calling functions which returned errors, but had no way of surfacing them. Switch the return type to KResultOr and start observing these error paths. --- Kernel/FileSystem/DevPtsFS.cpp | 2 +- Kernel/FileSystem/DevPtsFS.h | 2 +- Kernel/FileSystem/Ext2FileSystem.cpp | 2 +- Kernel/FileSystem/Ext2FileSystem.h | 2 +- Kernel/FileSystem/Inode.h | 2 +- Kernel/FileSystem/Plan9FileSystem.cpp | 8 ++++++-- Kernel/FileSystem/Plan9FileSystem.h | 2 +- Kernel/FileSystem/ProcFS.cpp | 12 ++++++++---- Kernel/FileSystem/ProcFS.h | 4 ++-- Kernel/FileSystem/TmpFS.cpp | 2 +- Kernel/FileSystem/TmpFS.h | 2 +- Kernel/FileSystem/VirtualFileSystem.cpp | 6 +++++- 12 files changed, 29 insertions(+), 17 deletions(-) diff --git a/Kernel/FileSystem/DevPtsFS.cpp b/Kernel/FileSystem/DevPtsFS.cpp index 67e1e1525c0..175c7075bf0 100644 --- a/Kernel/FileSystem/DevPtsFS.cpp +++ b/Kernel/FileSystem/DevPtsFS.cpp @@ -153,7 +153,7 @@ KResult DevPtsFSInode::traverse_as_directory(Function DevPtsFSInode::directory_entry_count() const { ASSERT(identifier().index() == 1); diff --git a/Kernel/FileSystem/DevPtsFS.h b/Kernel/FileSystem/DevPtsFS.h index 214f3d38660..202a0a6d7d5 100644 --- a/Kernel/FileSystem/DevPtsFS.h +++ b/Kernel/FileSystem/DevPtsFS.h @@ -76,7 +76,7 @@ private: virtual KResultOr> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override; virtual KResult add_child(Inode&, const StringView& name, mode_t) override; virtual KResult remove_child(const StringView& name) override; - virtual size_t directory_entry_count() const override; + virtual KResultOr directory_entry_count() const override; virtual KResult chmod(mode_t) override; virtual KResult chown(uid_t, gid_t) override; diff --git a/Kernel/FileSystem/Ext2FileSystem.cpp b/Kernel/FileSystem/Ext2FileSystem.cpp index bf206140afe..253f66e223d 100644 --- a/Kernel/FileSystem/Ext2FileSystem.cpp +++ b/Kernel/FileSystem/Ext2FileSystem.cpp @@ -1562,7 +1562,7 @@ void Ext2FS::uncache_inode(InodeIndex index) m_inode_cache.remove(index); } -size_t Ext2FSInode::directory_entry_count() const +KResultOr Ext2FSInode::directory_entry_count() const { ASSERT(is_directory()); LOCKER(m_lock); diff --git a/Kernel/FileSystem/Ext2FileSystem.h b/Kernel/FileSystem/Ext2FileSystem.h index cdb67aba77d..db3ddaaac5e 100644 --- a/Kernel/FileSystem/Ext2FileSystem.h +++ b/Kernel/FileSystem/Ext2FileSystem.h @@ -71,7 +71,7 @@ private: virtual int set_mtime(time_t) override; virtual KResult increment_link_count() override; virtual KResult decrement_link_count() override; - virtual size_t directory_entry_count() const override; + virtual KResultOr directory_entry_count() const override; virtual KResult chmod(mode_t) override; virtual KResult chown(uid_t, gid_t) override; virtual KResult truncate(u64) override; diff --git a/Kernel/FileSystem/Inode.h b/Kernel/FileSystem/Inode.h index d6a13f01fb4..ee388b5c73a 100644 --- a/Kernel/FileSystem/Inode.h +++ b/Kernel/FileSystem/Inode.h @@ -76,7 +76,7 @@ public: virtual KResultOr> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) = 0; virtual KResult add_child(Inode&, const StringView& name, mode_t) = 0; virtual KResult remove_child(const StringView& name) = 0; - virtual size_t directory_entry_count() const = 0; + virtual KResultOr directory_entry_count() const = 0; virtual KResult chmod(mode_t) = 0; virtual KResult chown(uid_t, gid_t) = 0; virtual KResult truncate(u64) { return KSuccess; } diff --git a/Kernel/FileSystem/Plan9FileSystem.cpp b/Kernel/FileSystem/Plan9FileSystem.cpp index 3c348628c26..ddd2c6b9aa0 100644 --- a/Kernel/FileSystem/Plan9FileSystem.cpp +++ b/Kernel/FileSystem/Plan9FileSystem.cpp @@ -794,13 +794,17 @@ void Plan9FSInode::flush_metadata() // Do nothing. } -size_t Plan9FSInode::directory_entry_count() const +KResultOr Plan9FSInode::directory_entry_count() const { size_t count = 0; - traverse_as_directory([&count](const FS::DirectoryEntry&) { + KResult result = traverse_as_directory([&count](const FS::DirectoryEntry&) { count++; return true; }); + + if (result.is_error()) + return result; + return count; } diff --git a/Kernel/FileSystem/Plan9FileSystem.h b/Kernel/FileSystem/Plan9FileSystem.h index cf40c17a408..9e922ca7fab 100644 --- a/Kernel/FileSystem/Plan9FileSystem.h +++ b/Kernel/FileSystem/Plan9FileSystem.h @@ -131,7 +131,7 @@ public: virtual KResultOr> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override; virtual KResult add_child(Inode&, const StringView& name, mode_t) override; virtual KResult remove_child(const StringView& name) override; - virtual size_t directory_entry_count() const override; + virtual KResultOr directory_entry_count() const override; virtual KResult chmod(mode_t) override; virtual KResult chown(uid_t, gid_t) override; virtual KResult truncate(u64) override; diff --git a/Kernel/FileSystem/ProcFS.cpp b/Kernel/FileSystem/ProcFS.cpp index 275b9eac42e..99bb40ee3ae 100644 --- a/Kernel/FileSystem/ProcFS.cpp +++ b/Kernel/FileSystem/ProcFS.cpp @@ -1515,10 +1515,10 @@ RefPtr ProcFSProxyInode::lookup(StringView name) return m_fd->inode()->lookup(name); } -size_t ProcFSProxyInode::directory_entry_count() const +KResultOr ProcFSProxyInode::directory_entry_count() const { if (!m_fd->inode()) - return 0; + return KResult(-EINVAL); return m_fd->inode()->directory_entry_count(); } @@ -1538,14 +1538,18 @@ KResult ProcFSInode::remove_child(const StringView& name) return KResult(-EPERM); } -size_t ProcFSInode::directory_entry_count() const +KResultOr ProcFSInode::directory_entry_count() const { ASSERT(is_directory()); size_t count = 0; - traverse_as_directory([&count](const FS::DirectoryEntry&) { + KResult result = traverse_as_directory([&count](const FS::DirectoryEntry&) { ++count; return true; }); + + if (result.is_error()) + return result; + return count; } diff --git a/Kernel/FileSystem/ProcFS.h b/Kernel/FileSystem/ProcFS.h index e57b45d85c8..4d79096b512 100644 --- a/Kernel/FileSystem/ProcFS.h +++ b/Kernel/FileSystem/ProcFS.h @@ -105,7 +105,7 @@ private: virtual KResultOr> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override; virtual KResult add_child(Inode&, const StringView& name, mode_t) override; virtual KResult remove_child(const StringView& name) override; - virtual size_t directory_entry_count() const override; + virtual KResultOr directory_entry_count() const override; virtual KResult chmod(mode_t) override; virtual KResult chown(uid_t, gid_t) override; virtual KResultOr> resolve_as_link(Custody& base, RefPtr* out_parent = nullptr, int options = 0, int symlink_recursion_level = 0) const override; @@ -132,7 +132,7 @@ private: virtual KResultOr> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override; virtual KResult add_child(Inode&, const StringView& name, mode_t) override; virtual KResult remove_child(const StringView& name) override; - virtual size_t directory_entry_count() const override; + virtual KResultOr directory_entry_count() const override; virtual KResult chmod(mode_t) override { return KResult(-EINVAL); } virtual KResult chown(uid_t, gid_t) override { return KResult(-EINVAL); } virtual KResultOr> resolve_as_link(Custody&, RefPtr*, int, int) const override { ASSERT_NOT_REACHED(); } diff --git a/Kernel/FileSystem/TmpFS.cpp b/Kernel/FileSystem/TmpFS.cpp index 6cd82b14060..cb72bfc5376 100644 --- a/Kernel/FileSystem/TmpFS.cpp +++ b/Kernel/FileSystem/TmpFS.cpp @@ -219,7 +219,7 @@ RefPtr TmpFSInode::lookup(StringView name) return fs().get_inode(it->value.entry.inode); } -size_t TmpFSInode::directory_entry_count() const +KResultOr TmpFSInode::directory_entry_count() const { LOCKER(m_lock, Lock::Mode::Shared); ASSERT(is_directory()); diff --git a/Kernel/FileSystem/TmpFS.h b/Kernel/FileSystem/TmpFS.h index 738851b3696..db28d223b07 100644 --- a/Kernel/FileSystem/TmpFS.h +++ b/Kernel/FileSystem/TmpFS.h @@ -83,7 +83,7 @@ public: virtual KResultOr> create_child(const String& name, mode_t, dev_t, uid_t, gid_t) override; virtual KResult add_child(Inode&, const StringView& name, mode_t) override; virtual KResult remove_child(const StringView& name) override; - virtual size_t directory_entry_count() const override; + virtual KResultOr directory_entry_count() const override; virtual KResult chmod(mode_t) override; virtual KResult chown(uid_t, gid_t) override; virtual KResult truncate(u64) override; diff --git a/Kernel/FileSystem/VirtualFileSystem.cpp b/Kernel/FileSystem/VirtualFileSystem.cpp index d6aec7a730a..ab11ae36f5d 100644 --- a/Kernel/FileSystem/VirtualFileSystem.cpp +++ b/Kernel/FileSystem/VirtualFileSystem.cpp @@ -731,7 +731,11 @@ KResult VFS::rmdir(StringView path, Custody& base) if (!parent_inode.metadata().may_write(*Process::current())) return KResult(-EACCES); - if (inode.directory_entry_count() != 2) + KResultOr dir_count_result = inode.directory_entry_count(); + if (dir_count_result.is_error()) + return dir_count_result.result(); + + if (dir_count_result.value() != 2) return KResult(-ENOTEMPTY); if (custody.is_readonly())