// Copyright 2017 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_FVM_FORMAT_H_
#define SRC_STORAGE_FVM_FORMAT_H_

#include <stdlib.h>
#include <string.h>

#include <algorithm>
#include <array>
#include <iosfwd>
#include <limits>
#include <string>
#include <type_traits>

#include <fbl/algorithm.h>
#include <gpt/gpt.h>

#include "src/lib/digest/digest.h"

// FVM is a virtual volume manager that allows partitions inside of it to be dynamically sized. It
// allocates data to partitions in units of fixed-size "slices".
//
// It maintains two copies of its data so there is a previous version to roll-back to in case of
// corruption. The latest one is determined by looking at the generation numbers stored in the
// headers (see Header::generation).
//
// There are two main structures which follow the header: the partition table contains the
// information for each virtual partition, and the allocation table maps which slice of the device
// is allocated to which partition.
//
// It's possible for the FVM partition to be smaller than the underlying physical device. The
// current size used by FVM is stored in |fvm_partition_size| (the header does not store the size of
// the underlying device). As long as the allocation table has enough entries, the FVM partition may
// be dynamically expanded to use more of the underlying device.
//
//             +----------------------------------
// Block 0  -> | Header (primary)
//             | <padding>
//             +----------------------------------
// Block 1  -> | Partition table (starts at block boundary)
//       .     |
//       .     |   ... Table of VPartitionEntry ...
//       .     |
//             +----------------------------------
// Block X  -> | Allocation table (starts at block boundary)
//       .     |
//       .     |   ... Table of SliceEntry[pslice_count] ...
//       .     |
//             | <padding to next block boundary>
// Block Y  -> +----------------------------------     <- Metadata used bytes (block boundary).
//       .     |
//       .     |   <unused allocation table space>
//       .     |
//             +==================================     <- Metadata allocated bytes (block boundary).
// Block Z  -> | Header (secondary, starts at block boundary)
//             +----------------------------------
//             | Partition table (secondary)
//             +----------------------------------
//             | Allocation table (secondary)
//             +==================================
//             | Physical slice "1" data...

