Device.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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.h>
  11. #include <Kernel/Sections.h>
  12. namespace Kernel {
  13. NonnullRefPtr<SysFSDeviceComponent> SysFSDeviceComponent::must_create(Device const& device)
  14. {
  15. // FIXME: Handle allocation failure gracefully
  16. auto device_name = MUST(KString::try_create(String::formatted("{}:{}", device.major(), device.minor())));
  17. return adopt_ref_if_nonnull(new SysFSDeviceComponent(move(device_name), device)).release_nonnull();
  18. }
  19. SysFSDeviceComponent::SysFSDeviceComponent(NonnullOwnPtr<KString> major_minor_formatted_device_name, Device const& device)
  20. : SysFSComponent()
  21. , m_block_device(device.is_block_device())
  22. , m_major_minor_formatted_device_name(move(major_minor_formatted_device_name))
  23. {
  24. VERIFY(device.is_block_device() || device.is_character_device());
  25. }
  26. UNMAP_AFTER_INIT NonnullRefPtr<SysFSDevicesDirectory> SysFSDevicesDirectory::must_create(SysFSRootDirectory const& root_directory)
  27. {
  28. auto devices_directory = adopt_ref_if_nonnull(new SysFSDevicesDirectory(root_directory)).release_nonnull();
  29. devices_directory->m_components.append(SysFSBlockDevicesDirectory::must_create(*devices_directory));
  30. devices_directory->m_components.append(SysFSCharacterDevicesDirectory::must_create(*devices_directory));
  31. return devices_directory;
  32. }
  33. SysFSDevicesDirectory::SysFSDevicesDirectory(SysFSRootDirectory const& root_directory)
  34. : SysFSDirectory(root_directory)
  35. {
  36. }
  37. NonnullRefPtr<SysFSBlockDevicesDirectory> SysFSBlockDevicesDirectory::must_create(SysFSDevicesDirectory const& devices_directory)
  38. {
  39. return adopt_ref_if_nonnull(new SysFSBlockDevicesDirectory(devices_directory)).release_nonnull();
  40. }
  41. SysFSBlockDevicesDirectory::SysFSBlockDevicesDirectory(SysFSDevicesDirectory const& devices_directory)
  42. : SysFSDirectory(devices_directory)
  43. {
  44. }
  45. ErrorOr<void> SysFSBlockDevicesDirectory::traverse_as_directory(FileSystemID fsid, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
  46. {
  47. VERIFY(m_parent_directory);
  48. TRY(callback({ ".", { fsid, component_index() }, 0 }));
  49. TRY(callback({ "..", { fsid, m_parent_directory->component_index() }, 0 }));
  50. return SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> ErrorOr<void> {
  51. for (auto& exposed_device : list) {
  52. if (!exposed_device.is_block_device())
  53. continue;
  54. TRY(callback({ exposed_device.name(), { fsid, exposed_device.component_index() }, 0 }));
  55. }
  56. return {};
  57. });
  58. }
  59. RefPtr<SysFSComponent> SysFSBlockDevicesDirectory::lookup(StringView name)
  60. {
  61. return SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> RefPtr<SysFSComponent> {
  62. for (auto& exposed_device : list) {
  63. if (!exposed_device.is_block_device())
  64. continue;
  65. if (exposed_device.name() == name)
  66. return exposed_device;
  67. }
  68. return nullptr;
  69. });
  70. }
  71. NonnullRefPtr<SysFSCharacterDevicesDirectory> SysFSCharacterDevicesDirectory::must_create(SysFSDevicesDirectory const& devices_directory)
  72. {
  73. return adopt_ref_if_nonnull(new SysFSCharacterDevicesDirectory(devices_directory)).release_nonnull();
  74. }
  75. SysFSCharacterDevicesDirectory::SysFSCharacterDevicesDirectory(SysFSDevicesDirectory const& devices_directory)
  76. : SysFSDirectory(devices_directory)
  77. {
  78. }
  79. ErrorOr<void> SysFSCharacterDevicesDirectory::traverse_as_directory(FileSystemID fsid, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const
  80. {
  81. VERIFY(m_parent_directory);
  82. TRY(callback({ ".", { fsid, component_index() }, 0 }));
  83. TRY(callback({ "..", { fsid, m_parent_directory->component_index() }, 0 }));
  84. return SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> ErrorOr<void> {
  85. for (auto& exposed_device : list) {
  86. if (exposed_device.is_block_device())
  87. continue;
  88. TRY(callback({ exposed_device.name(), { fsid, exposed_device.component_index() }, 0 }));
  89. }
  90. return {};
  91. });
  92. }
  93. RefPtr<SysFSComponent> SysFSCharacterDevicesDirectory::lookup(StringView name)
  94. {
  95. return SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> RefPtr<SysFSComponent> {
  96. for (auto& exposed_device : list) {
  97. if (exposed_device.is_block_device())
  98. continue;
  99. if (exposed_device.name() == name)
  100. return exposed_device;
  101. }
  102. return nullptr;
  103. });
  104. }
  105. Device::Device(MajorNumber major, MinorNumber minor)
  106. : m_major(major)
  107. , m_minor(minor)
  108. {
  109. }
  110. void Device::after_inserting()
  111. {
  112. DeviceManagement::the().after_inserting_device({}, *this);
  113. VERIFY(!m_sysfs_component);
  114. auto sys_fs_component = SysFSDeviceComponent::must_create(*this);
  115. m_sysfs_component = sys_fs_component;
  116. SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> void {
  117. list.append(sys_fs_component);
  118. });
  119. }
  120. void Device::before_removing()
  121. {
  122. VERIFY(m_sysfs_component);
  123. SysFSComponentRegistry::the().devices_list().with_exclusive([&](auto& list) -> void {
  124. list.remove(*m_sysfs_component);
  125. });
  126. DeviceManagement::the().before_device_removal({}, *this);
  127. m_state = State::BeingRemoved;
  128. }
  129. Device::~Device()
  130. {
  131. VERIFY(m_state == State::BeingRemoved);
  132. }
  133. ErrorOr<NonnullOwnPtr<KString>> Device::pseudo_path(const OpenFileDescription&) const
  134. {
  135. return KString::formatted("device:{},{}", major(), minor());
  136. }
  137. void Device::process_next_queued_request(Badge<AsyncDeviceRequest>, const AsyncDeviceRequest& completed_request)
  138. {
  139. SpinlockLocker lock(m_requests_lock);
  140. VERIFY(!m_requests.is_empty());
  141. VERIFY(m_requests.first().ptr() == &completed_request);
  142. m_requests.remove(m_requests.begin());
  143. if (!m_requests.is_empty()) {
  144. auto* next_request = m_requests.first().ptr();
  145. next_request->do_start(move(lock));
  146. }
  147. evaluate_block_conditions();
  148. }
  149. }