[Sys] Successfully spin up a new process from disk.
This commit is contained in:
parent
e5568450c2
commit
7c105c8a31
22 changed files with 415 additions and 191 deletions
|
|
@ -3,12 +3,22 @@
|
|||
#include "mammoth/debug.h"
|
||||
|
||||
glcr::ErrorOr<glcr::SharedPtr<Ext2BlockReader>> Ext2BlockReader::Init(
|
||||
ScopedDenaliClient&& denali) {
|
||||
const DenaliInfo& denali_info) {
|
||||
// Read 1024 bytes from 1024 offset.
|
||||
// FIXME: Don't assume 512 byte sectors somehow.
|
||||
ASSIGN_OR_RETURN(MappedMemoryRegion superblock, denali.ReadSectors(2, 2));
|
||||
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));
|
||||
MappedMemoryRegion superblock =
|
||||
MappedMemoryRegion::FromCapability(resp.memory());
|
||||
|
||||
return glcr::SharedPtr<Ext2BlockReader>(
|
||||
new Ext2BlockReader(glcr::Move(denali), superblock));
|
||||
new Ext2BlockReader(glcr::Move(client), denali_info.device_id(),
|
||||
denali_info.lba_offset(), superblock));
|
||||
}
|
||||
|
||||
Superblock* Ext2BlockReader::GetSuperblock() {
|
||||
|
|
@ -51,15 +61,40 @@ uint64_t Ext2BlockReader::InodeTableBlockSize() {
|
|||
|
||||
glcr::ErrorOr<MappedMemoryRegion> Ext2BlockReader::ReadBlock(
|
||||
uint64_t block_number) {
|
||||
return denali_.ReadSectors(block_number * SectorsPerBlock(),
|
||||
SectorsPerBlock());
|
||||
return ReadBlocks(block_number, 1);
|
||||
}
|
||||
glcr::ErrorOr<MappedMemoryRegion> Ext2BlockReader::ReadBlocks(
|
||||
uint64_t block_number, uint64_t num_blocks) {
|
||||
return denali_.ReadSectors(block_number * SectorsPerBlock(),
|
||||
num_blocks * SectorsPerBlock());
|
||||
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));
|
||||
return MappedMemoryRegion::FromCapability(resp.memory());
|
||||
}
|
||||
|
||||
Ext2BlockReader::Ext2BlockReader(ScopedDenaliClient&& denali,
|
||||
glcr::ErrorOr<MappedMemoryRegion> Ext2BlockReader::ReadBlocks(
|
||||
const glcr::Vector<uint64_t>& block_list) {
|
||||
ReadManyRequest req;
|
||||
req.set_device_id(device_id_);
|
||||
// FIXME: We should have better ergonomics for setting a repeated field in
|
||||
// Yunq.
|
||||
for (uint64_t i = 0; i < block_list.size(); i++) {
|
||||
uint64_t sector = lba_offset_ + block_list.at(i) * SectorsPerBlock();
|
||||
for (uint64_t j = 0; j < SectorsPerBlock(); j++) {
|
||||
req.add_lba(sector + j);
|
||||
}
|
||||
}
|
||||
ReadResponse resp;
|
||||
RET_ERR(denali_.ReadMany(req, resp));
|
||||
return MappedMemoryRegion::FromCapability(resp.memory());
|
||||
}
|
||||
|
||||
Ext2BlockReader::Ext2BlockReader(DenaliClient&& denali, uint64_t device_id,
|
||||
uint64_t lba_offset,
|
||||
MappedMemoryRegion super_block)
|
||||
: denali_(glcr::Move(denali)), super_block_region_(super_block) {}
|
||||
: denali_(glcr::Move(denali)),
|
||||
device_id_(device_id),
|
||||
lba_offset_(lba_offset),
|
||||
super_block_region_(super_block) {}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <denali/scoped_denali_client.h>
|
||||
#include <denali/denali.yunq.client.h>
|
||||
#include <glacier/memory/shared_ptr.h>
|
||||
#include <glacier/status/error_or.h>
|
||||
#include <mammoth/memory_region.h>
|
||||
#include <yellowstone/yellowstone.yunq.h>
|
||||
|
||||
#include "fs/ext2/ext2.h"
|
||||
|
||||
|
|
@ -15,7 +16,7 @@
|
|||
class Ext2BlockReader {
|
||||
public:
|
||||
static glcr::ErrorOr<glcr::SharedPtr<Ext2BlockReader>> Init(
|
||||
ScopedDenaliClient&& denali);
|
||||
const DenaliInfo& denali_info);
|
||||
|
||||
// TODO: Consider creating a new class wrapper with these computations.
|
||||
Superblock* GetSuperblock();
|
||||
|
|
@ -32,11 +33,17 @@ class Ext2BlockReader {
|
|||
glcr::ErrorOr<MappedMemoryRegion> ReadBlocks(uint64_t block_number,
|
||||
uint64_t num_blocks);
|
||||
|
||||
glcr::ErrorOr<MappedMemoryRegion> ReadBlocks(
|
||||
const glcr::Vector<uint64_t>& block_list);
|
||||
|
||||
private:
|
||||
ScopedDenaliClient denali_;
|
||||
DenaliClient denali_;
|
||||
uint64_t device_id_;
|
||||
uint64_t lba_offset_;
|
||||
MappedMemoryRegion super_block_region_;
|
||||
|
||||
Ext2BlockReader(ScopedDenaliClient&& denali, MappedMemoryRegion super_block);
|
||||
Ext2BlockReader(DenaliClient&& denali, uint64_t device_id,
|
||||
uint64_t lba_offset, MappedMemoryRegion super_block);
|
||||
|
||||
uint64_t SectorsPerBlock();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
#include <glacier/string/string.h>
|
||||
#include <mammoth/debug.h>
|
||||
|
||||
glcr::ErrorOr<Ext2Driver> Ext2Driver::Init(ScopedDenaliClient&& denali) {
|
||||
glcr::ErrorOr<Ext2Driver> Ext2Driver::Init(const DenaliInfo& denali_info) {
|
||||
ASSIGN_OR_RETURN(glcr::SharedPtr<Ext2BlockReader> reader,
|
||||
Ext2BlockReader::Init(glcr::Move(denali)));
|
||||
Ext2BlockReader::Init(glcr::Move(denali_info)));
|
||||
|
||||
ASSIGN_OR_RETURN(
|
||||
MappedMemoryRegion bgdt,
|
||||
|
|
@ -99,10 +99,31 @@ glcr::ErrorOr<MappedMemoryRegion> Ext2Driver::ReadFile(uint64_t inode_number) {
|
|||
uint64_t real_block_cnt =
|
||||
(inode->blocks - 1) / (ext2_reader_->BlockSize() / 512) + 1;
|
||||
|
||||
if (real_block_cnt > 1) {
|
||||
dbgln("Can't handle scatter-gather yet.");
|
||||
if (inode->block[14]) {
|
||||
dbgln("Can't handle triply-indirect blocks yet.");
|
||||
return glcr::UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
return ext2_reader_->ReadBlock(inode->block[0]);
|
||||
if (inode->block[13]) {
|
||||
dbgln("Can't handle doubly-indirect blocks yet.");
|
||||
return glcr::UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
MappedMemoryRegion indirect_block;
|
||||
if (inode->block[12]) {
|
||||
ASSIGN_OR_RETURN(indirect_block, ext2_reader_->ReadBlock(inode->block[12]));
|
||||
}
|
||||
|
||||
glcr::Vector<uint64_t> blocks_to_read;
|
||||
for (uint64_t i = 0; i < 12 && i < real_block_cnt; i++) {
|
||||
blocks_to_read.PushBack(inode->block[i]);
|
||||
}
|
||||
|
||||
for (uint64_t i = 12; i < 268 && i < real_block_cnt; i++) {
|
||||
uint32_t* block_array = reinterpret_cast<uint32_t*>(indirect_block.vaddr());
|
||||
uint64_t offset = i - 12;
|
||||
blocks_to_read.PushBack(block_array[offset]);
|
||||
}
|
||||
|
||||
return ext2_reader_->ReadBlocks(blocks_to_read);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <denali/scoped_denali_client.h>
|
||||
#include <glacier/memory/move.h>
|
||||
#include <glacier/memory/unique_ptr.h>
|
||||
#include <yellowstone/yellowstone.yunq.h>
|
||||
|
||||
#include "fs/ext2/ext2.h"
|
||||
#include "fs/ext2/ext2_block_reader.h"
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
class Ext2Driver {
|
||||
public:
|
||||
static glcr::ErrorOr<Ext2Driver> Init(ScopedDenaliClient&& denali);
|
||||
static glcr::ErrorOr<Ext2Driver> Init(const DenaliInfo& denali_info);
|
||||
|
||||
glcr::ErrorCode ProbePartition();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue