// Copyright 2018 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 #include #include #include #include namespace blobfs { void ExtentReserver::Reserve(const Extent& extent) { ZX_DEBUG_ASSERT_MSG(extent.Length() > 0, "Reserving empty extents is disallowed"); zx_status_t status = reserved_blocks_.Set(extent.Start(), extent.Start() + extent.Length()); ZX_DEBUG_ASSERT(status == ZX_OK); } void ExtentReserver::Unreserve(const Extent& extent) { // Ensure the blocks are already reserved. size_t blkno_out; ZX_DEBUG_ASSERT(reserved_blocks_.Find(true, extent.Start(), extent.Start() + extent.Length(), extent.Length(), &blkno_out) == ZX_OK); zx_status_t status = reserved_blocks_.Clear(extent.Start(), extent.Start() + extent.Length()); ZX_DEBUG_ASSERT(status == ZX_OK); } uint64_t ExtentReserver::ReservedBlockCount() const { return reserved_blocks_.num_bits(); } ReservedExtent::ReservedExtent(ExtentReserver* reserver, Extent extent) : reserver_(reserver), extent_(extent) { reserver_->Reserve(extent_); } ReservedExtent::~ReservedExtent() { Reset(); } ReservedExtent::ReservedExtent(ReservedExtent&& o) : reserver_(o.reserver_), extent_(o.extent_) { o.Release(); } ReservedExtent& ReservedExtent::operator=(ReservedExtent&& o) { Reset(); reserver_ = o.reserver_; extent_ = o.extent_; o.Release(); return *this; } const Extent& ReservedExtent::extent() const { ZX_DEBUG_ASSERT_MSG(Reserved(), "Accessing unreserved extent"); return extent_; } ReservedExtent ReservedExtent::SplitAt(BlockCountType block_split) { ZX_DEBUG_ASSERT_MSG(Reserved(), "Accessing unreserved extent"); ZX_DEBUG_ASSERT(block_split < extent_.Length()); Extent latter(extent_.Start() + block_split, static_cast(extent_.Length() - block_split)); extent_.SetLength(block_split); return ReservedExtent(reserver_, std::move(latter)); } void ReservedExtent::Reset() { if (Reserved()) { reserver_->Unreserve(extent()); } Release(); } void ReservedExtent::Release() { reserver_ = nullptr; } bool ReservedExtent::Reserved() const { return reserver_ != nullptr; } } // namespace blobfs