namespace fvm {

// Unique identifier mapped to a GPT partition that contains a FVM.
static constexpr uint64_t kMagic = 0x54524150204d5646;

// Current version of the format and the revision of the software. The format version determines
// backwards-compatibility. The revision should be incremented for any minor change in how data is
// stored (including format versions but also for anything minor) and does not imply anything about
// backwards compatibility. The revision is used to updated the oldest_revision field in the
// header.
//
// See //src/storage/docs/versioning.md for more.
//
// *************************************************************************************************
//
// IMPORTANT: When changing either kCurrentFormatVersion or kCurrentRevision:
//
//   * Update //third_party/cobalt_config/fuchsia/local_storage/versions.txt
//     (submission order does not matter).
//
//   * Update //src/storage/fvm/README.md with what changed.
//
// *************************************************************************************************
static constexpr uint64_t kCurrentFormatVersion = 1;
static constexpr uint64_t kCurrentRevision = 1;

// Defines the block size of that the FVM driver exposes. This need not be the block size of the
// underlying device.
static constexpr uint64_t kBlockSize = 8192;

// One past the maximum number of virtual partitions that can be created.
// Valid partitions indices range from 1 to 1023.
// TODO(fxb/59980) make this consistent so we can use the whole table. Either use 0-1023 as the
// valid partition range, or 1-1024.
static constexpr uint64_t kMaxVPartitions = 1024;
static constexpr uint64_t kMaxUsablePartitions = kMaxVPartitions - 1;

// Maximum size for a partition GUID.
static constexpr size_t kGuidSize = GPT_GUID_LEN;

// Maximum string length for virtual partition GUID.
static constexpr size_t kGuidStrLen = GPT_GUID_STRLEN;

// Maximum length allowed for a virtual partition name.
static constexpr size_t kMaxVPartitionNameLength = 24;

// Number of bits required for the VSlice address space.
static constexpr uint64_t kSliceEntryVSliceBits = 32;

// Number of bits required for the VPartition address space.
static constexpr uint64_t kSliceEntryVPartitionBits = 16;

// Maximum number of VSlices that can be addressed.
static constexpr uint64_t kMaxVSlices = 1ull << (kSliceEntryVSliceBits - 1);

// The maximum slice size should be such that it never overflows the address space.
static constexpr uint64_t kMaxSliceSize = std::numeric_limits<uint64_t>::max() / kMaxVSlices;

// Provides a placeholder instange GUID, that will be updated when a driver loads a partition with
// such instance GUID.
static constexpr std::array<uint8_t, kGuidSize> kPlaceHolderInstanceGuid = {0};

// Type GUID for an internally defined partition used to reserve slices for future uses.
static constexpr std::array<uint8_t, kGuidSize> kSnapshotMetadataTypeGuid = {
    0xa0, 0x44, 0xe4, 0x75, 0xaa, 0x6b, 0xe5, 0xf3, 0x52, 0x4b, 0xf3, 0x67, 0x81, 0x61, 0xf9, 0xce,
};

namespace internal {

// FVM block alignment properties for a given type.
template <typename T>
struct block_alignment {
  static constexpr bool may_cross_boundary = (kBlockSize % sizeof(T)) != 0;
  static constexpr bool ends_at_boundary = (sizeof(T) % kBlockSize);
};

}  // namespace internal

// Defines the type of superblocks of an FVM. The key difference is how the offset from the
// beginning is calculated. They both share the same format.
enum class SuperblockType {
  kPrimary,
  kSecondary,
};

// FVM header which describes the contents and layout of the volume manager.
struct Header {
  // Creates headers representing structures with the given information. FVM allows for growth, so
  // the "growable" variants takes the initial size as well as the max size that the metadata tables
  // can represent to allow for future growth up until that limit. FromDiskSize()/FromSliceCount()
  // will not necessarily allow for future growth (table padding up to a block boundary may allow
  // some growth).
  //
  // The partition and slice tables will end up both being one larger than the number of usable
  // entries passed in to this function. So don't pass even numbers to make the tables
  // nicely aligned, pass one less.
  // TODO(fxb/59980) make table_size == usable_count.
  //
  // Currently the partition table size is fixed, so usable_partitions must be kMaxUsablePartitions
  // or it will assert.
  // TODO(fxb/40192): Allow usable partitions to vary.
  static Header FromDiskSize(size_t usable_partitions, size_t disk_size, size_t slice_size);
  static Header FromGrowableDiskSize(size_t usable_partitions, size_t initial_disk_size,
                                     size_t max_disk_size, size_t slice_size);
  static Header FromSliceCount(size_t usable_partitions, size_t usable_slices, size_t slice_size);
  static Header FromGrowableSliceCount(size_t usable_partitions, size_t initial_usable_slices,
                                       size_t max_usable_slices, size_t slice_size);

  // Sets the number of slices.
  //   0 <= usable_slices <= GetAllocationTableAllocatedEntryCount();
  // This will update the pslice_count as well as the fvm_partition_size accordingly.
  void SetSliceCount(size_t usable_slices);

  // Getters ---------------------------------------------------------------------------------------

  // Validates the header. This does NOT check the hash because that covers the entire metadata
  // which is not available to just the header class.
  //
  // The disk size is passed to validate that the specified disk image does not overflow the device.
  // To disable checking, pass std::numeric_limits<uint64_t>::max() for the disk_size.
  //
  // The underlying device's disk_block_size is passed to ensure that it is a multiple of of the
  // slice size. To disable checking this, pass fvm::kBlockSize for the device block size.
  //
  // A description of the error (if present) will be placed into the given output parameter
  // (required).
  bool IsValid(uint64_t disk_size, uint64_t disk_block_size, std::string& out_err) const;

