| // Copyright 2019 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 <blobfs/vmo-buffer.h> |
| |
| #include <utility> |
| |
| #include <blobfs/format.h> |
| #include <fs/trace.h> |
| #include <zircon/status.h> |
| #include <zircon/assert.h> |
| |
| namespace blobfs { |
| |
| VmoBuffer::VmoBuffer(VmoBuffer&& other) |
| : vmoid_registry_(std::move(other.vmoid_registry_)), |
| mapper_(std::move(other.mapper_)), |
| vmoid_(other.vmoid_), |
| capacity_(other.capacity_) { |
| other.Reset(); |
| } |
| |
| VmoBuffer& VmoBuffer::operator=(VmoBuffer&& other) { |
| if (&other != this) { |
| vmoid_registry_ = other.vmoid_registry_; |
| mapper_ = std::move(other.mapper_); |
| vmoid_ = other.vmoid_; |
| capacity_ = other.capacity_; |
| |
| other.Reset(); |
| } |
| return *this; |
| } |
| |
| VmoBuffer::~VmoBuffer() { |
| if (vmoid_ != VMOID_INVALID) { |
| vmoid_registry_->DetachVmo(vmoid_); |
| } |
| } |
| |
| void VmoBuffer::Reset() { |
| vmoid_registry_ = nullptr; |
| vmoid_ = VMOID_INVALID; |
| capacity_ = 0; |
| } |
| |
| zx_status_t VmoBuffer::Initialize(VmoidRegistry* vmoid_registry, size_t blocks, const char* label) { |
| ZX_DEBUG_ASSERT(vmoid_ == VMOID_INVALID); |
| fzl::OwnedVmoMapper mapper; |
| zx_status_t status = mapper.CreateAndMap(blocks * kBlobfsBlockSize, label); |
| if (status != ZX_OK) { |
| FS_TRACE_ERROR("VmoBuffer: Failed to create vmo %s: %s\n", label, |
| zx_status_get_string(status)); |
| return status; |
| } |
| |
| vmoid_t vmoid; |
| status = vmoid_registry->AttachVmo(mapper.vmo(), &vmoid); |
| if (status != ZX_OK) { |
| FS_TRACE_ERROR("VmoBuffer: Failed to attach vmo %s: %s\n", label, |
| zx_status_get_string(status)); |
| return status; |
| } |
| |
| vmoid_registry_ = vmoid_registry; |
| mapper_ = std::move(mapper); |
| vmoid_ = vmoid; |
| capacity_ = mapper_.size() / kBlobfsBlockSize; |
| return ZX_OK; |
| } |
| |
| void* VmoBuffer::MutableData(size_t index) { |
| ZX_DEBUG_ASSERT(index < capacity_); |
| return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(mapper_.start()) + |
| (index * kBlobfsBlockSize)); |
| } |
| |
| } // namespace blobfs |