Kernel: Remove storage devices after unplugging them

This commit is contained in:
2025-02-07 18:04:54 +02:00
parent 26d2a4420e
commit 267fdf9fa1
5 changed files with 38 additions and 14 deletions

View File

@@ -16,6 +16,7 @@ namespace Kernel
Partition::Partition(BAN::RefPtr<BlockDevice> device, const BAN::GUID& type, const BAN::GUID& guid, uint64_t first_block, uint64_t last_block, uint64_t attr, const char* label, uint32_t index, BAN::StringView name_prefix)
: BlockDevice(0660, 0, 0)
, m_device(device)
, m_block_size(device->blksize())
, m_type(type)
, m_guid(guid)
, m_guid_string(MUST(guid.to_string()))
@@ -30,30 +31,42 @@ namespace Kernel
BAN::ErrorOr<void> Partition::read_blocks(uint64_t first_block, size_t block_count, BAN::ByteSpan buffer)
{
ASSERT(buffer.size() >= block_count * m_device->blksize());
auto device = m_device.lock();
if (!device)
return BAN::Error::from_errno(ENODEV);
ASSERT(buffer.size() >= block_count * device->blksize());
const uint32_t blocks_in_partition = m_last_block - m_first_block + 1;
if (first_block + block_count > blocks_in_partition)
return BAN::Error::from_error_code(ErrorCode::Storage_Boundaries);
TRY(m_device->read_blocks(m_first_block + first_block, block_count, buffer));
TRY(device->read_blocks(m_first_block + first_block, block_count, buffer));
return {};
}
BAN::ErrorOr<void> Partition::write_blocks(uint64_t first_block, size_t block_count, BAN::ConstByteSpan buffer)
{
ASSERT(buffer.size() >= block_count * m_device->blksize());
auto device = m_device.lock();
if (!device)
return BAN::Error::from_errno(ENODEV);
ASSERT(buffer.size() >= block_count * device->blksize());
const uint32_t blocks_in_partition = m_last_block - m_first_block + 1;
if (first_block + block_count > blocks_in_partition)
return BAN::Error::from_error_code(ErrorCode::Storage_Boundaries);
TRY(m_device->write_blocks(m_first_block + first_block, block_count, buffer));
TRY(device->write_blocks(m_first_block + first_block, block_count, buffer));
return {};
}
BAN::ErrorOr<void> Partition::sync_blocks(uint64_t block, size_t block_count)
{
auto device = m_device.lock();
if (!device)
return BAN::Error::from_errno(ENODEV);
const uint32_t blocks_in_partition = m_last_block - m_first_block + 1;
if (block + block_count > blocks_in_partition)
return BAN::Error::from_error_code(ErrorCode::Storage_Boundaries);
TRY(m_device->sync_blocks(m_first_block + block, block_count));
TRY(device->sync_blocks(m_first_block + block, block_count));
return {};
}
@@ -61,12 +74,16 @@ namespace Kernel
{
ASSERT(offset >= 0);
if (offset % m_device->blksize() || buffer.size() % m_device->blksize())
auto device = m_device.lock();
if (!device)
return BAN::Error::from_errno(ENODEV);
if (offset % device->blksize() || buffer.size() % device->blksize())
return BAN::Error::from_errno(ENOTSUP);
const uint32_t blocks_in_partition = m_last_block - m_first_block + 1;
uint32_t first_block = offset / m_device->blksize();
uint32_t block_count = buffer.size() / m_device->blksize();
uint32_t first_block = offset / device->blksize();
uint32_t block_count = buffer.size() / device->blksize();
if (first_block >= blocks_in_partition)
return 0;
@@ -74,7 +91,7 @@ namespace Kernel
block_count = blocks_in_partition - first_block;
TRY(read_blocks(first_block, block_count, buffer));
return block_count * m_device->blksize();
return block_count * device->blksize();
}
}

View File

@@ -204,6 +204,9 @@ namespace Kernel
StorageDevice::~StorageDevice()
{
for (auto& partition : m_partitions)
if (partition)
DevFileSystem::get().remove_device(partition);
}
void StorageDevice::add_disk_cache()