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 #include <blobfs/allocator.h>
6 #include <unittest/unittest.h>
7 
8 #include "utils.h"
9 
10 namespace blobfs {
11 
12 // Create a block and node map of the requested size, update the superblock of
13 // the |space_manager|, and create an allocator from this provided info.
InitializeAllocator(size_t blocks,size_t nodes,MockSpaceManager * space_manager,fbl::unique_ptr<Allocator> * out)14 bool InitializeAllocator(size_t blocks, size_t nodes, MockSpaceManager* space_manager,
15                          fbl::unique_ptr<Allocator>* out) {
16     BEGIN_HELPER;
17     RawBitmap block_map;
18     ASSERT_EQ(ZX_OK, block_map.Reset(blocks));
19     fzl::ResizeableVmoMapper node_map;
20     ASSERT_EQ(ZX_OK, node_map.CreateAndMap(nodes * kBlobfsBlockSize, "node map"));
21 
22     space_manager->MutableInfo().inode_count = nodes;
23     space_manager->MutableInfo().data_block_count = blocks;
24     *out = fbl::make_unique<Allocator>(space_manager, std::move(block_map), std::move(node_map));
25     (*out)->SetLogging(false);
26     END_HELPER;
27 }
28 
29 // Force the allocator to become maximally fragmented by allocating
30 // every-other block within up to |blocks|.
ForceFragmentation(Allocator * allocator,size_t blocks)31 bool ForceFragmentation(Allocator* allocator, size_t blocks) {
32     BEGIN_HELPER;
33 
34     fbl::Vector<ReservedExtent> extents[blocks];
35     for (size_t i = 0; i < blocks; i++) {
36         ASSERT_EQ(ZX_OK, allocator->ReserveBlocks(1, &extents[i]));
37         ASSERT_EQ(1, extents[i].size());
38     }
39 
40     for (size_t i = 0; i < blocks; i += 2) {
41         allocator->MarkBlocksAllocated(extents[i][0]);
42     }
43 
44     END_HELPER;
45 }
46 
47 // Save the extents within |in| in a non-reserved vector |out|.
CopyExtents(const fbl::Vector<ReservedExtent> & in,fbl::Vector<Extent> * out)48 void CopyExtents(const fbl::Vector<ReservedExtent>& in, fbl::Vector<Extent>* out) {
49     out->reserve(in.size());
50     for (size_t i = 0; i < in.size(); i++) {
51         out->push_back(in[i].extent());
52     }
53 }
54 
55 // Save the nodes within |in| in a non-reserved vector |out|.
CopyNodes(const fbl::Vector<ReservedNode> & in,fbl::Vector<uint32_t> * out)56 void CopyNodes(const fbl::Vector<ReservedNode>& in, fbl::Vector<uint32_t>* out) {
57     out->reserve(in.size());
58     for (size_t i = 0; i < in.size(); i++) {
59         out->push_back(in[i].index());
60     }
61 }
62 
63 } // namespace blobfs
64