  // Like IsValid but perfoms the minimal possible validation only on the partition and allocation
  // table sizes. This does not check any other data, even the signature.
  //
  // This function is useful when reading the primary superblock and we need to find the secondary
  // superblock. The secondary header is located after the allocation and partition tables, so the
  // primary header must have valid sizes for these tables before we can consider which variant is
  // valid.
  bool HasValidTableSizes(std::string& out_err) const;

  // The partition table always starts at a block offset, and is always a multiple of blocks
  // long in bytes.
  //
  // Partition IDs count from 1 but the partition table is indexed from 0, leaving an unused
  // VPartitionEntry at the beginning of this table. The "entry count" is therefore one less than
  // the size of the table.
  size_t GetPartitionTableOffset() const;
  size_t GetPartitionTableEntryCount() const;
  size_t GetPartitionTableByteSize() const;

  // Returns the offset of the given VPartitionEntry struct from the beginning of the Header. The
  // valid input range is:
  //   0 < index <= GetPartitionTableEntryCount()
  size_t GetPartitionEntryOffset(size_t index) const;

  // The allocation table begins on a block boundary after the partition table. It has a "used"
  // portion which are available for use by partitions (though they may not be used yet). Then it
  // has a potentially-larger "allocated" portion which allows FVM to grow assuming the underlying
  // device has room.
  size_t GetAllocationTableOffset() const;
  size_t GetAllocationTableUsedEntryCount() const;
  size_t GetAllocationTableUsedByteSize() const;
  size_t GetAllocationTableAllocatedEntryCount() const;
  size_t GetAllocationTableAllocatedByteSize() const;

  // Computes the number of allocation table entries that are needed for the given disk size,
  // capping it at the maximum number representable using the current allocation table size.
  // This is used when growing the FVM partition.
  size_t GetMaxAllocationTableEntriesForDiskSize(size_t disk_size) const;

  // Byte offset from the beginning of the Header to the allocation table entry (SliceEntry struct)
  // with the given ID. Physical slice IDs are 1-based so valid input is:
  //   1 <= pslice <= pslice_count
  // To get the actual slice data, see GetSliceOffset().
  size_t GetSliceEntryOffset(size_t pslice) const;

  // The metadata counts the header, partition table, and allocation table. The allocation table
  // may contain unused entries (allowing FVM to grow as long as there is space on the underlying
  // device), in which case the used bytes will be less than the allocated bytes.
  //
  // When the Header is default-initialized and the disk or slice size is 0, the metadata size
  // is defined to be 0.
  size_t GetMetadataUsedBytes() const;
  size_t GetMetadataAllocatedBytes() const;

  // Returns the offset in bytes of the given superblock from the beginning of the device.
  size_t GetSuperblockOffset(SuperblockType type) const;

  // Returns the offset in the device (counting both copies of the metadata) where the first slice
  // data starts.
  size_t GetDataStartOffset() const;

  // Byte offset from the beginning of the device to the slice data. Physical slice IDs are 1-based
  // so valid input is:
  //   1 <= pslice <= pslice_count
  // This gets the actual slice data. To get the slice's allocation table entry, see
  // GetSliceEntryOffset().
  size_t GetSliceDataOffset(size_t pslice) const;

  // Returns a stringified representation of the header, useful for debugging.
  std::string ToString() const;

  // Data ------------------------------------------------------------------------------------------

  // Unique identifier for this format type. Expected to be kMagic.
  uint64_t magic = kMagic;

  // Version of the overall format. If this is larger than kCurrentFormatVersion the driver must
  // not access the data. See also "oldest_revision" below and //src/storage/docs/versioning.md.
  uint64_t format_version = kCurrentFormatVersion;

