Device.cpp 2.4 KB

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