PartitionableDevice.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. * Copyright (c) 2023, Ben Wiederhake <BenWiederhake.GitHub@gmx.de>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibPartition/PartitionableDevice.h>
  7. #ifndef KERNEL
  8. # include <sys/ioctl.h>
  9. #endif
  10. namespace Partition {
  11. #ifdef KERNEL
  12. ErrorOr<PartitionableDevice> PartitionableDevice::create(Kernel::StorageDevice& device)
  13. {
  14. return PartitionableDevice(device);
  15. }
  16. #else
  17. ErrorOr<PartitionableDevice> PartitionableDevice::create(MaybeOwned<Core::File> device_file)
  18. {
  19. VERIFY(device_file.ptr() != nullptr);
  20. size_t block_size;
  21. int rc = ioctl(device_file->fd(), STORAGE_DEVICE_GET_BLOCK_SIZE, &block_size);
  22. if (rc < 0)
  23. return Error::from_string_view("ioctl on device failed"sv);
  24. return PartitionableDevice(move(device_file), block_size);
  25. }
  26. #endif
  27. #ifdef KERNEL
  28. PartitionableDevice::PartitionableDevice(Kernel::StorageDevice& device)
  29. : m_device(device)
  30. {
  31. }
  32. #else
  33. PartitionableDevice::PartitionableDevice(MaybeOwned<Core::File> device_file, size_t block_size)
  34. : m_device_file(move(device_file))
  35. , m_block_size(block_size)
  36. {
  37. }
  38. #endif
  39. #ifdef KERNEL
  40. PartitionableDevice PartitionableDevice::clone_unowned()
  41. {
  42. return PartitionableDevice(m_device);
  43. }
  44. #else
  45. PartitionableDevice PartitionableDevice::clone_unowned()
  46. {
  47. return PartitionableDevice(MaybeOwned<Core::File>(*m_device_file), m_block_size);
  48. }
  49. #endif
  50. #ifdef KERNEL
  51. ErrorOr<PartitionableDevice> PartitionableDevice::clone_owned()
  52. {
  53. return PartitionableDevice(m_device);
  54. }
  55. #else
  56. ErrorOr<PartitionableDevice> PartitionableDevice::clone_owned()
  57. {
  58. auto cloned_file = TRY(Core::File::adopt_fd(m_device_file->fd(), Core::File::OpenMode::Read, Core::File::ShouldCloseFileDescriptor::No));
  59. return PartitionableDevice(move(cloned_file), m_block_size);
  60. }
  61. #endif
  62. #ifdef KERNEL
  63. size_t PartitionableDevice::block_size() const
  64. {
  65. return m_device.block_size();
  66. }
  67. #else
  68. size_t PartitionableDevice::block_size() const
  69. {
  70. return m_block_size;
  71. }
  72. #endif
  73. #ifdef KERNEL
  74. ErrorOr<void> PartitionableDevice::read_block(size_t block_index, Bytes block_buffer)
  75. {
  76. VERIFY(block_buffer.size() == block_size());
  77. auto buffer = UserOrKernelBuffer::for_kernel_buffer(block_buffer.data());
  78. bool read_successful = m_device.read_block(block_index, buffer);
  79. if (!read_successful)
  80. return Error::from_errno(EIO);
  81. return {};
  82. }
  83. #else
  84. ErrorOr<void> PartitionableDevice::read_block(size_t block_index, Bytes block_buffer)
  85. {
  86. VERIFY(block_buffer.size() == block_size());
  87. TRY(m_device_file->seek(block_index * block_size(), SeekMode::SetPosition));
  88. TRY(m_device_file->read_until_filled(block_buffer));
  89. return {};
  90. }
  91. #endif
  92. }