blob: d4215669b917d87ba51caf89db86f6f0fc0e108b [file] [log] [blame]
// Copyright 2020 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 "src/storage/blobfs/iterator/allocated-node-iterator.h"
#include <lib/zx/status.h>
#include <stdint.h>
#include <zircon/errors.h>
#include <zircon/types.h>
#include "src/storage/blobfs/format.h"
#include "src/storage/blobfs/node-finder.h"
namespace blobfs {
AllocatedNodeIterator::AllocatedNodeIterator(NodeFinder* finder, Inode* inode)
: finder_(finder), inode_(inode) {}
bool AllocatedNodeIterator::Done() const {
return extent_index_ + NodeExtentCount() >= inode_->extent_count;
}
zx::status<ExtentContainer*> AllocatedNodeIterator::Next() {
ZX_DEBUG_ASSERT(!Done());
auto next_node = finder_->GetNode(NextNodeIndex());
if (next_node.is_error()) {
return zx::error(ZX_ERR_IO_DATA_INTEGRITY);
}
ExtentContainer* next = next_node->AsExtentContainer();
ZX_DEBUG_ASSERT(next != nullptr);
bool is_container = next->header.IsAllocated() && next->header.IsExtentContainer();
if (!is_container) {
return zx::error(ZX_ERR_IO_DATA_INTEGRITY);
}
extent_index_ += NodeExtentCount();
extent_node_ = next;
return zx::ok(extent_node_);
}
uint32_t AllocatedNodeIterator::ExtentIndex() const { return extent_index_; }
uint32_t AllocatedNodeIterator::NextNodeIndex() const {
ZX_DEBUG_ASSERT(!Done());
return IsInode() ? inode_->header.next_node : extent_node_->header.next_node;
}
uint32_t AllocatedNodeIterator::NodeExtentCount() const {
if (IsInode()) {
return inode_->extent_count > 0 ? 1 : 0;
}
return extent_node_->extent_count;
}
bool AllocatedNodeIterator::IsInode() const { return extent_node_ == nullptr; }
} // namespace blobfs