2023-07-05 23:19:25 -07:00
|
|
|
#include "fs/ext2/ext2_block_reader.h"
|
|
|
|
|
2023-11-22 14:39:27 -08:00
|
|
|
#include <mammoth/util/debug.h>
|
2023-10-24 18:24:26 -07:00
|
|
|
|
2023-08-01 10:39:26 -07:00
|
|
|
glcr::ErrorOr<glcr::SharedPtr<Ext2BlockReader>> Ext2BlockReader::Init(
|
2023-11-15 09:47:32 -08:00
|
|
|
const DenaliInfo& denali_info) {
|
2023-07-05 23:19:25 -07:00
|
|
|
// Read 1024 bytes from 1024 offset.
|
|
|
|
// FIXME: Don't assume 512 byte sectors somehow.
|
2023-11-15 09:47:32 -08:00
|
|
|
DenaliClient client(denali_info.denali_endpoint());
|
|
|
|
ReadRequest req;
|
|
|
|
req.set_device_id(denali_info.device_id());
|
|
|
|
req.set_lba(denali_info.lba_offset() + 2);
|
|
|
|
req.set_size(2);
|
|
|
|
ReadResponse resp;
|
|
|
|
RET_ERR(client.Read(req, resp));
|
2023-11-22 14:59:41 -08:00
|
|
|
mmth::OwnedMemoryRegion superblock =
|
|
|
|
mmth::OwnedMemoryRegion::FromCapability(resp.memory());
|
2023-11-15 09:47:32 -08:00
|
|
|
|
2023-08-01 10:39:26 -07:00
|
|
|
return glcr::SharedPtr<Ext2BlockReader>(
|
2023-11-15 09:47:32 -08:00
|
|
|
new Ext2BlockReader(glcr::Move(client), denali_info.device_id(),
|
2023-11-19 20:33:15 -08:00
|
|
|
denali_info.lba_offset(), glcr::Move(superblock)));
|
2023-07-05 23:19:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
Superblock* Ext2BlockReader::GetSuperblock() {
|
|
|
|
return reinterpret_cast<Superblock*>(super_block_region_.vaddr());
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t Ext2BlockReader::SectorsPerBlock() {
|
|
|
|
return 1 << (GetSuperblock()->log_block_size + 1);
|
|
|
|
}
|
|
|
|
|
2023-07-06 09:58:26 -07:00
|
|
|
uint64_t Ext2BlockReader::BlockSize() {
|
|
|
|
return 1024 << (GetSuperblock()->log_block_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t Ext2BlockReader::NumberOfBlockGroups() {
|
|
|
|
return ((GetSuperblock()->blocks_count - 1) /
|
|
|
|
GetSuperblock()->blocks_per_group) +
|
|
|
|
1;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t Ext2BlockReader::BgdtBlockNum() {
|
|
|
|
return (BlockSize() == 1024) ? 2 : 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t Ext2BlockReader::BgdtBlockSize() {
|
|
|
|
return ((NumberOfBlockGroups() * sizeof(BlockGroupDescriptor) - 1) /
|
|
|
|
BlockSize()) +
|
|
|
|
1;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t Ext2BlockReader::InodeSize() {
|
|
|
|
constexpr uint64_t kDefaultInodeSize = 0x80;
|
|
|
|
return GetSuperblock()->rev_level >= 1 ? GetSuperblock()->inode_size
|
|
|
|
: kDefaultInodeSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t Ext2BlockReader::InodeTableBlockSize() {
|
|
|
|
return (InodeSize() * GetSuperblock()->inodes_per_group) / BlockSize();
|
|
|
|
}
|
|
|
|
|
2023-11-22 14:59:41 -08:00
|
|
|
glcr::ErrorOr<mmth::OwnedMemoryRegion> Ext2BlockReader::ReadBlock(
|
2023-07-05 23:19:25 -07:00
|
|
|
uint64_t block_number) {
|
2023-11-15 09:47:32 -08:00
|
|
|
return ReadBlocks(block_number, 1);
|
2023-07-05 23:19:25 -07:00
|
|
|
}
|
2023-11-22 14:59:41 -08:00
|
|
|
glcr::ErrorOr<mmth::OwnedMemoryRegion> Ext2BlockReader::ReadBlocks(
|
2023-07-05 23:19:25 -07:00
|
|
|
uint64_t block_number, uint64_t num_blocks) {
|
2023-11-15 09:47:32 -08:00
|
|
|
ReadRequest req;
|
|
|
|
req.set_device_id(device_id_);
|
|
|
|
req.set_lba(lba_offset_ + block_number * SectorsPerBlock());
|
|
|
|
req.set_size(num_blocks * SectorsPerBlock());
|
|
|
|
ReadResponse resp;
|
|
|
|
RET_ERR(denali_.Read(req, resp));
|
2023-11-22 14:59:41 -08:00
|
|
|
return mmth::OwnedMemoryRegion::FromCapability(resp.memory());
|
2023-11-15 09:47:32 -08:00
|
|
|
}
|
|
|
|
|
2023-11-22 14:59:41 -08:00
|
|
|
glcr::ErrorOr<mmth::OwnedMemoryRegion> Ext2BlockReader::ReadBlocks(
|
2023-11-15 09:47:32 -08:00
|
|
|
const glcr::Vector<uint64_t>& block_list) {
|
|
|
|
ReadManyRequest req;
|
|
|
|
req.set_device_id(device_id_);
|
|
|
|
for (uint64_t i = 0; i < block_list.size(); i++) {
|
2023-11-22 12:17:56 -08:00
|
|
|
uint64_t curr_start = lba_offset_ + block_list.at(i) * SectorsPerBlock();
|
|
|
|
uint64_t curr_run_len = 1;
|
|
|
|
while ((i + 1) < block_list.size() &&
|
|
|
|
block_list.at(i + 1) == block_list.at(i) + 1) {
|
|
|
|
i++;
|
|
|
|
curr_run_len++;
|
2023-11-15 09:47:32 -08:00
|
|
|
}
|
2023-11-22 12:17:56 -08:00
|
|
|
req.add_lba(curr_start);
|
|
|
|
req.add_sector_cnt(curr_run_len * SectorsPerBlock());
|
|
|
|
dbgln("Read {x}, {x}", curr_start, curr_run_len * SectorsPerBlock());
|
2023-11-15 09:47:32 -08:00
|
|
|
}
|
2023-11-22 12:17:56 -08:00
|
|
|
dbgln("Read many: {x}", req.lba().size());
|
2023-11-15 09:47:32 -08:00
|
|
|
ReadResponse resp;
|
|
|
|
RET_ERR(denali_.ReadMany(req, resp));
|
2023-11-22 14:59:41 -08:00
|
|
|
return mmth::OwnedMemoryRegion::FromCapability(resp.memory());
|
2023-07-05 23:19:25 -07:00
|
|
|
}
|
|
|
|
|
2023-11-15 09:47:32 -08:00
|
|
|
Ext2BlockReader::Ext2BlockReader(DenaliClient&& denali, uint64_t device_id,
|
|
|
|
uint64_t lba_offset,
|
2023-11-22 14:59:41 -08:00
|
|
|
mmth::OwnedMemoryRegion&& super_block)
|
2023-11-15 09:47:32 -08:00
|
|
|
: denali_(glcr::Move(denali)),
|
|
|
|
device_id_(device_id),
|
|
|
|
lba_offset_(lba_offset),
|
2023-11-19 20:33:15 -08:00
|
|
|
super_block_region_(glcr::Move(super_block)) {}
|