  // The number of physical slices which can be addressed and allocated by the virtual parititons.
  // This is the number of slices that will fit in the current fvm_partition_size, minus the size
  // of the two copies of the metadata at the beginning of the device.
  //
  // Physical slices are 1-indexed (0 means "none"). Therefore:
  //   1 <= |maximum valid pslice| <= pslice_count
  //
  // IMPORTANT NOTE: Due to fxbug.dev/59980, this value is one less than the number of entries worth
  // of space in the allocation table because there is an unused 0 entry.
  uint64_t pslice_count = 0;

  // Size of the each slice in bytes. Must be a multiple of kBlockSize.
  uint64_t slice_size = 0;

  // Current size of the volume the fvm described by this header. This might be smaller than the
  // size of the underlying device (see comments at the top of the file). Must be a multiple of
  // kBlockSize.
  uint64_t fvm_partition_size = 0;

  // Size in bytes of the partition table of the superblock the header describes. Must be a
  // multiple of kBlockSize.
  //
  // Currently this is fixed to be the size required to hold exactly kMaxVPartitions and various
  // code assumes this constant.
  // TODO(fxbug.dev/40192): Use this value so the partition table can have different sizes.
  uint64_t vpartition_table_size = 0;

  // Size in bytes reserved for the allocation table. Must be a multiple of kBlockSize. This
  // includes extra space allowing the fvm to grow as the underlying volume grows. The
  // currently-used allocation table size, which defines the number of slices that can be addressed,
  // is derived from |pslice_count|.
  uint64_t allocation_table_size = 0;

  // Use to determine over two copies(primary, secondary) of superblock, which one is the latest
  // one. This is incremented for each metadata change so the valid metadata with the largest
  // generation is the one to use.
  uint64_t generation = 0;

  // Integrity check of the entire metadata (one copy). When computing the hash (use
  // fvm::UpdateHash() to compute), this field is is considered to be 0-filled.
  uint8_t hash[digest::kSha256Length] = {0};

  // The oldest revision of the software that has written to this FVM instance. When opening for
  // writes, the driver should check this and lower it if the current revision is lower than the
  // one stored in this header. This does not say anything about backwards-compatibility, that is
  // determined by format_version above.
  //
  // See //src/storage/docs/versioning.md for more.
  uint64_t oldest_revision = kCurrentRevision;

  // Fill remainder of the block.
  uint8_t reserved[0];
};

static_assert(std::is_standard_layout_v<Header> && sizeof(Header) <= kBlockSize,
              "fvm::Header must fit within one block and match standard layout.");

// Represent an entry in the FVM Partition table, which is fixed size contiguous flat buffer.
struct VPartitionEntry {
  VPartitionEntry() = default;

  // The name must not contain embedded nulls (this code will assert if it does). The name will
  // be truncated to kMaxVPartitionNameLength characters.
  //
  // See StringFromArray() to create the name parmeter if you're creating from another fixed-length
  // buffer.
  //
  // The format of the flags is not user-controllable since the flag values are not exposed in the
  // header. Pass either 0 for default, or copy from another VPartitionEntry.
  VPartitionEntry(const uint8_t type[kGuidSize], const uint8_t guid[kGuidSize], uint32_t slices,
                  std::string name, uint32_t flags = 0);

  // Creates an entry which is used to retain slices for future use.
  static VPartitionEntry CreateSnapshotMetadataPartition();

  // Creates a string from the given possibly-null-terminated fixed-length buffer. If there is a
  // null terminator it will indicate the end of the string. if there is none, the string will use
  // up the entire input buffer.
  template <size_t N>
  static std::string StringFromArray(const uint8_t (&array)[N]) {
    return std::string(reinterpret_cast<const char*>(&array[0]),
                       std::find(&array[0], &array[N], 0) - &array[0]);
  }

  // Returns the allowed set of flags in |raw_flags|.
  static uint32_t MaskInvalidFlags(uint32_t raw_flags);

  // Returns true if the entry is allocated.
  bool IsAllocated() const;

