diff --git a/AK/Retainable.h b/AK/Retainable.h index 32c4a9b7a0..05757bea7e 100644 --- a/AK/Retainable.h +++ b/AK/Retainable.h @@ -1,39 +1,54 @@ #pragma once #include "Assertions.h" +#include "StdLibExtras.h" namespace AK { +template +constexpr auto call_will_be_destroyed_if_present(T* object) -> decltype(object->will_be_destroyed(), TrueType { }) +{ + object->will_be_destroyed(); + return { }; +} + +constexpr auto call_will_be_destroyed_if_present(...) -> FalseType +{ + return { }; +} + template class Retainable { public: void retain() { - ASSERT(m_retainCount); - ++m_retainCount; + ASSERT(m_retain_count); + ++m_retain_count; } void release() { - ASSERT(m_retainCount); - if (!--m_retainCount) + ASSERT(m_retain_count); + if (!--m_retain_count) { + call_will_be_destroyed_if_present(static_cast(this)); delete static_cast(this); + } } - int retainCount() const + int retain_count() const { - return m_retainCount; + return m_retain_count; } protected: Retainable() { } ~Retainable() { - ASSERT(!m_retainCount); + ASSERT(!m_retain_count); } private: - int m_retainCount { 1 }; + int m_retain_count { 1 }; }; } diff --git a/Kernel/ProcFileSystem.cpp b/Kernel/ProcFileSystem.cpp index 71dd6d6a35..7ea66052e5 100644 --- a/Kernel/ProcFileSystem.cpp +++ b/Kernel/ProcFileSystem.cpp @@ -83,7 +83,7 @@ ByteBuffer procfs$pid_vmo(Process& process) region->vmo().is_anonymous() ? "anonymous" : "file-backed", region->vmo().name().characters(), ®ion->vmo(), - region->vmo().retainCount()); + region->vmo().retain_count()); for (size_t i = 0; i < region->vmo().page_count(); ++i) { auto& physical_page = region->vmo().physical_pages()[i]; ptr += ksprintf(ptr, "P%x%s(%u) ", @@ -205,7 +205,7 @@ ByteBuffer procfs$mm() ptr += ksprintf(ptr, "VMO: %p %s(%u): p:%4u %s\n", vmo, vmo->is_anonymous() ? "anon" : "file", - vmo->retainCount(), + vmo->retain_count(), vmo->page_count(), vmo->name().characters()); } diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 04415ea033..c9b3c18f89 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -1104,7 +1104,7 @@ int Process::sys$utime(const char* pathname, const Unix::utimbuf* buf) atime = now; } inode.set_atime(atime); - inode.set_mtime(atime); + inode.set_mtime(mtime); inode.flush_metadata(); return 0; } diff --git a/VirtualFileSystem/Ext2FileSystem.cpp b/VirtualFileSystem/Ext2FileSystem.cpp index 8321284da9..aae08f7eb2 100644 --- a/VirtualFileSystem/Ext2FileSystem.cpp +++ b/VirtualFileSystem/Ext2FileSystem.cpp @@ -317,6 +317,7 @@ void Ext2FSInode::flush_metadata() m_raw_inode.i_dtime = m_metadata.dtime; m_raw_inode.i_blocks = m_metadata.blockCount; fs().write_ext2_inode(index(), m_raw_inode); + set_metadata_dirty(false); } RetainPtr Ext2FS::get_inode(InodeIdentifier inode) const diff --git a/VirtualFileSystem/FileSystem.cpp b/VirtualFileSystem/FileSystem.cpp index a4b986f51c..f990a11f87 100644 --- a/VirtualFileSystem/FileSystem.cpp +++ b/VirtualFileSystem/FileSystem.cpp @@ -129,6 +129,12 @@ Inode::~Inode() { } +void Inode::will_be_destroyed() +{ + if (m_metadata_dirty) + flush_metadata(); +} + int Inode::set_atime(Unix::time_t ts) { if (fs().is_readonly()) @@ -136,7 +142,7 @@ int Inode::set_atime(Unix::time_t ts) if (m_metadata.atime == ts) return 0; m_metadata.atime = ts; - m_dirty = true; + m_metadata_dirty = true; return 0; } @@ -147,7 +153,7 @@ int Inode::set_ctime(Unix::time_t ts) if (m_metadata.ctime == ts) return 0; m_metadata.ctime = ts; - m_dirty = true; + m_metadata_dirty = true; return 0; } @@ -158,6 +164,6 @@ int Inode::set_mtime(Unix::time_t ts) if (m_metadata.mtime == ts) return 0; m_metadata.mtime = ts; - m_dirty = true; + m_metadata_dirty = true; return 0; } diff --git a/VirtualFileSystem/FileSystem.h b/VirtualFileSystem/FileSystem.h index a675c7dc70..726066e2be 100644 --- a/VirtualFileSystem/FileSystem.h +++ b/VirtualFileSystem/FileSystem.h @@ -87,7 +87,7 @@ public: virtual InodeIdentifier lookup(const String& name) = 0; virtual String reverse_lookup(InodeIdentifier) = 0; - bool is_dirty() const { return m_dirty; } + bool is_metadata_dirty() const { return m_metadata_dirty; } int set_atime(Unix::time_t); int set_ctime(Unix::time_t); @@ -95,6 +95,8 @@ public: virtual void flush_metadata() = 0; + void will_be_destroyed(); + protected: Inode(FS& fs, unsigned index) : m_fs(fs) @@ -103,13 +105,13 @@ protected: } virtual void populate_metadata() const = 0; - void set_dirty(bool b) { m_dirty = b; } + void set_metadata_dirty(bool b) { m_metadata_dirty = b; } mutable InodeMetadata m_metadata; private: FS& m_fs; unsigned m_index { 0 }; - bool m_dirty { false }; + bool m_metadata_dirty { false }; }; inline FS* InodeIdentifier::fs()