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

Kernel/SysFS: Reduce the responsibilities of the Registry object

Instead, let the /sys/dev/block and /sys/dev/char directories to handle
the registering part of SysFSDeviceComponents by themselves.
This commit is contained in:
Liav A 2022-04-23 00:26:36 +03:00 committed by Andreas Kling
parent ecc29bb52e
commit 6733f19b3c
11 changed files with 72 additions and 31 deletions

View file

@ -9,6 +9,8 @@
#include <Kernel/Devices/DeviceManagement.h> #include <Kernel/Devices/DeviceManagement.h>
#include <Kernel/FileSystem/InodeMetadata.h> #include <Kernel/FileSystem/InodeMetadata.h>
#include <Kernel/FileSystem/SysFS.h> #include <Kernel/FileSystem/SysFS.h>
#include <Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/BlockDevicesDirectory.h>
#include <Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/CharacterDevicesDirectory.h>
#include <Kernel/Sections.h> #include <Kernel/Sections.h>
namespace Kernel { namespace Kernel {
@ -25,7 +27,14 @@ void Device::after_inserting()
VERIFY(!m_sysfs_component); VERIFY(!m_sysfs_component);
auto sys_fs_component = SysFSDeviceComponent::must_create(*this); auto sys_fs_component = SysFSDeviceComponent::must_create(*this);
m_sysfs_component = sys_fs_component; m_sysfs_component = sys_fs_component;
SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> void { if (is_block_device()) {
SysFSBlockDevicesDirectory::the().devices_list({}).with([&](auto& list) -> void {
list.append(sys_fs_component);
});
return;
}
VERIFY(is_character_device());
SysFSCharacterDevicesDirectory::the().devices_list({}).with([&](auto& list) -> void {
list.append(sys_fs_component); list.append(sys_fs_component);
}); });
} }
@ -33,9 +42,16 @@ void Device::after_inserting()
void Device::will_be_destroyed() void Device::will_be_destroyed()
{ {
VERIFY(m_sysfs_component); VERIFY(m_sysfs_component);
SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> void { if (is_block_device()) {
list.remove(*m_sysfs_component); SysFSBlockDevicesDirectory::the().devices_list({}).with([&](auto& list) -> void {
}); list.remove(*m_sysfs_component);
});
} else {
VERIFY(is_character_device());
SysFSCharacterDevicesDirectory::the().devices_list({}).with([&](auto& list) -> void {
list.remove(*m_sysfs_component);
});
}
DeviceManagement::the().before_device_removal({}, *this); DeviceManagement::the().before_device_removal({}, *this);
m_state = State::BeingRemoved; m_state = State::BeingRemoved;
} }

View file

