1 // Copyright 2018 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <stdbool.h> 8 #include <stdint.h> 9 10 #include <blobfs/allocator.h> 11 #include <blobfs/extent-reserver.h> 12 #include <blobfs/format.h> 13 #include <blobfs/node-reserver.h> 14 #include <fbl/function.h> 15 #include <fbl/vector.h> 16 #include <zircon/types.h> 17 18 namespace blobfs { 19 20 // A helper class which utilizes the visitor pattern to chain together a group 21 // of extents and nodes. 22 // 23 // Precondition: 24 // nodes.size() >= NodeCountForExtents(extents.size()) 25 class NodePopulator { 26 public: 27 NodePopulator(Allocator* allocator, 28 fbl::Vector<ReservedExtent> extents, 29 fbl::Vector<ReservedNode> nodes); 30 31 DISALLOW_COPY_ASSIGN_AND_MOVE(NodePopulator); 32 33 // Returns the maximum number of nodes necessary to hold |extent_count| extents. 34 static uint32_t NodeCountForExtents(ExtentCountType extent_count); 35 36 enum class IterationCommand { 37 Continue, 38 Stop, 39 }; 40 41 using OnNodeCallback = fbl::Function<void(const ReservedNode& node)>; 42 using OnExtentCallback = fbl::Function<IterationCommand(ReservedExtent& extent)>; 43 44 // Utilizes the |allocator| to locate all nodes provided by |nodes|, and allocate each 45 // node the appropriate |extent|. 46 // 47 // Along the way, this methods sets the following fields on the blob inode: |next_node|, 48 // |extents|, |extent_count|. This method sets all fields on the container nodes. 49 // 50 // Before each extent is accessed, |on_extent| is invoked. This allows a caller to modify how 51 // much of the extent is actually used. If IterationCommand::Stop is returned from |on_extent|, 52 // then extent-filling exits early, and no additional extents are used. This ability to "stop 53 // short" when using extents is useful when less storage is needed to persist a blob than 54 // originally allocated. This is common when using compression. 55 // 56 // After all extents are accessed, |on_node| is invoked on all nodes which are actually used to 57 // represent the blob. This may be smaller than the number of nodes passed in the ReservedNode 58 // vector. 59 zx_status_t Walk(OnNodeCallback on_node, OnExtentCallback on_extent); 60 61 private: 62 Allocator* allocator_; 63 fbl::Vector<ReservedExtent> extents_; 64 fbl::Vector<ReservedNode> nodes_; 65 }; 66 67 } // namespace blobfs 68