Kernel: Add common {read,write}_blocks() api to BlockDevice
This commit is contained in:
parent
6a068fb9f9
commit
b749963b62
|
@ -25,6 +25,12 @@ namespace Kernel
|
|||
|
||||
class BlockDevice : public Device
|
||||
{
|
||||
public:
|
||||
virtual BAN::ErrorOr<void> read_blocks(uint64_t first_block, size_t block_count, BAN::ByteSpan) = 0;
|
||||
virtual BAN::ErrorOr<void> write_blocks(uint64_t first_block, size_t block_count, BAN::ConstByteSpan) = 0;
|
||||
|
||||
virtual blksize_t blksize() const = 0;
|
||||
|
||||
protected:
|
||||
BlockDevice(mode_t mode, uid_t uid, gid_t gid)
|
||||
: Device(mode, uid, gid)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <BAN/HashMap.h>
|
||||
#include <kernel/Storage/StorageDevice.h>
|
||||
#include <kernel/Storage/Partition.h>
|
||||
#include <kernel/FS/FileSystem.h>
|
||||
#include <kernel/FS/Ext2/Inode.h>
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace Kernel
|
|||
class Partition final : public BlockDevice
|
||||
{
|
||||
public:
|
||||
static BAN::ErrorOr<BAN::RefPtr<Partition>> create(BAN::RefPtr<BlockDevice>, const BAN::GUID& type, const BAN::GUID& guid, uint64_t first_sector, uint64_t last_sector, uint64_t attr, const char* label, uint32_t index);
|
||||
static BAN::ErrorOr<BAN::RefPtr<Partition>> create(BAN::RefPtr<BlockDevice>, 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);
|
||||
|
||||
const BAN::GUID& partition_type() const { return m_type; }
|
||||
const BAN::GUID& partition_guid() const { return m_guid; }
|
||||
|
@ -17,8 +17,11 @@ namespace Kernel
|
|||
|
||||
virtual blksize_t blksize() const { return m_device->blksize(); }
|
||||
|
||||
virtual BAN::ErrorOr<void> read_sectors(uint64_t first_sector, size_t sector_count, BAN::ByteSpan) override;
|
||||
virtual BAN::ErrorOr<void> write_sectors(uint64_t first_sector, size_t sector_count, BAN::ConstByteSpan) override;
|
||||
BAN::ErrorOr<void> read_sectors(uint64_t first_block, size_t block_count, BAN::ByteSpan buffer) { return read_blocks(first_block, block_count, buffer); }
|
||||
BAN::ErrorOr<void> write_sectors(uint64_t first_block, size_t block_count, BAN::ConstByteSpan buffer) { return write_blocks(first_block, block_count, buffer); }
|
||||
|
||||
virtual BAN::ErrorOr<void> read_blocks(uint64_t first_block, size_t block_count, BAN::ByteSpan) override;
|
||||
virtual BAN::ErrorOr<void> write_blocks(uint64_t first_block, size_t block_count, BAN::ConstByteSpan) override;
|
||||
|
||||
virtual BAN::StringView name() const override { return m_name; }
|
||||
|
||||
|
@ -29,8 +32,8 @@ namespace Kernel
|
|||
BAN::RefPtr<BlockDevice> m_device;
|
||||
const BAN::GUID m_type;
|
||||
const BAN::GUID m_guid;
|
||||
const uint64_t m_first_sector;
|
||||
const uint64_t m_last_sector;
|
||||
const uint64_t m_first_block;
|
||||
const uint64_t m_last_block;
|
||||
const uint64_t m_attributes;
|
||||
char m_label[36 * 4 + 1];
|
||||
const BAN::String m_name;
|
||||
|
|
|
@ -18,9 +18,13 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<void> initialize_partitions();
|
||||
|
||||
virtual BAN::ErrorOr<void> read_blocks(uint64_t lba, size_t sector_count, BAN::ByteSpan buffer) override { return read_sectors(lba, sector_count, buffer); }
|
||||
virtual BAN::ErrorOr<void> write_blocks(uint64_t lba, size_t sector_count, BAN::ConstByteSpan buffer) override { return write_sectors(lba, sector_count, buffer); }
|
||||
|
||||
BAN::ErrorOr<void> read_sectors(uint64_t lba, size_t sector_count, BAN::ByteSpan);
|
||||
BAN::ErrorOr<void> write_sectors(uint64_t lba, size_t sector_count, BAN::ConstByteSpan);
|
||||
|
||||
virtual blksize_t blksize() const { return sector_size(); }
|
||||
virtual uint32_t sector_size() const = 0;
|
||||
virtual uint64_t total_size() const = 0;
|
||||
|
||||
|
|
|
@ -5,21 +5,21 @@
|
|||
namespace Kernel
|
||||
{
|
||||
|
||||
BAN::ErrorOr<BAN::RefPtr<Partition>> Partition::create(BAN::RefPtr<BlockDevice> device, const BAN::GUID& type, const BAN::GUID& guid, uint64_t first_sector, uint64_t last_sector, uint64_t attr, const char* label, uint32_t index)
|
||||
BAN::ErrorOr<BAN::RefPtr<Partition>> Partition::create(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)
|
||||
{
|
||||
auto partition_ptr = new Partition(device, type, guid, first_sector, last_sector, attr, label, index);
|
||||
auto partition_ptr = new Partition(device, type, guid, first_block, last_block, attr, label, index);
|
||||
if (partition_ptr == nullptr)
|
||||
return BAN::Error::from_errno(ENOMEM);
|
||||
return BAN::RefPtr<Partition>::adopt(partition_ptr);
|
||||
}
|
||||
|
||||
Partition::Partition(BAN::RefPtr<BlockDevice> device, const BAN::GUID& type, const BAN::GUID& guid, uint64_t first_sector, uint64_t last_sector, uint64_t attr, const char* label, uint32_t index)
|
||||
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)
|
||||
: BlockDevice(0660, 0, 0)
|
||||
, m_device(device)
|
||||
, m_type(type)
|
||||
, m_guid(guid)
|
||||
, m_first_sector(first_sector)
|
||||
, m_last_sector(last_sector)
|
||||
, m_first_block(first_block)
|
||||
, m_last_block(last_block)
|
||||
, m_attributes(attr)
|
||||
, m_name(BAN::String::formatted("{}{}", device->name(), index))
|
||||
, m_rdev(makedev(major(device->rdev()), index))
|
||||
|
@ -27,23 +27,23 @@ namespace Kernel
|
|||
memcpy(m_label, label, sizeof(m_label));
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Partition::read_sectors(uint64_t first_sector, size_t sector_count, BAN::ByteSpan buffer)
|
||||
BAN::ErrorOr<void> Partition::read_blocks(uint64_t first_block, size_t block_count, BAN::ByteSpan buffer)
|
||||
{
|
||||
ASSERT(buffer.size() >= sector_count * m_device->blksize());
|
||||
const uint32_t sectors_in_partition = m_last_sector - m_first_sector + 1;
|
||||
if (first_sector + sector_count > sectors_in_partition)
|
||||
ASSERT(buffer.size() >= block_count * m_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_sectors(m_first_sector + first_sector, sector_count, buffer));
|
||||
TRY(m_device->read_blocks(m_first_block + first_block, block_count, buffer));
|
||||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Partition::write_sectors(uint64_t first_sector, size_t sector_count, BAN::ConstByteSpan buffer)
|
||||
BAN::ErrorOr<void> Partition::write_blocks(uint64_t first_block, size_t block_count, BAN::ConstByteSpan buffer)
|
||||
{
|
||||
ASSERT(buffer.size() >= sector_count * m_device->blksize());
|
||||
const uint32_t sectors_in_partition = m_last_sector - m_first_sector + 1;
|
||||
if (m_first_sector + sector_count > sectors_in_partition)
|
||||
ASSERT(buffer.size() >= block_count * m_device->blksize());
|
||||
const uint32_t blocks_in_partition = m_last_block - m_first_block + 1;
|
||||
if (m_first_block + block_count > blocks_in_partition)
|
||||
return BAN::Error::from_error_code(ErrorCode::Storage_Boundaries);
|
||||
TRY(m_device->write_sectors(m_first_sector + first_sector, sector_count, buffer));
|
||||
TRY(m_device->write_blocks(m_first_block + first_block, block_count, buffer));
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -54,17 +54,17 @@ namespace Kernel
|
|||
if (offset % m_device->blksize() || buffer.size() % m_device->blksize())
|
||||
return BAN::Error::from_errno(ENOTSUP);
|
||||
|
||||
const uint32_t sectors_in_partition = m_last_sector - m_first_sector + 1;
|
||||
uint32_t first_sector = offset / m_device->blksize();
|
||||
uint32_t sector_count = buffer.size() / m_device->blksize();
|
||||
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();
|
||||
|
||||
if (first_sector >= sectors_in_partition)
|
||||
if (first_block >= blocks_in_partition)
|
||||
return 0;
|
||||
if (first_sector + sector_count > sectors_in_partition)
|
||||
sector_count = sectors_in_partition - first_sector;
|
||||
if (first_block + block_count > blocks_in_partition)
|
||||
block_count = blocks_in_partition - first_block;
|
||||
|
||||
TRY(read_sectors(first_sector, sector_count, buffer));
|
||||
return sector_count * m_device->blksize();
|
||||
TRY(read_blocks(first_block, block_count, buffer));
|
||||
return block_count * m_device->blksize();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue