1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-24 21:25:07 +00:00

Kernel: Port Inode to ListedRefCounted

This consolidates the lock+list combo into a SpinLockProtectedValue
and closes yet another unref() race. :^)
This commit is contained in:
Andreas Kling 2021-08-17 01:05:06 +02:00
parent b70b3a9b92
commit ea09294351
2 changed files with 13 additions and 20 deletions

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021, sin-ack <sin-ack@protonmail.com> * Copyright (c) 2021, sin-ack <sin-ack@protonmail.com>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
@ -22,26 +22,22 @@
namespace Kernel { namespace Kernel {
static SpinLock s_all_inodes_lock; static Singleton<SpinLockProtectedValue<Inode::AllInstancesList>> s_all_instances;
static Singleton<Inode::List> s_list;
static Inode::List& all_with_lock() SpinLockProtectedValue<Inode::AllInstancesList>& Inode::all_instances()
{ {
VERIFY(s_all_inodes_lock.is_locked()); return s_all_instances;
return *s_list;
} }
void Inode::sync() void Inode::sync()
{ {
NonnullRefPtrVector<Inode, 32> inodes; NonnullRefPtrVector<Inode, 32> inodes;
{ Inode::all_instances().with([&](auto& all_inodes) {
ScopedSpinLock all_inodes_lock(s_all_inodes_lock); for (auto& inode : all_inodes) {
for (auto& inode : all_with_lock()) {
if (inode.is_metadata_dirty()) if (inode.is_metadata_dirty())
inodes.append(inode); inodes.append(inode);
} }
} });
for (auto& inode : inodes) { for (auto& inode : inodes) {
VERIFY(inode.is_metadata_dirty()); VERIFY(inode.is_metadata_dirty());
@ -95,15 +91,11 @@ Inode::Inode(FileSystem& fs, InodeIndex index)
: m_file_system(fs) : m_file_system(fs)
, m_index(index) , m_index(index)
{ {
ScopedSpinLock all_inodes_lock(s_all_inodes_lock); Inode::all_instances().with([&](auto& all_inodes) { all_inodes.append(*this); });
all_with_lock().append(*this);
} }
Inode::~Inode() Inode::~Inode()
{ {
ScopedSpinLock all_inodes_lock(s_all_inodes_lock);
all_with_lock().remove(*this);
for (auto& watcher : m_watchers) { for (auto& watcher : m_watchers) {
watcher->unregister_by_inode({}, identifier()); watcher->unregister_by_inode({}, identifier());
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021, sin-ack <sin-ack@protonmail.com> * Copyright (c) 2021, sin-ack <sin-ack@protonmail.com>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
@ -10,7 +10,6 @@
#include <AK/Function.h> #include <AK/Function.h>
#include <AK/HashTable.h> #include <AK/HashTable.h>
#include <AK/IntrusiveList.h> #include <AK/IntrusiveList.h>
#include <AK/RefCounted.h>
#include <AK/String.h> #include <AK/String.h>
#include <AK/WeakPtr.h> #include <AK/WeakPtr.h>
#include <Kernel/FileSystem/FIFO.h> #include <Kernel/FileSystem/FIFO.h>
@ -19,11 +18,12 @@
#include <Kernel/FileSystem/InodeMetadata.h> #include <Kernel/FileSystem/InodeMetadata.h>
#include <Kernel/Forward.h> #include <Kernel/Forward.h>
#include <Kernel/KResult.h> #include <Kernel/KResult.h>
#include <Kernel/Library/ListedRefCounted.h>
#include <Kernel/Locking/Mutex.h> #include <Kernel/Locking/Mutex.h>
namespace Kernel { namespace Kernel {
class Inode : public RefCounted<Inode> { class Inode : public ListedRefCounted<Inode> {
friend class VirtualFileSystem; friend class VirtualFileSystem;
friend class FileSystem; friend class FileSystem;
@ -134,7 +134,8 @@ private:
Vector<Flock> m_flocks; Vector<Flock> m_flocks;
public: public:
using List = IntrusiveList<Inode, RawPtr<Inode>, &Inode::m_inode_list_node>; using AllInstancesList = IntrusiveList<Inode, RawPtr<Inode>, &Inode::m_inode_list_node>;
static SpinLockProtectedValue<Inode::AllInstancesList>& all_instances();
}; };
} }