blob: b3a872b1d6a2b19c46eeea35af3c4f7978cc93ee [file] [log] [blame]
// 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.
#ifndef SRC_STORAGE_BLOBFS_ITERATOR_ALLOCATED_EXTENT_ITERATOR_H_
#define SRC_STORAGE_BLOBFS_ITERATOR_ALLOCATED_EXTENT_ITERATOR_H_
#include <stdbool.h>
#include <stdint.h>
#include <zircon/types.h>
#include "src/storage/blobfs/format.h"
#include "src/storage/blobfs/iterator/allocated-node-iterator.h"
#include "src/storage/blobfs/iterator/extent-iterator.h"
#include "src/storage/blobfs/node-finder.h"
namespace blobfs {
// Allows traversing a collection of extents from an already-allocated node.
// Partially validates containers as they are traversed.
//
// This iterator is useful for accessing blobs which have already been written
// to disk.
class AllocatedExtentIterator : public ExtentIterator {
public:
AllocatedExtentIterator& operator=(const AllocatedExtentIterator&) = delete;
AllocatedExtentIterator(const AllocatedExtentIterator&) = delete;
AllocatedExtentIterator(AllocatedExtentIterator&&) = default;
AllocatedExtentIterator& operator=(AllocatedExtentIterator&&) = default;
// Creates an AllocatedExtentIterator. Returns an error if |node_index| isn't a valid index in
// |finder|.
static zx::status<AllocatedExtentIterator> Create(NodeFinder* finder, uint32_t node_index);
////////////////
// ExtentIterator interface.
bool Done() const final;
zx_status_t Next(const Extent** out) final;
uint64_t BlockIndex() const final;
////////////////
// Other methods.
// Returns the number of extents we've iterated past already.
uint32_t ExtentIndex() const;
// Returns the node we're about to read from on the upcoming call to |Next|.
//
// It is unsafe to call this method if |Done()| is true.
uint32_t NodeIndex() const;
// Returns |ZX_OK| when the node list can be safely traversed.
static zx_status_t VerifyIteration(NodeFinder* finder, Inode* inode);
private:
AllocatedExtentIterator(NodeFinder* finder, InodePtr inode, uint32_t node_index);
// Indicates if the current node is the inode (as opposed to a container).
bool IsInode() const;
// Returns |ZX_OK| if the container can accept another extent.
zx_status_t ValidateExtentCount() const;
// Moves the block, extent, and local indices forward.
void UpdateIndices(const Extent& extent);
// Acquires the current extent.
const Extent* GetExtent() const;
// Moves from either an inode to a container, or from one container to another.
//
// Returns an error if this container is unallocated, or not marked as a container.
zx_status_t NextContainer();
InodePtr inode_;
// The index of the node we're currently observing.
uint32_t node_index_;
AllocatedNodeIterator node_iterator_;
ExtentContainer* extent_node_ = nullptr;
// The block index, indicating how many blocks we've iterated past thus far.
uint64_t block_index_ = 0;
// The extent index into the current inode or container.
uint32_t local_index_ = 0;
};
} // namespace blobfs
#endif // SRC_STORAGE_BLOBFS_ITERATOR_ALLOCATED_EXTENT_ITERATOR_H_