diff --git a/Kernel/Devices/Device.cpp b/Kernel/Devices/Device.cpp index 966325f6e7..34df75f350 100644 --- a/Kernel/Devices/Device.cpp +++ b/Kernel/Devices/Device.cpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include namespace Kernel { @@ -25,7 +27,14 @@ void Device::after_inserting() VERIFY(!m_sysfs_component); auto sys_fs_component = SysFSDeviceComponent::must_create(*this); 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); }); } @@ -33,9 +42,16 @@ void Device::after_inserting() void Device::will_be_destroyed() { VERIFY(m_sysfs_component); - SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> void { - list.remove(*m_sysfs_component); - }); + if (is_block_device()) { + 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); m_state = State::BeingRemoved; } diff --git a/Kernel/FileSystem/SysFS/Component.cpp b/Kernel/FileSystem/SysFS/Component.cpp index 3216f199d2..fb9cfce122 100644 --- a/Kernel/FileSystem/SysFS/Component.cpp +++ b/Kernel/FileSystem/SysFS/Component.cpp @@ -106,7 +106,7 @@ SysFSSymbolicLink::SysFSSymbolicLink(SysFSDirectory const& parent_directory, Sys ErrorOr SysFSDirectory::traverse_as_directory(FileSystemID fsid, Function(FileSystem::DirectoryEntryView const&)> callback) const { - MutexLocker locker(SysFSComponentRegistry::the().get_lock()); + MutexLocker locker(m_traverse_lock); VERIFY(m_parent_directory); TRY(callback({ "."sv, { fsid, component_index() }, 0 })); TRY(callback({ ".."sv, { fsid, m_parent_directory->component_index() }, 0 })); diff --git a/Kernel/FileSystem/SysFS/Component.h b/Kernel/FileSystem/SysFS/Component.h index 5c6d7da9b3..c5711ea1f0 100644 --- a/Kernel/FileSystem/SysFS/Component.h +++ b/Kernel/FileSystem/SysFS/Component.h @@ -81,6 +81,8 @@ protected: SysFSDirectory() {}; explicit SysFSDirectory(SysFSDirectory const& parent_directory); NonnullRefPtrVector m_components; + + mutable Mutex m_traverse_lock; }; } diff --git a/Kernel/FileSystem/SysFS/Registry.cpp b/Kernel/FileSystem/SysFS/Registry.cpp index e11084651e..c8d623f67b 100644 --- a/Kernel/FileSystem/SysFS/Registry.cpp +++ b/Kernel/FileSystem/SysFS/Registry.cpp @@ -31,15 +31,10 @@ UNMAP_AFTER_INIT SysFSComponentRegistry::SysFSComponentRegistry() 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); } -SysFSComponentRegistry::DevicesList& SysFSComponentRegistry::devices_list() -{ - return m_devices_list; -} - SysFSBusDirectory& SysFSComponentRegistry::buses_directory() { return *m_root_directory->m_buses_directory; diff --git a/Kernel/FileSystem/SysFS/Registry.h b/Kernel/FileSystem/SysFS/Registry.h index b888bb5eef..6632fd81aa 100644 --- a/Kernel/FileSystem/SysFS/Registry.h +++ b/Kernel/FileSystem/SysFS/Registry.h @@ -16,7 +16,6 @@ namespace Kernel { class SysFSComponentRegistry { - using DevicesList = MutexProtected>; public: static SysFSComponentRegistry& the(); @@ -27,17 +26,13 @@ public: void register_new_component(SysFSComponent&); SysFSDirectory& root_directory() { return m_root_directory; } - Mutex& get_lock() { return m_lock; } void register_new_bus_directory(SysFSDirectory&); SysFSBusDirectory& buses_directory(); - DevicesList& devices_list(); - private: - Mutex m_lock; NonnullRefPtr m_root_directory; - DevicesList m_devices_list; + Spinlock m_root_directory_lock; }; } diff --git a/Kernel/FileSystem/SysFS/RootDirectory.cpp b/Kernel/FileSystem/SysFS/RootDirectory.cpp index b844df3100..d32f2e0332 100644 --- a/Kernel/FileSystem/SysFS/RootDirectory.cpp +++ b/Kernel/FileSystem/SysFS/RootDirectory.cpp @@ -19,7 +19,7 @@ NonnullRefPtr SysFSRootDirectory::create() ErrorOr SysFSRootDirectory::traverse_as_directory(FileSystemID fsid, Function(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, 0 }, 0 })); diff --git a/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/BlockDevicesDirectory.cpp b/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/BlockDevicesDirectory.cpp index 6de2fc0026..feeea0634d 100644 --- a/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/BlockDevicesDirectory.cpp +++ b/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/BlockDevicesDirectory.cpp @@ -10,6 +10,8 @@ namespace Kernel { +static SysFSBlockDevicesDirectory* s_the { nullptr }; + NonnullRefPtr SysFSBlockDevicesDirectory::must_create(SysFSDeviceIdentifiersDirectory const& devices_directory) { return adopt_ref_if_nonnull(new SysFSBlockDevicesDirectory(devices_directory)).release_nonnull(); @@ -17,6 +19,13 @@ NonnullRefPtr SysFSBlockDevicesDirectory::must_creat SysFSBlockDevicesDirectory::SysFSBlockDevicesDirectory(SysFSDeviceIdentifiersDirectory const& devices_directory) : SysFSDirectory(devices_directory) { + s_the = this; +} + +SysFSBlockDevicesDirectory& SysFSBlockDevicesDirectory::the() +{ + VERIFY(s_the); + return *s_the; } ErrorOr SysFSBlockDevicesDirectory::traverse_as_directory(FileSystemID fsid, Function(FileSystem::DirectoryEntryView const&)> callback) const @@ -25,10 +34,9 @@ ErrorOr SysFSBlockDevicesDirectory::traverse_as_directory(FileSystemID fsi TRY(callback({ "."sv, { fsid, component_index() }, 0 })); TRY(callback({ ".."sv, { fsid, m_parent_directory->component_index() }, 0 })); - return SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> ErrorOr { + return m_devices_list.with([&](auto& list) -> ErrorOr { for (auto& exposed_device : list) { - if (!exposed_device.is_block_device()) - continue; + VERIFY(exposed_device.is_block_device()); TRY(callback({ exposed_device.name(), { fsid, exposed_device.component_index() }, 0 })); } return {}; @@ -37,10 +45,9 @@ ErrorOr SysFSBlockDevicesDirectory::traverse_as_directory(FileSystemID fsi RefPtr SysFSBlockDevicesDirectory::lookup(StringView name) { - return SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> RefPtr { + return m_devices_list.with([&](auto& list) -> RefPtr { for (auto& exposed_device : list) { - if (!exposed_device.is_block_device()) - continue; + VERIFY(exposed_device.is_block_device()); if (exposed_device.name() == name) return exposed_device; } diff --git a/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/BlockDevicesDirectory.h b/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/BlockDevicesDirectory.h index 7b5b0ab155..9ae2ade125 100644 --- a/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/BlockDevicesDirectory.h +++ b/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/BlockDevicesDirectory.h @@ -7,10 +7,12 @@ #pragma once #include +#include #include namespace Kernel { +class Device; class SysFSBlockDevicesDirectory final : public SysFSDirectory { public: virtual StringView name() const override { return "block"sv; } @@ -18,8 +20,15 @@ public: virtual ErrorOr traverse_as_directory(FileSystemID, Function(FileSystem::DirectoryEntryView const&)>) const override; virtual RefPtr lookup(StringView name) override; + static SysFSBlockDevicesDirectory& the(); + + using DevicesList = SpinlockProtected>; + DevicesList& devices_list(Badge) { return m_devices_list; } + private: explicit SysFSBlockDevicesDirectory(SysFSDeviceIdentifiersDirectory const&); + + DevicesList m_devices_list; }; } diff --git a/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/CharacterDevicesDirectory.cpp b/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/CharacterDevicesDirectory.cpp index a26b6bcc42..9d59452404 100644 --- a/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/CharacterDevicesDirectory.cpp +++ b/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/CharacterDevicesDirectory.cpp @@ -10,6 +10,8 @@ namespace Kernel { +static SysFSCharacterDevicesDirectory* s_the { nullptr }; + NonnullRefPtr SysFSCharacterDevicesDirectory::must_create(SysFSDeviceIdentifiersDirectory const& devices_directory) { return adopt_ref_if_nonnull(new SysFSCharacterDevicesDirectory(devices_directory)).release_nonnull(); @@ -17,6 +19,7 @@ NonnullRefPtr SysFSCharacterDevicesDirectory::mu SysFSCharacterDevicesDirectory::SysFSCharacterDevicesDirectory(SysFSDeviceIdentifiersDirectory const& devices_directory) : SysFSDirectory(devices_directory) { + s_the = this; } ErrorOr SysFSCharacterDevicesDirectory::traverse_as_directory(FileSystemID fsid, Function(FileSystem::DirectoryEntryView const&)> callback) const { @@ -24,22 +27,26 @@ ErrorOr SysFSCharacterDevicesDirectory::traverse_as_directory(FileSystemID TRY(callback({ "."sv, { fsid, component_index() }, 0 })); TRY(callback({ ".."sv, { fsid, m_parent_directory->component_index() }, 0 })); - return SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> ErrorOr { + return m_devices_list.with([&](auto& list) -> ErrorOr { for (auto& exposed_device : list) { - if (exposed_device.is_block_device()) - continue; + VERIFY(!exposed_device.is_block_device()); TRY(callback({ exposed_device.name(), { fsid, exposed_device.component_index() }, 0 })); } return {}; }); } +SysFSCharacterDevicesDirectory& SysFSCharacterDevicesDirectory::the() +{ + VERIFY(s_the); + return *s_the; +} + RefPtr SysFSCharacterDevicesDirectory::lookup(StringView name) { - return SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> RefPtr { + return m_devices_list.with([&](auto& list) -> RefPtr { for (auto& exposed_device : list) { - if (exposed_device.is_block_device()) - continue; + VERIFY(!exposed_device.is_block_device()); if (exposed_device.name() == name) return exposed_device; } diff --git a/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/CharacterDevicesDirectory.h b/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/CharacterDevicesDirectory.h index 1249d93da0..c273cf820f 100644 --- a/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/CharacterDevicesDirectory.h +++ b/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/CharacterDevicesDirectory.h @@ -7,10 +7,12 @@ #pragma once #include +#include #include namespace Kernel { +class Device; class SysFSCharacterDevicesDirectory final : public SysFSDirectory { public: virtual StringView name() const override { return "char"sv; } @@ -18,8 +20,15 @@ public: virtual ErrorOr traverse_as_directory(FileSystemID, Function(FileSystem::DirectoryEntryView const&)>) const override; virtual RefPtr lookup(StringView name) override; + static SysFSCharacterDevicesDirectory& the(); + + using DevicesList = SpinlockProtected>; + DevicesList& devices_list(Badge) { return m_devices_list; } + private: explicit SysFSCharacterDevicesDirectory(SysFSDeviceIdentifiersDirectory const&); + + DevicesList m_devices_list; }; } diff --git a/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/DeviceComponent.h b/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/DeviceComponent.h index 40aaebbb3d..479b1b0b4e 100644 --- a/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/DeviceComponent.h +++ b/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/DeviceComponent.h @@ -15,7 +15,8 @@ namespace Kernel { class SysFSDeviceComponent final : public SysFSComponent , public Weakable { - friend class SysFSComponentRegistry; + friend class SysFSBlockDevicesDirectory; + friend class SysFSCharacterDevicesDirectory; public: static NonnullRefPtr must_create(Device const&);