Serenity Operating System
at master 86 lines 2.5 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/Singleton.h> 8#include <Kernel/Devices/Device.h> 9#include <Kernel/Devices/DeviceManagement.h> 10#include <Kernel/FileSystem/InodeMetadata.h> 11#include <Kernel/FileSystem/SysFS/Component.h> 12#include <Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/BlockDevicesDirectory.h> 13#include <Kernel/FileSystem/SysFS/Subsystems/DeviceIdentifiers/CharacterDevicesDirectory.h> 14#include <Kernel/Sections.h> 15 16namespace Kernel { 17 18Device::Device(MajorNumber major, MinorNumber minor) 19 : m_major(major) 20 , m_minor(minor) 21{ 22} 23 24void Device::before_will_be_destroyed_remove_from_device_management() 25{ 26 DeviceManagement::the().before_device_removal({}, *this); 27 m_state = State::BeingRemoved; 28} 29 30void Device::after_inserting_add_to_device_management() 31{ 32 DeviceManagement::the().after_inserting_device({}, *this); 33} 34 35ErrorOr<void> Device::after_inserting() 36{ 37 after_inserting_add_to_device_management(); 38 VERIFY(!m_sysfs_component); 39 auto sys_fs_component = SysFSDeviceComponent::must_create(*this); 40 m_sysfs_component = sys_fs_component; 41 after_inserting_add_to_device_identifier_directory(); 42 return {}; 43} 44 45void Device::will_be_destroyed() 46{ 47 VERIFY(m_sysfs_component); 48 before_will_be_destroyed_remove_from_device_identifier_directory(); 49 before_will_be_destroyed_remove_from_device_management(); 50} 51 52Device::~Device() 53{ 54 VERIFY(m_state == State::BeingRemoved); 55} 56 57ErrorOr<NonnullOwnPtr<KString>> Device::pseudo_path(OpenFileDescription const&) const 58{ 59 return KString::formatted("device:{},{}", major(), minor()); 60} 61 62ErrorOr<NonnullRefPtr<OpenFileDescription>> Device::open(int options) 63{ 64 TRY(Process::current().jail().with([&](auto const& my_jail) -> ErrorOr<void> { 65 if (my_jail && !is_openable_by_jailed_processes()) 66 return Error::from_errno(EPERM); 67 return {}; 68 })); 69 return File::open(options); 70} 71 72void Device::process_next_queued_request(Badge<AsyncDeviceRequest>, AsyncDeviceRequest const& completed_request) 73{ 74 SpinlockLocker lock(m_requests_lock); 75 VERIFY(!m_requests.is_empty()); 76 VERIFY(m_requests.first().ptr() == &completed_request); 77 m_requests.remove(m_requests.begin()); 78 if (!m_requests.is_empty()) { 79 auto* next_request = m_requests.first().ptr(); 80 next_request->do_start(move(lock)); 81 } 82 83 evaluate_block_conditions(); 84} 85 86}