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 <fvm/sparse-reader.h>
8 
9 #include "format.h"
10 
11 struct SparsePartitionInfo {
12     fvm::partition_descriptor_t descriptor;
13     fbl::Vector<fvm::extent_descriptor_t> extents;
14     fbl::unique_ptr<Format> format;
15 };
16 
17 // Given a target path and partition data from a SparseReader, generates a full FVM image.
18 class SparsePaver {
19 public:
20     // Creates a SparsePaver with the given attributes.
21     static zx_status_t Create(const char* path, size_t slice_size, size_t disk_offset,
22                               size_t disk_size, fbl::unique_ptr<SparsePaver>* out);
23 
24     // Allocates the partition and slices described by |partition| to info_, and writes out
25     // corresponding data from |reader| to the FVM. |partition| will not be modified.
26     zx_status_t AddPartition(const SparsePartitionInfo* partition, fvm::SparseReader* reader);
27 
28     // Commits the FVM image by writing the metadata to disk.
29     zx_status_t Commit();
30 private:
SparsePaver(size_t disk_offset,size_t disk_size)31     SparsePaver(size_t disk_offset, size_t disk_size) : disk_offset_(disk_offset),
32                                                         disk_size_(disk_size) {}
33 
34     // Initializes the FVM metadata.
35     zx_status_t Init(const char* path, size_t slice_size);
36 
37     // Allocates the extent described by |extent| to the partition at |vpart_index|, as well as
38     // allocating its slices and persisting all associated data.
39     zx_status_t AddExtent(uint32_t vpart_index, fvm::extent_descriptor_t* extent,
40                           fvm::SparseReader* reader);
41 
42     // Writes the next slice out to disk, reading as many of |bytes_left| as possible from |reader|
43     // and appending zeroes if necessary.
44     zx_status_t WriteSlice(size_t* bytes_left, fvm::SparseReader* reader);
45 
46     FvmInfo info_;
47     fbl::unique_fd fd_;
48     size_t disk_offset_; // Offset into fd_ at which to create FVM.
49     size_t disk_size_; // Number of bytes allocated for the FVM.
50     size_t disk_ptr_; // Marks the current offset within the target image.
51     fbl::unique_ptr<uint8_t[]> data_; // Buffer to hold data to be written to disk.
52 };
53