From 8e775d241e43b3f5dfcd17f7c6ae038ec1265ef7 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 30 Sep 2019 11:45:22 +0200 Subject: [PATCH] Kernel: Make DiskBackedFS flush writes if cache is completely dirty If we want to make a new entry in the disk cache when it's completely full of dirty blocks, we'll now synchronously flush the writes at that point. Maybe it's not ideal, but at least we can keep going. --- Kernel/FileSystem/DiskBackedFileSystem.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/Kernel/FileSystem/DiskBackedFileSystem.cpp b/Kernel/FileSystem/DiskBackedFileSystem.cpp index c8c3be33a6..c7581b8fb1 100644 --- a/Kernel/FileSystem/DiskBackedFileSystem.cpp +++ b/Kernel/FileSystem/DiskBackedFileSystem.cpp @@ -15,12 +15,13 @@ struct CacheEntry { class DiskCache { public: - explicit DiskCache(size_t block_size) - : m_cached_block_data(KBuffer::create_with_size(m_entry_count * block_size)) + explicit DiskCache(DiskBackedFS& fs) + : m_fs(fs) + , m_cached_block_data(KBuffer::create_with_size(m_entry_count * m_fs.block_size())) { m_entries = (CacheEntry*)kmalloc_eternal(m_entry_count * sizeof(CacheEntry)); for (size_t i = 0; i < m_entry_count; ++i) { - m_entries[i].data = m_cached_block_data.data() + i * block_size; + m_entries[i].data = m_cached_block_data.data() + i * m_fs.block_size(); } } @@ -47,8 +48,11 @@ public: oldest_clean_entry = &entry; } } - // FIXME: What if every single entry was dirty though :( - ASSERT(oldest_clean_entry); + if (!oldest_clean_entry) { + // Not a single clean entry! Flush writes and try again. + m_fs.flush_writes(); + return get(block_index); + } // Replace the oldest clean entry. auto& new_entry = *oldest_clean_entry; @@ -66,6 +70,8 @@ public: callback(m_entries[i]); } +private: + DiskBackedFS& m_fs; size_t m_entry_count { 10000 }; KBuffer m_cached_block_data; CacheEntry* m_entries { nullptr }; @@ -160,6 +166,6 @@ void DiskBackedFS::flush_writes() DiskCache& DiskBackedFS::cache() const { if (!m_cache) - m_cache = make(block_size()); + m_cache = make(const_cast(*this)); return *m_cache; }