  // Returns true if the entry is free.
  bool IsFree() const;

  // Releases the partition, marking it as free.
  void Release();

  // Returns true if the partition is should be treated as active..
  bool IsActive() const;

  // Returns true if the partition is flagged as inactive.
  bool IsInactive() const;

  // Returns true if the partition is an internal one used for reserving slices for future uses.
  bool IsInternalReservationPartition() const;

  // Marks this entry active status as |is_active|.
  void SetActive(bool is_active);

  std::string name() const { return StringFromArray(unsafe_name); }

  // Mirrors GPT value.
  uint8_t type[kGuidSize] = {0};

  // Mirrors GPT value.
  uint8_t guid[kGuidSize] = {0};

  // Number of allocated slices.
  uint32_t slices = 0u;

  // Used internally by the mutator/accessor functions above.
  uint32_t flags = 0u;

  // Partition name. The name is counted until the first null byte or the end of the static buffer
  // (it is not null terminated in this case). Prefer to use the name() accessor above which
  // abstracts this handling.
  uint8_t unsafe_name[fvm::kMaxVPartitionNameLength] = {0};
};

// Outputs a single-line description of the partition entry.
std::ostream& operator<<(std::ostream& out, const VPartitionEntry& entry);

static_assert(sizeof(VPartitionEntry) == 64, "Unchecked VPartitionEntry size change.");
static_assert(std::is_standard_layout_v<VPartitionEntry>,
              "VPartitionEntry must be standard layout compilant and trivial.");
static_assert(!internal::block_alignment<VPartitionEntry>::may_cross_boundary,
              "VPartitionEntry must not cross block boundary.");
static_assert(!internal::block_alignment<VPartitionEntry[kMaxVPartitions]>::ends_at_boundary,
              "VPartitionEntry table max size must end at block boundary.");

// A Slice Entry represents the allocation of a slice.
//
// Slice Entries are laid out in an array on disk. The index into this array determines the
// "physical slice" being accessed, where physical slices consist of all disk space immediately
// following the FVM metadata on an FVM partition.
struct SliceEntry {
  SliceEntry() = default;
  SliceEntry(uint64_t vpartition, uint64_t vslice);

  // Returns true if this slice is assigned to a partition.
  bool IsAllocated() const;

  // Returns true if this slice is unassigned.
  bool IsFree() const;

  // Resets the slice entry, marking it as Free.
  void Release();

  // Returns the |vpartition| that owns this slice.
  uint64_t VPartition() const;

  // Returns the |vslice| of this slice. This represents the relative order of the slices
  // assigned to |vpartition|. This is, the block device exposed to |partition| sees an array of
  // all slices assigned to it, sorted by |vslice|.
  uint64_t VSlice() const;

  // Sets the contents of the slice entry to |partition| and |slice|.
  void Set(uint64_t vpartition, uint64_t vslice);