@ -106,7 +106,7 @@ SysFSSymbolicLink::SysFSSymbolicLink(SysFSDirectory const& parent_directory, Sys
ErrorOr<void> SysFSDirectory::traverse_as_directory(FileSystemID fsid, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const ErrorOr<void> SysFSDirectory::traverse_as_directory(FileSystemID fsid, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
{ {
MutexLocker locker(SysFSComponentRegistry::the().get_lock()); MutexLocker locker(m_traverse_lock);
VERIFY(m_parent_directory); VERIFY(m_parent_directory);
TRY(callback({ "."sv, { fsid, component_index() }, 0 })); TRY(callback({ "."sv, { fsid, component_index() }, 0 }));
TRY(callback({ ".."sv, { fsid, m_parent_directory->component_index() }, 0 })); TRY(callback({ ".."sv, { fsid, m_parent_directory->component_index() }, 0 }));

View file

@ -81,6 +81,8 @@ protected:
SysFSDirectory() {}; SysFSDirectory() {};
explicit SysFSDirectory(SysFSDirectory const& parent_directory); explicit SysFSDirectory(SysFSDirectory const& parent_directory);
NonnullRefPtrVector<SysFSComponent> m_components; NonnullRefPtrVector<SysFSComponent> m_components;
mutable Mutex m_traverse_lock;
}; };
} }

View file

@ -31,15 +31,10 @@ UNMAP_AFTER_INIT SysFSComponentRegistry::SysFSComponentRegistry()
UNMAP_AFTER_INIT void SysFSComponentRegistry::register_new_component(SysFSComponent& component) UNMAP_AFTER_INIT void SysFSComponentRegistry::register_new_component(SysFSComponent& component)
{ {
MutexLocker locker(m_lock); SpinlockLocker locker(m_root_directory_lock);
m_root_directory->m_components.append(component); m_root_directory->m_components.append(component);
} }
SysFSComponentRegistry::DevicesList& SysFSComponentRegistry::devices_list()
{
return m_devices_list;
}
SysFSBusDirectory& SysFSComponentRegistry::buses_directory() SysFSBusDirectory& SysFSComponentRegistry::buses_directory()
{ {
return *m_root_directory->m_buses_directory; return *m_root_directory->m_buses_directory;

View file

@ -16,7 +16,6 @@
namespace Kernel { namespace Kernel {
class SysFSComponentRegistry { class SysFSComponentRegistry {
using DevicesList = MutexProtected<IntrusiveList<&SysFSDeviceComponent::m_list_node>>;
public: public:
static SysFSComponentRegistry& the(); static SysFSComponentRegistry& the();
@ -27,17 +26,13 @@ public:
void register_new_component(SysFSComponent&); void register_new_component(SysFSComponent&);
SysFSDirectory& root_directory() { return m_root_directory; } SysFSDirectory& root_directory() { return m_root_directory; }
Mutex& get_lock() { return m_lock; }
void register_new_bus_directory(SysFSDirectory&); void register_new_bus_directory(SysFSDirectory&);
SysFSBusDirectory& buses_directory(); SysFSBusDirectory& buses_directory();
DevicesList& devices_list();
private: private:
Mutex m_lock;
NonnullRefPtr<SysFSRootDirectory> m_root_directory; NonnullRefPtr<SysFSRootDirectory> m_root_directory;
DevicesList m_devices_list; Spinlock m_root_directory_lock;
}; };
} }

View file

@ -19,7 +19,7 @@ NonnullRefPtr<SysFSRootDirectory> SysFSRootDirectory::create()
ErrorOr<void> SysFSRootDirectory::traverse_as_directory(FileSystemID fsid, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const ErrorOr<void> SysFSRootDirectory::traverse_as_directory(FileSystemID fsid, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
{ {
MutexLocker locker(SysFSComponentRegistry::the().get_lock()); MutexLocker locker(m_traverse_lock);
TRY(callback({ "."sv, { fsid, component_index() }, 0 })); TRY(callback({ "."sv, { fsid, component_index() }, 0 }));
TRY(callback({ ".."sv, { fsid, 0 }, 0 })); TRY(callback({ ".."sv, { fsid, 0 }, 0 }));

View file

@ -10,6 +10,8 @@
namespace Kernel { namespace Kernel {
static SysFSBlockDevicesDirectory* s_the { nullptr };
NonnullRefPtr<SysFSBlockDevicesDirectory> SysFSBlockDevicesDirectory::must_create(SysFSDeviceIdentifiersDirectory const& devices_directory) NonnullRefPtr<SysFSBlockDevicesDirectory> SysFSBlockDevicesDirectory::must_create(SysFSDeviceIdentifiersDirectory const& devices_directory)
{ {
return adopt_ref_if_nonnull(new SysFSBlockDevicesDirectory(devices_directory)).release_nonnull(); return adopt_ref_if_nonnull(new SysFSBlockDevicesDirectory(devices_directory)).release_nonnull();
@ -17,6 +19,13 @@ NonnullRefPtr<SysFSBlockDevicesDirectory> SysFSBlockDevicesDirectory::must_creat
SysFSBlockDevicesDirectory::SysFSBlockDevicesDirectory(SysFSDeviceIdentifiersDirectory const& devices_directory) SysFSBlockDevicesDirectory::SysFSBlockDevicesDirectory(SysFSDeviceIdentifiersDirectory const& devices_directory)
: SysFSDirectory(devices_directory) : SysFSDirectory(devices_directory)
{ {
s_the = this;
}
SysFSBlockDevicesDirectory& SysFSBlockDevicesDirectory::the()
{
VERIFY(s_the);
return *s_the;
} }
ErrorOr<void> SysFSBlockDevicesDirectory::traverse_as_directory(FileSystemID fsid, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const ErrorOr<void> SysFSBlockDevicesDirectory::traverse_as_directory(FileSystemID fsid, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
@ -25,10 +34,9 @@ ErrorOr<void> SysFSBlockDevicesDirectory::traverse_as_directory(FileSystemID fsi
TRY(callback({ "."sv, { fsid, component_index() }, 0 })); TRY(callback({ "."sv, { fsid, component_index() }, 0 }));
TRY(callback({ ".."sv, { fsid, m_parent_directory->component_index() }, 0 })); TRY(callback({ ".."sv, { fsid, m_parent_directory->component_index() }, 0 }));
return SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> ErrorOr<void> { return m_devices_list.with([&](auto& list) -> ErrorOr<void> {
for (auto& exposed_device : list) { for (auto& exposed_device : list) {
if (!exposed_device.is_block_device()) VERIFY(exposed_device.is_block_device());
continue;
TRY(callback({ exposed_device.name(), { fsid, exposed_device.component_index() }, 0 })); TRY(callback({ exposed_device.name(), { fsid, exposed_device.component_index() }, 0 }));
} }
return {}; return {};
@ -37,10 +45,9 @@ ErrorOr<void> SysFSBlockDevicesDirectory::traverse_as_directory(FileSystemID fsi
RefPtr<SysFSComponent> SysFSBlockDevicesDirectory::lookup(StringView name) RefPtr<SysFSComponent> SysFSBlockDevicesDirectory::lookup(StringView name)
{ {
return SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> RefPtr<SysFSComponent> { return m_devices_list.with([&](auto& list) -> RefPtr<SysFSComponent> {
for (auto& exposed_device : list) { for (auto& exposed_device : list) {
if (!exposed_device.is_block_device()) VERIFY(exposed_device.is_block_device());
continue;
if (exposed_device.name() == name) if (exposed_device.name() == name)
return exposed_device; return exposed_device;
} }

View file

@ -7,10 +7,12 @@
#pragma once #pragma once
#include <Kernel/FileSystem/SysFS/Component.h> #include <Kernel/FileSystem/SysFS/Component.h>
#include <Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/DeviceComponent.h>
#include <Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/Directory.h> #include <Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/Directory.h>
namespace Kernel { namespace Kernel {
class Device;
class SysFSBlockDevicesDirectory final : public SysFSDirectory { class SysFSBlockDevicesDirectory final : public SysFSDirectory {
public: public:
virtual StringView name() const override { return "block"sv; } virtual StringView name() const override { return "block"sv; }
@ -18,8 +20,15 @@ public:
virtual ErrorOr<void> traverse_as_directory(FileSystemID, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(FileSystemID, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual RefPtr<SysFSComponent> lookup(StringView name) override; virtual RefPtr<SysFSComponent> lookup(StringView name) override;
static SysFSBlockDevicesDirectory& the();
using DevicesList = SpinlockProtected<IntrusiveList<&SysFSDeviceComponent::m_list_node>>;
DevicesList& devices_list(Badge<Device>) { return m_devices_list; }
private: private:
explicit SysFSBlockDevicesDirectory(SysFSDeviceIdentifiersDirectory const&); explicit SysFSBlockDevicesDirectory(SysFSDeviceIdentifiersDirectory const&);
DevicesList m_devices_list;
}; };
} }

View file

@ -10,6 +10,8 @@
namespace Kernel { namespace Kernel {
static SysFSCharacterDevicesDirectory* s_the { nullptr };
NonnullRefPtr<SysFSCharacterDevicesDirectory> SysFSCharacterDevicesDirectory::must_create(SysFSDeviceIdentifiersDirectory const& devices_directory) NonnullRefPtr<SysFSCharacterDevicesDirectory> SysFSCharacterDevicesDirectory::must_create(SysFSDeviceIdentifiersDirectory const& devices_directory)
{ {
return adopt_ref_if_nonnull(new SysFSCharacterDevicesDirectory(devices_directory)).release_nonnull(); return adopt_ref_if_nonnull(new SysFSCharacterDevicesDirectory(devices_directory)).release_nonnull();
@ -17,6 +19,7 @@ NonnullRefPtr<SysFSCharacterDevicesDirectory> SysFSCharacterDevicesDirectory::mu
SysFSCharacterDevicesDirectory::SysFSCharacterDevicesDirectory(SysFSDeviceIdentifiersDirectory const& devices_directory) SysFSCharacterDevicesDirectory::SysFSCharacterDevicesDirectory(SysFSDeviceIdentifiersDirectory const& devices_directory)
: SysFSDirectory(devices_directory) : SysFSDirectory(devices_directory)
{ {
s_the = this;
} }
ErrorOr<void> SysFSCharacterDevicesDirectory::traverse_as_directory(FileSystemID fsid, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const ErrorOr<void> SysFSCharacterDevicesDirectory::traverse_as_directory(FileSystemID fsid, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
{ {
@ -24,22 +27,26 @@ ErrorOr<void> SysFSCharacterDevicesDirectory::traverse_as_directory(FileSystemID
TRY(callback({ "."sv, { fsid, component_index() }, 0 })); TRY(callback({ "."sv, { fsid, component_index() }, 0 }));
TRY(callback({ ".."sv, { fsid, m_parent_directory->component_index() }, 0 })); TRY(callback({ ".."sv, { fsid, m_parent_directory->component_index() }, 0 }));
return SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> ErrorOr<void> { return m_devices_list.with([&](auto& list) -> ErrorOr<void> {
for (auto& exposed_device : list) { for (auto& exposed_device : list) {
if (exposed_device.is_block_device()) VERIFY(!exposed_device.is_block_device());
continue;
TRY(callback({ exposed_device.name(), { fsid, exposed_device.component_index() }, 0 })); TRY(callback({ exposed_device.name(), { fsid, exposed_device.component_index() }, 0 }));
} }
return {}; return {};
}); });
} }
SysFSCharacterDevicesDirectory& SysFSCharacterDevicesDirectory::the()
{
VERIFY(s_the);
return *s_the;
}
RefPtr<SysFSComponent> SysFSCharacterDevicesDirectory::lookup(StringView name) RefPtr<SysFSComponent> SysFSCharacterDevicesDirectory::lookup(StringView name)
{ {
return SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> RefPtr<SysFSComponent> { return m_devices_list.with([&](auto& list) -> RefPtr<SysFSComponent> {
for (auto& exposed_device : list) { for (auto& exposed_device : list) {
if (exposed_device.is_block_device()) VERIFY(!exposed_device.is_block_device());
continue;
if (exposed_device.name() == name) if (exposed_device.name() == name)
return exposed_device; return exposed_device;
} }

View file

@ -7,10 +7,12 @@
#pragma once #pragma once
#include <Kernel/FileSystem/SysFS/Component.h> #include <Kernel/FileSystem/SysFS/Component.h>
#include <Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/DeviceComponent.h>
#include <Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/Directory.h> #include <Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/Directory.h>
namespace Kernel { namespace Kernel {
class Device;
class SysFSCharacterDevicesDirectory final : public SysFSDirectory { class SysFSCharacterDevicesDirectory final : public SysFSDirectory {
public: public:
virtual StringView name() const override { return "char"sv; } virtual StringView name() const override { return "char"sv; }
@ -18,8 +20,15 @@ public:
virtual ErrorOr<void> traverse_as_directory(FileSystemID, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<void> traverse_as_directory(FileSystemID, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
virtual RefPtr<SysFSComponent> lookup(StringView name) override; virtual RefPtr<SysFSComponent> lookup(StringView name) override;
static SysFSCharacterDevicesDirectory& the();
using DevicesList = SpinlockProtected<IntrusiveList<&SysFSDeviceComponent::m_list_node>>;
DevicesList& devices_list(Badge<Device>) { return m_devices_list; }
private: private:
explicit SysFSCharacterDevicesDirectory(SysFSDeviceIdentifiersDirectory const&); explicit SysFSCharacterDevicesDirectory(SysFSDeviceIdentifiersDirectory const&);
DevicesList m_devices_list;
}; };
} }

View file

@ -15,7 +15,8 @@ namespace Kernel {
class SysFSDeviceComponent final class SysFSDeviceComponent final
: public SysFSComponent : public SysFSComponent
, public Weakable<SysFSDeviceComponent> { , public Weakable<SysFSDeviceComponent> {
friend class SysFSComponentRegistry; friend class SysFSBlockDevicesDirectory;
friend class SysFSCharacterDevicesDirectory;
public: public:
static NonnullRefPtr<SysFSDeviceComponent> must_create(Device const&); static NonnullRefPtr<SysFSDeviceComponent> must_create(Device const&);