1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 06:37:35 +00:00

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.
This commit is contained in:
Liav A 2022-04-23 11:48:40 +03:00 committed by Andreas Kling
parent 22335e53e0
commit 1dbd32488f
19 changed files with 450 additions and 1 deletions

View file

@ -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());
}
}

View file

@ -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 };
};
}

View file

@ -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))
{
}
}

View file

@ -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;
};
}

View file

@ -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)
{
}
}

View file

@ -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&);
};
}