diff options
author | Liav A <liavalb@gmail.com> | 2022-04-23 11:48:40 +0300 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-07-15 12:29:23 +0200 |
commit | 1dbd32488f746a27c6a98f84abb96bdfd8578444 (patch) | |
tree | 69028bb07608696b8537f966218cd74a2b15acd2 /Kernel | |
parent | 22335e53e0a3bfde31bb48514301eabcd17468c6 (diff) | |
download | serenity-1dbd32488f746a27c6a98f84abb96bdfd8578444.zip |
Kernel/SysFS: Add /sys/devices/storage directory
This change in fact does the following:
1. Use support for symlinks between /sys/dev/block/ storage device
identifier nodes and devices in /sys/devices/storage/{LUN}.
2. Add basic nodes in a /sys/devices/storage/{LUN} directory, to let
userspace to know about the device and its details.
Diffstat (limited to 'Kernel')
19 files changed, 450 insertions, 1 deletions
diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index f0a0cef579..b7efb3d917 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -152,6 +152,11 @@ set(KERNEL_SOURCES FileSystem/SysFS/Subsystems/DeviceIdentifiers/CharacterDevicesDirectory.cpp FileSystem/SysFS/Subsystems/DeviceIdentifiers/DeviceComponent.cpp FileSystem/SysFS/Subsystems/DeviceIdentifiers/Directory.cpp + FileSystem/SysFS/Subsystems/DeviceIdentifiers/SymbolicLinkDeviceComponent.cpp + FileSystem/SysFS/Subsystems/Devices/Storage/DeviceAttribute.cpp + FileSystem/SysFS/Subsystems/Devices/Storage/DeviceDirectory.cpp + FileSystem/SysFS/Subsystems/Devices/Storage/Directory.cpp + FileSystem/SysFS/Subsystems/Devices/Directory.cpp FileSystem/SysFS/Subsystems/Firmware/BIOS/Component.cpp FileSystem/SysFS/Subsystems/Firmware/BIOS/Directory.cpp FileSystem/SysFS/Subsystems/Firmware/Directory.cpp diff --git a/Kernel/Devices/Device.h b/Kernel/Devices/Device.h index f968fe7253..84f2086ac8 100644 --- a/Kernel/Devices/Device.h +++ b/Kernel/Devices/Device.h @@ -24,6 +24,7 @@ #include <Kernel/FileSystem/File.h> #include <Kernel/FileSystem/SysFS/Registry.h> #include <Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/DeviceComponent.h> +#include <Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/SymbolicLinkDeviceComponent.h> #include <Kernel/UnixTypes.h> namespace Kernel { @@ -82,6 +83,10 @@ private: Spinlock m_requests_lock; DoublyLinkedList<RefPtr<AsyncDeviceRequest>> m_requests; RefPtr<SysFSDeviceComponent> m_sysfs_component; + +protected: + RefPtr<SysFSSymbolicLinkDeviceComponent> m_symlink_sysfs_component; + RefPtr<SysFSDirectory> m_sysfs_device_directory; }; } diff --git a/Kernel/FileSystem/SysFS/RootDirectory.cpp b/Kernel/FileSystem/SysFS/RootDirectory.cpp index 1f21579a26..d3e7fc20a8 100644 --- a/Kernel/FileSystem/SysFS/RootDirectory.cpp +++ b/Kernel/FileSystem/SysFS/RootDirectory.cpp @@ -8,6 +8,7 @@ #include <Kernel/FileSystem/SysFS/RootDirectory.h> #include <Kernel/FileSystem/SysFS/Subsystems/Bus/Directory.h> #include <Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/Directory.h> +#include <Kernel/FileSystem/SysFS/Subsystems/Devices/Directory.h> #include <Kernel/Sections.h> namespace Kernel { @@ -21,9 +22,11 @@ SysFSRootDirectory::SysFSRootDirectory() { auto buses_directory = SysFSBusDirectory::must_create(*this); auto device_identifiers_directory = SysFSDeviceIdentifiersDirectory::must_create(*this); + auto devices_directory = SysFSDevicesDirectory::must_create(*this); MUST(m_child_components.with([&](auto& list) -> ErrorOr<void> { list.append(buses_directory); list.append(device_identifiers_directory); + list.append(devices_directory); return {}; })); m_buses_directory = buses_directory; diff --git a/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/BlockDevicesDirectory.h b/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/BlockDevicesDirectory.h index 8b23fcda06..a1d2069361 100644 --- a/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/BlockDevicesDirectory.h +++ b/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/BlockDevicesDirectory.h @@ -13,7 +13,11 @@ namespace Kernel { class Device; +class StorageDevice; class SysFSBlockDevicesDirectory final : public SysFSDirectory { + friend class Device; + friend class StorageDevice; + public: virtual StringView name() const override { return "block"sv; } static NonnullRefPtr<SysFSBlockDevicesDirectory> must_create(SysFSDeviceIdentifiersDirectory const&); diff --git a/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/Directory.cpp b/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/Directory.cpp index 32b51391e5..3653948246 100644 --- a/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/Directory.cpp +++ b/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/Directory.cpp @@ -12,6 +12,14 @@ namespace Kernel { +static SysFSDeviceIdentifiersDirectory* s_the { nullptr }; + +SysFSDeviceIdentifiersDirectory& SysFSDeviceIdentifiersDirectory::the() +{ + VERIFY(s_the); + return *s_the; +} + UNMAP_AFTER_INIT NonnullRefPtr<SysFSDeviceIdentifiersDirectory> SysFSDeviceIdentifiersDirectory::must_create(SysFSRootDirectory const& root_directory) { auto devices_directory = adopt_ref_if_nonnull(new SysFSDeviceIdentifiersDirectory(root_directory)).release_nonnull(); @@ -20,7 +28,7 @@ UNMAP_AFTER_INIT NonnullRefPtr<SysFSDeviceIdentifiersDirectory> SysFSDeviceIdent list.append(SysFSCharacterDevicesDirectory::must_create(*devices_directory)); return {}; })); - + s_the = devices_directory; return devices_directory; } SysFSDeviceIdentifiersDirectory::SysFSDeviceIdentifiersDirectory(SysFSRootDirectory const& root_directory) diff --git a/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/Directory.h b/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/Directory.h index 5b7b684ef2..9bc56f2fa2 100644 --- a/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/Directory.h +++ b/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/Directory.h @@ -16,6 +16,8 @@ public: virtual StringView name() const override { return "dev"sv; } static NonnullRefPtr<SysFSDeviceIdentifiersDirectory> must_create(SysFSRootDirectory const&); + static SysFSDeviceIdentifiersDirectory& the(); + private: explicit SysFSDeviceIdentifiersDirectory(SysFSRootDirectory const&); }; diff --git a/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/SymbolicLinkDeviceComponent.cpp b/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/SymbolicLinkDeviceComponent.cpp new file mode 100644 index 0000000000..ebf62c0a86 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/SymbolicLinkDeviceComponent.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <Kernel/Devices/Device.h> +#include <Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/Directory.h> +#include <Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/SymbolicLinkDeviceComponent.h> +#include <Kernel/Sections.h> + +namespace Kernel { + +ErrorOr<NonnullRefPtr<SysFSSymbolicLinkDeviceComponent>> SysFSSymbolicLinkDeviceComponent::try_create(SysFSDeviceIdentifiersDirectory const& parent_directory, Device const& device, SysFSComponent const& pointed_component) +{ + auto device_name = TRY(KString::formatted("{}:{}", device.major(), device.minor())); + return adopt_nonnull_ref_or_enomem(new (nothrow) SysFSSymbolicLinkDeviceComponent(parent_directory, move(device_name), device, pointed_component)); +} +SysFSSymbolicLinkDeviceComponent::SysFSSymbolicLinkDeviceComponent(SysFSDeviceIdentifiersDirectory const& parent_directory, NonnullOwnPtr<KString> major_minor_formatted_device_name, Device const& device, SysFSComponent const& pointed_component) + : SysFSSymbolicLink(parent_directory, pointed_component) + , m_block_device(device.is_block_device()) + , m_major_minor_formatted_device_name(move(major_minor_formatted_device_name)) +{ + VERIFY(device.is_block_device() || device.is_character_device()); +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/SymbolicLinkDeviceComponent.h b/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/SymbolicLinkDeviceComponent.h new file mode 100644 index 0000000000..8dcd9c6cb8 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/SymbolicLinkDeviceComponent.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/IntrusiveList.h> +#include <Kernel/FileSystem/SysFS/Component.h> +#include <Kernel/KString.h> + +namespace Kernel { + +class SysFSDeviceIdentifiersDirectory; +class SysFSSymbolicLinkDeviceComponent final + : public SysFSSymbolicLink + , public Weakable<SysFSSymbolicLinkDeviceComponent> { + friend class SysFSComponentRegistry; + +public: + static ErrorOr<NonnullRefPtr<SysFSSymbolicLinkDeviceComponent>> try_create(SysFSDeviceIdentifiersDirectory const& parent_directory, Device const&, SysFSComponent const& pointed_component); + virtual StringView name() const override { return m_major_minor_formatted_device_name->view(); } + bool is_block_device() const { return m_block_device; } + +private: + SysFSSymbolicLinkDeviceComponent(SysFSDeviceIdentifiersDirectory const& parent_directory, NonnullOwnPtr<KString> major_minor_formatted_device_name, Device const&, SysFSComponent const& pointed_component); + IntrusiveListNode<SysFSSymbolicLinkDeviceComponent, NonnullRefPtr<SysFSSymbolicLinkDeviceComponent>> m_list_node; + bool const m_block_device { false }; + NonnullOwnPtr<KString> m_major_minor_formatted_device_name; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Devices/Directory.cpp b/Kernel/FileSystem/SysFS/Subsystems/Devices/Directory.cpp new file mode 100644 index 0000000000..af8217f01e --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Devices/Directory.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <Kernel/FileSystem/SysFS/RootDirectory.h> +#include <Kernel/FileSystem/SysFS/Subsystems/Devices/Directory.h> +#include <Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/Directory.h> +#include <Kernel/Sections.h> + +namespace Kernel { + +UNMAP_AFTER_INIT NonnullRefPtr<SysFSDevicesDirectory> SysFSDevicesDirectory::must_create(SysFSRootDirectory const& root_directory) +{ + auto devices_directory = adopt_ref_if_nonnull(new (nothrow) SysFSDevicesDirectory(root_directory)).release_nonnull(); + MUST(devices_directory->m_child_components.with([&](auto& list) -> ErrorOr<void> { + list.append(SysFSStorageDirectory::must_create(*devices_directory)); + return {}; + })); + return devices_directory; +} +SysFSDevicesDirectory::SysFSDevicesDirectory(SysFSRootDirectory const& root_directory) + : SysFSDirectory(root_directory) +{ +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Devices/Directory.h b/Kernel/FileSystem/SysFS/Subsystems/Devices/Directory.h new file mode 100644 index 0000000000..0d1e08ba45 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Devices/Directory.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <Kernel/FileSystem/SysFS/Component.h> +#include <Kernel/Forward.h> + +namespace Kernel { + +class SysFSDevicesDirectory final : public SysFSDirectory { +public: + virtual StringView name() const override { return "devices"sv; } + static NonnullRefPtr<SysFSDevicesDirectory> must_create(SysFSRootDirectory const&); + +private: + explicit SysFSDevicesDirectory(SysFSRootDirectory const&); +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/DeviceAttribute.cpp b/Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/DeviceAttribute.cpp new file mode 100644 index 0000000000..c76ea273f6 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/DeviceAttribute.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <Kernel/Bus/PCI/API.h> +#include <Kernel/Bus/PCI/Access.h> +#include <Kernel/Debug.h> +#include <Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/DeviceAttribute.h> +#include <Kernel/Sections.h> + +namespace Kernel { + +StringView StorageDeviceAttributeSysFSComponent::name() const +{ + switch (m_type) { + case Type::EndLBA: + return "last_lba"sv; + case Type::SectorSize: + return "sector_size"sv; + case Type::CommandSet: + return "command_set"sv; + case Type::InterfaceType: + return "interface_type"sv; + default: + VERIFY_NOT_REACHED(); + } +} + +NonnullRefPtr<StorageDeviceAttributeSysFSComponent> StorageDeviceAttributeSysFSComponent::must_create(StorageDeviceSysFSDirectory const& device_directory, Type type) +{ + return adopt_ref(*new (nothrow) StorageDeviceAttributeSysFSComponent(device_directory, type)); +} + +StorageDeviceAttributeSysFSComponent::StorageDeviceAttributeSysFSComponent(StorageDeviceSysFSDirectory const& device_directory, Type type) + : SysFSComponent() + , m_device(device_directory.device({})) + , m_type(type) +{ +} + +ErrorOr<size_t> StorageDeviceAttributeSysFSComponent::read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, OpenFileDescription*) const +{ + auto blob = TRY(try_to_generate_buffer()); + + if ((size_t)offset >= blob->size()) + return 0; + + ssize_t nread = min(static_cast<off_t>(blob->size() - offset), static_cast<off_t>(count)); + TRY(buffer.write(blob->data() + offset, nread)); + return nread; +} + +ErrorOr<NonnullOwnPtr<KBuffer>> StorageDeviceAttributeSysFSComponent::try_to_generate_buffer() const +{ + OwnPtr<KString> value; + switch (m_type) { + case Type::EndLBA: + value = TRY(KString::formatted("{}", m_device->max_addressable_block())); + break; + case Type::SectorSize: + value = TRY(KString::formatted("{}", m_device->block_size())); + break; + case Type::CommandSet: + value = TRY(KString::formatted("{}", m_device->command_set_to_string_view())); + break; + case Type::InterfaceType: + value = TRY(KString::formatted("{}", m_device->interface_type_to_string_view())); + break; + default: + VERIFY_NOT_REACHED(); + } + return KBuffer::try_create_with_bytes("SysFS StorageDeviceAttributeComponent buffer"sv, value->view().bytes()); +} +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/DeviceAttribute.h b/Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/DeviceAttribute.h new file mode 100644 index 0000000000..f9c769e224 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/DeviceAttribute.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <Kernel/FileSystem/SysFS/Component.h> +#include <Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/DeviceDirectory.h> +#include <Kernel/KBuffer.h> + +namespace Kernel { + +class StorageDeviceAttributeSysFSComponent : public SysFSComponent { +public: + enum class Type { + EndLBA, + SectorSize, + CommandSet, + InterfaceType, + }; + +public: + static NonnullRefPtr<StorageDeviceAttributeSysFSComponent> must_create(StorageDeviceSysFSDirectory const& device_directory, Type); + + virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const override; + virtual ~StorageDeviceAttributeSysFSComponent() {}; + + virtual StringView name() const override; + +protected: + ErrorOr<NonnullOwnPtr<KBuffer>> try_to_generate_buffer() const; + StorageDeviceAttributeSysFSComponent(StorageDeviceSysFSDirectory const& device, Type); + NonnullRefPtr<StorageDevice> m_device; + Type const m_type { Type::EndLBA }; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/DeviceDirectory.cpp b/Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/DeviceDirectory.cpp new file mode 100644 index 0000000000..87e0efa6ef --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/DeviceDirectory.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <Kernel/Bus/PCI/API.h> +#include <Kernel/Bus/PCI/Access.h> +#include <Kernel/Debug.h> +#include <Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/DeviceAttribute.h> +#include <Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/DeviceDirectory.h> +#include <Kernel/Sections.h> +#include <Kernel/Storage/StorageDevice.h> + +namespace Kernel { + +StorageDevice const& StorageDeviceSysFSDirectory::device(Badge<StorageDeviceAttributeSysFSComponent>) const +{ + return *m_device; +} + +UNMAP_AFTER_INIT NonnullRefPtr<StorageDeviceSysFSDirectory> StorageDeviceSysFSDirectory::create(SysFSDirectory const& parent_directory, StorageDevice const& device) +{ + // FIXME: Handle allocation failure gracefully + auto lun_address = device.logical_unit_number_address(); + auto device_name = MUST(KString::formatted("{:02x}:{:02x}.{}", lun_address.controller_id, lun_address.target_id, lun_address.disk_id)); + auto directory = adopt_ref(*new (nothrow) StorageDeviceSysFSDirectory(move(device_name), parent_directory, device)); + MUST(directory->m_child_components.with([&](auto& list) -> ErrorOr<void> { + list.append(StorageDeviceAttributeSysFSComponent::must_create(*directory, StorageDeviceAttributeSysFSComponent::Type::EndLBA)); + list.append(StorageDeviceAttributeSysFSComponent::must_create(*directory, StorageDeviceAttributeSysFSComponent::Type::SectorSize)); + list.append(StorageDeviceAttributeSysFSComponent::must_create(*directory, StorageDeviceAttributeSysFSComponent::Type::CommandSet)); + list.append(StorageDeviceAttributeSysFSComponent::must_create(*directory, StorageDeviceAttributeSysFSComponent::Type::InterfaceType)); + return {}; + })); + return directory; +} + +UNMAP_AFTER_INIT StorageDeviceSysFSDirectory::StorageDeviceSysFSDirectory(NonnullOwnPtr<KString> device_directory_name, SysFSDirectory const& parent_directory, StorageDevice const& device) + : SysFSDirectory(parent_directory) + , m_device(device) + , m_device_directory_name(move(device_directory_name)) +{ +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/DeviceDirectory.h b/Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/DeviceDirectory.h new file mode 100644 index 0000000000..b06ed67ad9 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/DeviceDirectory.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <Kernel/FileSystem/SysFS/Component.h> +#include <Kernel/KString.h> +#include <Kernel/Storage/StorageDevice.h> + +namespace Kernel { + +class StorageDeviceAttributeSysFSComponent; +class StorageDeviceSysFSDirectory final : public SysFSDirectory { +public: + static NonnullRefPtr<StorageDeviceSysFSDirectory> create(SysFSDirectory const&, StorageDevice const&); + + virtual StringView name() const override { return m_device_directory_name->view(); } + + StorageDevice const& device(Badge<StorageDeviceAttributeSysFSComponent>) const; + +private: + StorageDeviceSysFSDirectory(NonnullOwnPtr<KString> device_directory_name, SysFSDirectory const&, StorageDevice const&); + RefPtr<StorageDevice> m_device; + NonnullOwnPtr<KString> m_device_directory_name; +}; + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/Directory.cpp b/Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/Directory.cpp new file mode 100644 index 0000000000..8bd4c2ace8 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/Directory.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <Kernel/FileSystem/SysFS/RootDirectory.h> +#include <Kernel/FileSystem/SysFS/Subsystems/Devices/Directory.h> +#include <Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/DeviceDirectory.h> +#include <Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/Directory.h> +#include <Kernel/Sections.h> +#include <Kernel/Storage/StorageDevice.h> + +namespace Kernel { + +static SysFSStorageDirectory* s_the { nullptr }; + +UNMAP_AFTER_INIT NonnullRefPtr<SysFSStorageDirectory> SysFSStorageDirectory::must_create(SysFSDevicesDirectory const& parent_directory) +{ + auto directory = adopt_ref(*new (nothrow) SysFSStorageDirectory(parent_directory)); + s_the = directory; + return directory; +} + +SysFSStorageDirectory& SysFSStorageDirectory::the() +{ + VERIFY(s_the); + return *s_the; +} + +void SysFSStorageDirectory::plug(Badge<StorageDevice>, StorageDeviceSysFSDirectory& new_device_directory) +{ + MUST(m_child_components.with([&](auto& list) -> ErrorOr<void> { + list.append(new_device_directory); + auto pointed_component_base_name = MUST(KString::try_create(new_device_directory.name())); + auto pointed_component_relative_path = MUST(new_device_directory.relative_path(move(pointed_component_base_name), 0)); + return {}; + })); +} +void SysFSStorageDirectory::unplug(Badge<StorageDevice>, SysFSDirectory& removed_device_directory) +{ + MUST(m_child_components.with([&](auto& list) -> ErrorOr<void> { + list.remove(removed_device_directory); + return {}; + })); +} + +UNMAP_AFTER_INIT SysFSStorageDirectory::SysFSStorageDirectory(SysFSDevicesDirectory const& parent_directory) + : SysFSDirectory(parent_directory) +{ +} + +} diff --git a/Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/Directory.h b/Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/Directory.h new file mode 100644 index 0000000000..80170fb901 --- /dev/null +++ b/Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/Directory.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <Kernel/FileSystem/SysFS/Component.h> +#include <Kernel/Forward.h> + +namespace Kernel { + +class StorageDeviceSysFSDirectory; +class StorageDevice; +class SysFSStorageDirectory : public SysFSDirectory { + friend class SysFSComponentRegistry; + +public: + virtual StringView name() const override { return "storage"sv; } + static SysFSStorageDirectory& the(); + static NonnullRefPtr<SysFSStorageDirectory> must_create(SysFSDevicesDirectory const&); + + void plug(Badge<StorageDevice>, StorageDeviceSysFSDirectory&); + void unplug(Badge<StorageDevice>, SysFSDirectory&); + +private: + explicit SysFSStorageDirectory(SysFSDevicesDirectory const&); +}; + +} diff --git a/Kernel/Forward.h b/Kernel/Forward.h index 3b27605c8f..2362940352 100644 --- a/Kernel/Forward.h +++ b/Kernel/Forward.h @@ -56,6 +56,7 @@ class SysFS; class SysFSDirectory; class SysFSRootDirectory; class SysFSBusDirectory; +class SysFSDevicesDirectory; class SysFSDirectoryInode; class SysFSInode; class TCPSocket; diff --git a/Kernel/Storage/StorageDevice.cpp b/Kernel/Storage/StorageDevice.cpp index 8ca455ea81..991962878c 100644 --- a/Kernel/Storage/StorageDevice.cpp +++ b/Kernel/Storage/StorageDevice.cpp @@ -7,7 +7,12 @@ #include <AK/Memory.h> #include <AK/StringView.h> #include <Kernel/Debug.h> +#include <Kernel/Devices/DeviceManagement.h> #include <Kernel/FileSystem/OpenFileDescription.h> +#include <Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/BlockDevicesDirectory.h> +#include <Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/SymbolicLinkDeviceComponent.h> +#include <Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/DeviceDirectory.h> +#include <Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/Directory.h> #include <Kernel/Storage/StorageDevice.h> #include <Kernel/Storage/StorageManagement.h> #include <LibC/sys/ioctl_numbers.h> @@ -23,6 +28,33 @@ StorageDevice::StorageDevice(LUNAddress logical_unit_number_address, MajorNumber { } +void StorageDevice::after_inserting() +{ + after_inserting_add_to_device_management(); + auto sysfs_storage_device_directory = StorageDeviceSysFSDirectory::create(SysFSStorageDirectory::the(), *this); + m_sysfs_device_directory = sysfs_storage_device_directory; + SysFSStorageDirectory::the().plug({}, *sysfs_storage_device_directory); + VERIFY(!m_symlink_sysfs_component); + auto sys_fs_component = MUST(SysFSSymbolicLinkDeviceComponent::try_create(SysFSDeviceIdentifiersDirectory::the(), *this, *m_sysfs_device_directory)); + m_symlink_sysfs_component = sys_fs_component; + VERIFY(is_block_device()); + SysFSBlockDevicesDirectory::the().m_child_components.with([&](auto& list) -> void { + list.append(sys_fs_component); + }); +} + +void StorageDevice::will_be_destroyed() +{ + VERIFY(m_symlink_sysfs_component); + VERIFY(is_block_device()); + SysFSBlockDevicesDirectory::the().m_child_components.with([&](auto& list) -> void { + list.remove(*m_symlink_sysfs_component); + }); + m_symlink_sysfs_component.clear(); + SysFSStorageDirectory::the().unplug({}, *m_sysfs_device_directory); + before_will_be_destroyed_remove_from_device_management(); +} + StringView StorageDevice::class_name() const { return "StorageDevice"sv; diff --git a/Kernel/Storage/StorageDevice.h b/Kernel/Storage/StorageDevice.h index eb06214a80..c0fb061c91 100644 --- a/Kernel/Storage/StorageDevice.h +++ b/Kernel/Storage/StorageDevice.h @@ -17,6 +17,7 @@ namespace Kernel { class StorageDevice : public BlockDevice { friend class StorageManagement; + friend class DeviceManagement; public: // Note: this attribute describes the internal command set of a Storage device. @@ -92,6 +93,9 @@ protected: virtual StringView class_name() const override; private: + virtual void after_inserting() override; + virtual void will_be_destroyed() override; + virtual InterfaceType interface_type() const = 0; mutable IntrusiveListNode<StorageDevice, RefPtr<StorageDevice>> m_list_node; NonnullRefPtrVector<DiskPartition> m_partitions; |