From 5159f641174c421ef9250abdc7026a42d52c54b8 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Tue, 7 Sep 2021 20:31:30 +0200 Subject: [PATCH] Kernel: Stop leaking TmpFS inodes TmpFS inodes rely on the call to Inode::one_ref_left() to unregister themselves from the inode cache in TmpFS. When moving various kernel classes to ListedRefCounted for safe unref() while participating on lists, I forgot to make ListedRefCounted check for (and call) one_ref_left() & will_be_destroyed() on the CRTP class. --- Kernel/Library/ListedRefCounted.h | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/Kernel/Library/ListedRefCounted.h b/Kernel/Library/ListedRefCounted.h index e9a98e8731..d0cabd75ba 100644 --- a/Kernel/Library/ListedRefCounted.h +++ b/Kernel/Library/ListedRefCounted.h @@ -20,15 +20,19 @@ class ListedRefCounted : public RefCountedBase { public: bool unref() const { - bool did_hit_zero = T::all_instances().with([&](auto& list) { - if (deref_base()) - return false; - list.remove(const_cast(static_cast(*this))); - return true; + auto new_ref_count = T::all_instances().with([&](auto& list) { + auto new_ref_count = deref_base(); + if (new_ref_count == 0) + list.remove(const_cast(static_cast(*this))); + return new_ref_count; }); - if (did_hit_zero) + if (new_ref_count == 0) { + call_will_be_destroyed_if_present(static_cast(this)); delete const_cast(static_cast(this)); - return did_hit_zero; + } else if (new_ref_count == 1) { + call_one_ref_left_if_present(static_cast(this)); + } + return new_ref_count == 0; } };