blob: b29e3d07b87b478cc8299a4c8981b02261497f4a [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "peridot/bin/ledger/storage/impl/object_impl.h"
#include <utility>
#include "peridot/bin/ledger/storage/impl/object_digest.h"
namespace storage {
namespace {
uint64_t ToFullPages(uint64_t value) {
return (value + PAGE_SIZE - 1) & (~(PAGE_SIZE - 1));
}
} // namespace
InlinedObject::InlinedObject(ObjectIdentifier identifier)
: identifier_(std::move(identifier)) {}
InlinedObject::~InlinedObject() {}
ObjectIdentifier InlinedObject::GetIdentifier() const { return identifier_; }
Status InlinedObject::GetData(fxl::StringView* data) const {
*data = ExtractObjectDigestData(identifier_.object_digest());
return Status::OK;
}
StringObject::StringObject(ObjectIdentifier identifier, std::string content)
: identifier_(std::move(identifier)), content_(std::move(content)) {}
StringObject::~StringObject() {}
ObjectIdentifier StringObject::GetIdentifier() const { return identifier_; }
Status StringObject::GetData(fxl::StringView* data) const {
*data = content_;
return Status::OK;
}
LevelDBObject::LevelDBObject(ObjectIdentifier identifier,
std::unique_ptr<leveldb::Iterator> iterator)
: identifier_(std::move(identifier)), iterator_(std::move(iterator)) {}
LevelDBObject::~LevelDBObject() {}
ObjectIdentifier LevelDBObject::GetIdentifier() const { return identifier_; }
Status LevelDBObject::GetData(fxl::StringView* data) const {
*data = convert::ExtendedStringView(iterator_->value());
return Status::OK;
}
VmoObject::VmoObject(ObjectIdentifier identifier, fsl::SizedVmo vmo)
: identifier_(std::move(identifier)), vmo_(std::move(vmo)) {}
VmoObject::~VmoObject() {
if (vmar_) {
vmar_.destroy();
}
}
ObjectIdentifier VmoObject::GetIdentifier() const { return identifier_; }
Status VmoObject::GetData(fxl::StringView* data) const {
Status status = Initialize();
if (status != Status::OK) {
return status;
}
*data = data_;
return Status::OK;
}
Status VmoObject::GetVmo(fsl::SizedVmo* vmo) const {
Status status = Initialize();
if (status != Status::OK) {
return status;
}
zx_status_t zx_status =
vmo_.Duplicate(ZX_RIGHTS_BASIC | ZX_RIGHT_READ | ZX_RIGHT_MAP, vmo);
if (zx_status != ZX_OK) {
FXL_LOG(ERROR) << "Unable to duplicate a vmo. Status: " << zx_status;
return Status::INTERNAL_IO_ERROR;
}
return Status::OK;
}
Status VmoObject::Initialize() const {
if (initialized_) {
return Status::OK;
}
uintptr_t allocate_address;
zx_status_t zx_status = zx::vmar::root_self()->allocate(
0, ToFullPages(vmo_.size()),
ZX_VM_CAN_MAP_READ | ZX_VM_CAN_MAP_WRITE | ZX_VM_CAN_MAP_SPECIFIC, &vmar_,
&allocate_address);
if (zx_status != ZX_OK) {
FXL_LOG(ERROR) << "Unable to allocate VMAR. Error: " << zx_status;
return Status::INTERNAL_IO_ERROR;
}
char* mapped_address;
zx_status = vmar_.map(0, vmo_.vmo(), 0, vmo_.size(),
ZX_VM_PERM_READ | ZX_VM_PERM_WRITE | ZX_VM_SPECIFIC,
reinterpret_cast<uintptr_t*>(&mapped_address));
if (zx_status != ZX_OK) {
FXL_LOG(ERROR) << "Unable to map VMO. Error: " << zx_status;
vmar_.reset();
return Status::INTERNAL_IO_ERROR;
}
data_ = fxl::StringView(mapped_address, vmo_.size());
initialized_ = true;
return Status::OK;
}
} // namespace storage