ladybird/Kernel/Devices/Device.cpp
Liav A 25bb293629 Kernel: Make Device::after_inserting to return ErrorOr<void>
Instead of just returning nothing, let's return Error or nothing.
This would help later on with error propagation in case of failure
during this method.

This also makes us more paranoid about failure in this method, so when
initializing a DisplayConnector we safely tear down the internal members
of the object. This applies the same for a StorageDevice object, but its
after_inserting method is much smaller compared to the DisplayConnector
overriden method.
2023-01-07 11:45:08 -07:00

87 lines
2.4 KiB
C++

/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Singleton.h>
#include <Kernel/Devices/Device.h>
#include <Kernel/Devices/DeviceManagement.h>
#include <Kernel/FileSystem/InodeMetadata.h>
#include <Kernel/FileSystem/SysFS/Component.h>
#include <Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/BlockDevicesDirectory.h>
#include <Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/CharacterDevicesDirectory.h>
#include <Kernel/Sections.h>
namespace Kernel {
Device::Device(MajorNumber major, MinorNumber minor)
: m_major(major)
, m_minor(minor)
{
}
void Device::before_will_be_destroyed_remove_from_device_management()
{
DeviceManagement::the().before_device_removal({}, *this);
m_state = State::BeingRemoved;
}
void Device::after_inserting_add_to_device_management()
{
DeviceManagement::the().after_inserting_device({}, *this);
}
ErrorOr<void> Device::after_inserting()
{
after_inserting_add_to_device_management();
VERIFY(!m_sysfs_component);
auto sys_fs_component = SysFSDeviceComponent::must_create(*this);
m_sysfs_component = sys_fs_component;
after_inserting_add_to_device_identifier_directory();
return {};
}
void Device::will_be_destroyed()
{
VERIFY(m_sysfs_component);
before_will_be_destroyed_remove_from_device_identifier_directory();
before_will_be_destroyed_remove_from_device_management();
}
Device::~Device()
{
VERIFY(m_state == State::BeingRemoved);
}
ErrorOr<NonnullOwnPtr<KString>> Device::pseudo_path(OpenFileDescription const&) const
{
return KString::formatted("device:{},{}", major(), minor());
}
ErrorOr<NonnullLockRefPtr<OpenFileDescription>> Device::open(int options)
{
TRY(Process::current().jail().with([&](auto const& my_jail) -> ErrorOr<void> {
if (my_jail && !is_openable_by_jailed_processes())
return Error::from_errno(EPERM);
return {};
}));
return File::open(options);
}
void Device::process_next_queued_request(Badge<AsyncDeviceRequest>, AsyncDeviceRequest const& completed_request)
{
SpinlockLocker lock(m_requests_lock);
VERIFY(!m_requests.is_empty());
VERIFY(m_requests.first().ptr() == &completed_request);
m_requests.remove(m_requests.begin());
if (!m_requests.is_empty()) {
auto* next_request = m_requests.first().ptr();
next_request->do_start(move(lock));
}
evaluate_block_conditions();
}
}