summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiav A <liavalb@gmail.com>2022-04-23 11:48:40 +0300
committerAndreas Kling <kling@serenityos.org>2022-07-15 12:29:23 +0200
commit1dbd32488f746a27c6a98f84abb96bdfd8578444 (patch)
tree69028bb07608696b8537f966218cd74a2b15acd2
parent22335e53e0a3bfde31bb48514301eabcd17468c6 (diff)
downloadserenity-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.
-rw-r--r--Kernel/CMakeLists.txt5
-rw-r--r--Kernel/Devices/Device.h5
-rw-r--r--Kernel/FileSystem/SysFS/RootDirectory.cpp3
-rw-r--r--Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/BlockDevicesDirectory.h4
-rw-r--r--Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/Directory.cpp10
-rw-r--r--Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/Directory.h2
-rw-r--r--Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/SymbolicLinkDeviceComponent.cpp27
-rw-r--r--Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/SymbolicLinkDeviceComponent.h33
-rw-r--r--Kernel/FileSystem/SysFS/Subsystems/Devices/Directory.cpp28
-rw-r--r--Kernel/FileSystem/SysFS/Subsystems/Devices/Directory.h23
-rw-r--r--Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/DeviceAttribute.cpp76
-rw-r--r--Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/DeviceAttribute.h39
-rw-r--r--Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/DeviceDirectory.cpp45
-rw-r--r--Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/DeviceDirectory.h30
-rw-r--r--Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/Directory.cpp53
-rw-r--r--Kernel/FileSystem/SysFS/Subsystems/Devices/Storage/Directory.h31
-rw-r--r--Kernel/Forward.h1
-rw-r--r--Kernel/Storage/StorageDevice.cpp32
-rw-r--r--Kernel/Storage/StorageDevice.h4
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;