[VictoriaFalls] Implement Read File.
This commit is contained in:
parent
abf09d8fce
commit
d7050ff19f
|
@ -17,6 +17,21 @@ class Vector {
|
||||||
other.size_ = 0;
|
other.size_ = 0;
|
||||||
other.capacity_ = 0;
|
other.capacity_ = 0;
|
||||||
}
|
}
|
||||||
|
Vector& operator=(Vector&& other) {
|
||||||
|
if (data_) {
|
||||||
|
delete[] data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
data_ = other.data_;
|
||||||
|
size_ = other.size_;
|
||||||
|
capacity_ = other.capacity_;
|
||||||
|
|
||||||
|
other.data_ = nullptr;
|
||||||
|
other.size_ = 0;
|
||||||
|
other.capacity_ = 0;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
~Vector() {
|
~Vector() {
|
||||||
if (data_) {
|
if (data_) {
|
||||||
|
|
|
@ -44,9 +44,11 @@ glcr::ErrorOr<Inode*> Ext2Driver::GetInode(uint32_t inode_number) {
|
||||||
return inode_table_->GetInode(inode_number);
|
return inode_table_->GetInode(inode_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
glcr::ErrorCode Ext2Driver::ProbeDirectory(Inode* inode) {
|
glcr::ErrorOr<glcr::Vector<DirEntry>> Ext2Driver::ReadDirectory(
|
||||||
|
uint32_t inode_number) {
|
||||||
|
ASSIGN_OR_RETURN(Inode * inode, inode_table_->GetInode(inode_number));
|
||||||
if (!(inode->mode & 0x4000)) {
|
if (!(inode->mode & 0x4000)) {
|
||||||
dbgln("Probing non-directory");
|
dbgln("Reading non directory.");
|
||||||
return glcr::INVALID_ARGUMENT;
|
return glcr::INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +61,7 @@ glcr::ErrorCode Ext2Driver::ProbeDirectory(Inode* inode) {
|
||||||
return glcr::FAILED_PRECONDITION;
|
return glcr::FAILED_PRECONDITION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glcr::Vector<DirEntry> directory;
|
||||||
for (uint64_t i = 0; i < real_block_cnt; i++) {
|
for (uint64_t i = 0; i < real_block_cnt; i++) {
|
||||||
dbgln("Getting block %lx", inode->block[i]);
|
dbgln("Getting block %lx", inode->block[i]);
|
||||||
ASSIGN_OR_RETURN(MappedMemoryRegion block,
|
ASSIGN_OR_RETURN(MappedMemoryRegion block,
|
||||||
|
@ -66,6 +69,7 @@ glcr::ErrorCode Ext2Driver::ProbeDirectory(Inode* inode) {
|
||||||
uint64_t addr = block.vaddr();
|
uint64_t addr = block.vaddr();
|
||||||
while (addr < block.vaddr() + ext2_reader_->BlockSize()) {
|
while (addr < block.vaddr() + ext2_reader_->BlockSize()) {
|
||||||
DirEntry* entry = reinterpret_cast<DirEntry*>(addr);
|
DirEntry* entry = reinterpret_cast<DirEntry*>(addr);
|
||||||
|
directory.PushBack(*entry);
|
||||||
glcr::String name(entry->name, entry->name_len);
|
glcr::String name(entry->name, entry->name_len);
|
||||||
switch (entry->file_type) {
|
switch (entry->file_type) {
|
||||||
case kExt2FtFile:
|
case kExt2FtFile:
|
||||||
|
@ -80,5 +84,25 @@ glcr::ErrorCode Ext2Driver::ProbeDirectory(Inode* inode) {
|
||||||
addr += entry->record_length;
|
addr += entry->record_length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return glcr::OK;
|
return directory;
|
||||||
|
}
|
||||||
|
|
||||||
|
glcr::ErrorOr<MappedMemoryRegion> Ext2Driver::ReadFile(uint64_t inode_number) {
|
||||||
|
ASSIGN_OR_RETURN(Inode * inode, inode_table_->GetInode(inode_number));
|
||||||
|
|
||||||
|
if (!(inode->mode & 0x8000)) {
|
||||||
|
dbgln("Reading non file.");
|
||||||
|
return glcr::INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This calculation is cursed.
|
||||||
|
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.");
|
||||||
|
return glcr::UNIMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ext2_reader_->ReadBlock(inode->block[0]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,10 @@ class Ext2Driver {
|
||||||
glcr::ErrorCode ProbePartition();
|
glcr::ErrorCode ProbePartition();
|
||||||
|
|
||||||
glcr::ErrorOr<Inode*> GetInode(uint32_t inode_number);
|
glcr::ErrorOr<Inode*> GetInode(uint32_t inode_number);
|
||||||
glcr::ErrorCode ProbeDirectory(Inode* inode);
|
|
||||||
|
glcr::ErrorOr<glcr::Vector<DirEntry>> ReadDirectory(uint32_t inode_number);
|
||||||
|
|
||||||
|
glcr::ErrorOr<MappedMemoryRegion> ReadFile(uint64_t inode_number);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
glcr::SharedPtr<Ext2BlockReader> ext2_reader_;
|
glcr::SharedPtr<Ext2BlockReader> ext2_reader_;
|
||||||
|
|
|
@ -20,9 +20,7 @@ uint64_t main(uint64_t init_cap) {
|
||||||
denali_info.device_id(), denali_info.lba_offset());
|
denali_info.device_id(), denali_info.lba_offset());
|
||||||
ASSIGN_OR_RETURN(Ext2Driver ext2, Ext2Driver::Init(glcr::Move(denali)));
|
ASSIGN_OR_RETURN(Ext2Driver ext2, Ext2Driver::Init(glcr::Move(denali)));
|
||||||
|
|
||||||
ASSIGN_OR_RETURN(Inode * root, ext2.GetInode(2));
|
ASSIGN_OR_RETURN(auto server, VFSServer::Create(ext2));
|
||||||
|
|
||||||
ASSIGN_OR_RETURN(auto server, VFSServer::Create());
|
|
||||||
|
|
||||||
Thread server_thread = server->RunServer();
|
Thread server_thread = server->RunServer();
|
||||||
|
|
||||||
|
@ -31,7 +29,6 @@ uint64_t main(uint64_t init_cap) {
|
||||||
ASSIGN_OR_RETURN(auto client, server->CreateClient());
|
ASSIGN_OR_RETURN(auto client, server->CreateClient());
|
||||||
req.set_endpoint_capability(client.Capability());
|
req.set_endpoint_capability(client.Capability());
|
||||||
check(yellowstone.RegisterEndpoint(req, empty));
|
check(yellowstone.RegisterEndpoint(req, empty));
|
||||||
check(ext2.ProbeDirectory(root));
|
|
||||||
|
|
||||||
RET_ERR(server_thread.Join());
|
RET_ERR(server_thread.Join());
|
||||||
|
|
||||||
|
|
|
@ -4,22 +4,47 @@
|
||||||
#include <mammoth/debug.h>
|
#include <mammoth/debug.h>
|
||||||
#include <zcall.h>
|
#include <zcall.h>
|
||||||
|
|
||||||
glcr::ErrorOr<glcr::UniquePtr<VFSServer>> VFSServer::Create() {
|
glcr::ErrorOr<glcr::UniquePtr<VFSServer>> VFSServer::Create(
|
||||||
|
Ext2Driver& driver) {
|
||||||
z_cap_t endpoint_cap;
|
z_cap_t endpoint_cap;
|
||||||
RET_ERR(ZEndpointCreate(&endpoint_cap));
|
RET_ERR(ZEndpointCreate(&endpoint_cap));
|
||||||
return glcr::UniquePtr<VFSServer>(new VFSServer(endpoint_cap));
|
return glcr::UniquePtr<VFSServer>(new VFSServer(endpoint_cap, driver));
|
||||||
}
|
}
|
||||||
|
|
||||||
glcr::ErrorCode VFSServer::HandleOpenFile(const OpenFileRequest& request,
|
glcr::ErrorCode VFSServer::HandleOpenFile(const OpenFileRequest& request,
|
||||||
OpenFileResponse&) {
|
OpenFileResponse& response) {
|
||||||
auto path_tokens = glcr::StrSplit(request.path(), '/');
|
auto path_tokens = glcr::StrSplit(request.path(), '/');
|
||||||
for (uint64_t i = 0; i < path_tokens.size(); i++) {
|
|
||||||
dbgln("Token %u: '%s'", i, glcr::String(path_tokens.at(i)).cstr());
|
|
||||||
}
|
|
||||||
// Require all paths to be absolute rather than relative.
|
// Require all paths to be absolute rather than relative.
|
||||||
// If the path starts with '/' then the first token will be empty.
|
// If the path starts with '/' then the first token will be empty.
|
||||||
if (path_tokens.at(0) != "") {
|
if (path_tokens.at(0) != "") {
|
||||||
return glcr::INVALID_ARGUMENT;
|
return glcr::INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
return glcr::UNIMPLEMENTED;
|
|
||||||
|
ASSIGN_OR_RETURN(auto files, driver_.ReadDirectory(2));
|
||||||
|
for (uint64_t i = 1; i < path_tokens.size() - 1; i++) {
|
||||||
|
for (uint64_t j = 0; j < files.size(); j++) {
|
||||||
|
if (path_tokens.at(i) ==
|
||||||
|
glcr::StringView(files.at(j).name, files.at(j).name_len)) {
|
||||||
|
ASSIGN_OR_RETURN(files, driver_.ReadDirectory(files.at(j).inode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dbgln("Directory '%s' not found.", glcr::String(path_tokens.at(i)).cstr());
|
||||||
|
return glcr::NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
MappedMemoryRegion region;
|
||||||
|
for (uint64_t j = 0; j < files.size(); j++) {
|
||||||
|
if (path_tokens.at(path_tokens.size() - 1) ==
|
||||||
|
glcr::StringView(files.at(j).name, files.at(j).name_len)) {
|
||||||
|
ASSIGN_OR_RETURN(region, driver_.ReadFile(files.at(j).inode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!region) {
|
||||||
|
dbgln("File '%s' not found.",
|
||||||
|
glcr::String(path_tokens.at(path_tokens.size() - 1)).cstr());
|
||||||
|
}
|
||||||
|
|
||||||
|
response.set_path(request.path());
|
||||||
|
response.set_memory(region.cap());
|
||||||
|
return glcr::OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,15 +2,20 @@
|
||||||
|
|
||||||
#include <glacier/memory/unique_ptr.h>
|
#include <glacier/memory/unique_ptr.h>
|
||||||
|
|
||||||
|
#include "fs/ext2/ext2_driver.h"
|
||||||
#include "victoriafalls/victoriafalls.yunq.server.h"
|
#include "victoriafalls/victoriafalls.yunq.server.h"
|
||||||
|
|
||||||
class VFSServer : public VFSServerBase {
|
class VFSServer : public VFSServerBase {
|
||||||
public:
|
public:
|
||||||
static glcr::ErrorOr<glcr::UniquePtr<VFSServer>> Create();
|
static glcr::ErrorOr<glcr::UniquePtr<VFSServer>> Create(Ext2Driver& driver);
|
||||||
|
|
||||||
glcr::ErrorCode HandleOpenFile(const OpenFileRequest&,
|
glcr::ErrorCode HandleOpenFile(const OpenFileRequest&,
|
||||||
OpenFileResponse&) override;
|
OpenFileResponse&) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VFSServer(z_cap_t endpoint_cap) : VFSServerBase(endpoint_cap) {}
|
// FIXME: Don't store this as a reference.
|
||||||
|
Ext2Driver& driver_;
|
||||||
|
|
||||||
|
VFSServer(z_cap_t endpoint_cap, Ext2Driver& driver)
|
||||||
|
: VFSServerBase(endpoint_cap), driver_(driver) {}
|
||||||
};
|
};
|
||||||
|
|
|
@ -44,6 +44,7 @@ uint64_t main(uint64_t port_cap) {
|
||||||
MappedMemoryRegion::FromCapability(response.memory());
|
MappedMemoryRegion::FromCapability(response.memory());
|
||||||
|
|
||||||
dbgln("addr: %lu, size: %lu", file.vaddr(), file.size());
|
dbgln("addr: %lu, size: %lu", file.vaddr(), file.size());
|
||||||
|
dbgln("Test: '%s'", file.vaddr());
|
||||||
|
|
||||||
check(server_thread.Join());
|
check(server_thread.Join());
|
||||||
dbgln("Yellowstone Finished Successfully.");
|
dbgln("Yellowstone Finished Successfully.");
|
||||||
|
|
Loading…
Reference in New Issue