  // Packed entry, the format must remain obscure to the user.
  uint64_t data = 0u;
};

// Outputs a single-line description of the partition entry.
std::ostream& operator<<(std::ostream& out, const SliceEntry& entry);

static_assert(sizeof(SliceEntry) == 8, "Unchecked SliceEntry size change.");
static_assert(std::is_standard_layout_v<SliceEntry>, "VSliceEntry must be standard layout.");
static_assert(!internal::block_alignment<SliceEntry>::may_cross_boundary,
              "VSliceEntry must not cross block boundary.");

// Due to the way partitions are counted, the usable partitions (the input to this function) is one
// smaller than the number table entries because the 0th entry is not used. This function may
// generate a larger-than-needed partition table to ensure it's block-aligned.
//
// TODO(fxb/59980) Remove the unused 0th entry so we can actually use the full number passed in.
constexpr size_t PartitionTableByteSizeForUsablePartitionCount(size_t usable_partitions) {
  // This multiply shouldn't overflow because usable_partitions should always be <=
  // kMaxUsablePartitions.
  return fbl::round_up(sizeof(VPartitionEntry) * (usable_partitions + 1), kBlockSize);
}

constexpr size_t AllocTableByteSizeForUsableSliceCount(size_t slice_count) {
  // Reserve the 0th table entry so need +1 to get the usable slices.
  //
  // This multiply shouldn't overflow since slice_count should be <= kMaxVSlices which leaves many
  // spare bits.
  return fbl::round_up(sizeof(SliceEntry) * (slice_count + 1), fvm::kBlockSize);
}

constexpr size_t BlocksToSlices(size_t slice_size, size_t block_size, size_t block_count) {
  if (slice_size == 0 || slice_size < block_size) {
    return 0;
  }

  const size_t kBlocksPerSlice = slice_size / block_size;
  return (block_count + kBlocksPerSlice - 1) / kBlocksPerSlice;
}

constexpr size_t SlicesToBlocks(size_t slice_size, size_t block_size, size_t slice_count) {
  // This multiply shouldn't overflow because the slice size and slice count show always be capped
  // to the max values (which were picked to avoid overflow).
  return slice_count * slice_size / block_size;
}

// Limits on the maximum metadata sizes. These value are to prevent overallocating buffers if
// the metadata is corrupt. The metadata size counts one copy of the metadata only (there will
// actually be two copies at the beginning of the device.
static constexpr uint64_t kMaxPartitionTableByteSize =
    PartitionTableByteSizeForUsablePartitionCount(kMaxUsablePartitions);
static constexpr uint64_t kMaxAllocationTableByteSize =
    fbl::round_up(sizeof(SliceEntry) * kMaxVSlices, fvm::kBlockSize);
static constexpr uint64_t kMaxMetadataByteSize =
    kBlockSize + kMaxPartitionTableByteSize + kMaxAllocationTableByteSize;

inline void Header::SetSliceCount(size_t usable_slices) {
  pslice_count = usable_slices;
  fvm_partition_size = GetDataStartOffset() + usable_slices * slice_size;
}

inline size_t Header::GetPartitionTableOffset() const {
  // The partition table starts at the first block after the header.
  return kBlockSize;
}

inline size_t Header::GetPartitionTableEntryCount() const {
  // The partition table has an unused 0th entry, so the number of usable entries in the table
  // is one less than that.
  // TODO(fxb/59980) the partition table is 0-indexed (with the 0th entry not used) while the
  // valid indices start from 1 (0 means invalid). This should be more consistent to remove the
  // unused entry.
  // Currently we expect the partition table count and size to be constant.
  // TODO(bug 40192): Derive this from the header so we can have different sizes.
  return kMaxVPartitions - 1;
}

inline size_t Header::GetPartitionTableByteSize() const {
  // Currently we expect the partition table count and size to be constant.
  // TODO(bug 40192): Derive this from the header so we can have different sizes.
  return sizeof(VPartitionEntry) * kMaxVPartitions;
}

inline size_t Header::GetPartitionEntryOffset(size_t index) const {
  return GetPartitionTableOffset() + index * sizeof(VPartitionEntry);
}

inline size_t Header::GetAllocationTableOffset() const {
  // The allocation table follows the partition table immediately.
  return GetPartitionTableOffset() + GetPartitionTableByteSize();
}

inline size_t Header::GetAllocationTableUsedEntryCount() const { return pslice_count; }

inline size_t Header::GetAllocationTableUsedByteSize() const {
  // Ensure the used allocation table byte size is always on a multiple of the block suize.
  return fbl::round_up(sizeof(SliceEntry) * GetAllocationTableUsedEntryCount(), kBlockSize);
}

inline size_t Header::GetAllocationTableAllocatedEntryCount() const {
  // The "-1" here allows for the unused 0 indexed slice.
  // TODO(fxbug.dev/59980) the allocation table is 0-indexed (with the 0th entry not used) while the
  // allocation data itself is 1-indexed. This inconsistency should be fixed.
  if (size_t byte_size = GetAllocationTableAllocatedByteSize(); byte_size > 0)
    return byte_size / sizeof(SliceEntry) - 1;
  return 0;  // Don't underflow if the table is empty.
}

inline size_t Header::GetAllocationTableAllocatedByteSize() const { return allocation_table_size; }

inline size_t Header::GetMaxAllocationTableEntriesForDiskSize(size_t disk_size) const {
  size_t start_offset = GetDataStartOffset();
  if (slice_size == 0 || disk_size <= start_offset)
    return 0;  // Prevent underflow.

  // See how many slices fit in in the non-metadata portion of the device.
  size_t requested_slices = (disk_size - start_offset) / slice_size;

  // That value may be limited by the maximum number of entries in the allocation table.
  return std::min(requested_slices, GetAllocationTableAllocatedEntryCount());
}

inline size_t Header::GetSliceEntryOffset(size_t pslice) const {
  // TODO(fxbug.dev/59980) the allocation table is 0-indexed (with the 0th entry not used) while the
  // allocation data itself is 1-indexed. This inconsistency should be fixed,
  return GetAllocationTableOffset() + pslice * sizeof(SliceEntry);
}

inline size_t Header::GetMetadataUsedBytes() const {
  if (fvm_partition_size == 0 || slice_size == 0)
    return 0;  // Uninitialized header.

  // The used metadata ends after the used portion of the allocation table.
  //
  // This addition won't overflow when the allocation and partition tables are <= their max sizes.
  return GetAllocationTableOffset() + GetAllocationTableUsedByteSize();
}

inline size_t Header::GetMetadataAllocatedBytes() const {
  if (fvm_partition_size == 0 || slice_size == 0)
    return 0;  // Uninitialized header.

  // The metadata ends after the allocation table.
  //
  // This addition won't overflow when the allocation and partition tables are <= their max sizes.
  return GetAllocationTableOffset() + GetAllocationTableAllocatedByteSize();
}

inline size_t Header::GetSuperblockOffset(SuperblockType type) const {
  return (type == SuperblockType::kPrimary) ? 0 : GetMetadataAllocatedBytes();
}

inline size_t Header::GetDataStartOffset() const {
  // The slice data starts after the two copies of metadata at beginning of device.
  return 2 * GetMetadataAllocatedBytes();
}

inline size_t Header::GetSliceDataOffset(size_t pslice) const {
  // The pslice is 1-based and the array starts at the "data start".
  return GetDataStartOffset() + (pslice - 1) * slice_size;
}

}  // namespace fvm

// Following describes the android sparse format

constexpr uint32_t kAndroidSparseHeaderMagic = 0xed26ff3a;

struct AndroidSparseHeader {
  const uint32_t kMagic = kAndroidSparseHeaderMagic;
  const uint16_t kMajorVersion = 0x1;
  const uint16_t kMinorVersion = 0x0;
  uint16_t file_header_size = 0;
  uint16_t chunk_header_size = 0;
  uint32_t block_size = 0;
  uint32_t total_blocks = 0;
  uint32_t total_chunks = 0;
  // CRC32 checksum of the original data, including dont-care chunk
  uint32_t image_checksum = 0;
};

enum AndroidSparseChunkType : uint16_t {
  kChunkTypeRaw = 0xCAC1,
  kChunkTypeFill = 0xCAC2,
  kChunkTypeDontCare = 0xCAC3,
};

struct AndroidSparseChunkHeader {
  AndroidSparseChunkType chunk_type;
  uint16_t reserved1 = 0;
  // In the unit of blocks
  uint32_t chunk_blocks = 0;
  // In the unit of bytes
  uint32_t total_size = 0;
};

#endif  // SRC_STORAGE_FVM_FORMAT_H_
