blob: 33630591a17efa2c94cb25e7fadd6d9cf5080ff7 [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.
#pragma once
#include <fbl/unique_fd.h>
#include <fvm/fvm-sparse.h>
// Wrapper around FVM metadata which attempts to read existing metadata from disk, allows
// new partitions and slices to be allocated, and writes updated metadata back to disk.
class FvmInfo {
public:
FvmInfo() : valid_(false), dirty_(false), metadata_size_(0), vpart_hint_(1), pslice_hint_(1) {}
// Resets the metadata to default values.
zx_status_t Reset(size_t disk_size, size_t slice_size);
// Loads and validates metadata from disk. If invalid metadata is found a success status is
// returned, but valid_ is marked false.
zx_status_t Load(const fbl::unique_fd& fd, uint64_t disk_offset, uint64_t disk_size);
// Validates the loaded metadata.
zx_status_t Validate() const;
// Grows in-memory metadata representation to the specified size.
zx_status_t Grow(size_t metadata_size);
// Grows in-memory metadata representation to account for |slice_count| additional slices.
zx_status_t GrowForSlices(size_t slice_count);
// Writes metadata to the partition described by |fd| of size |disk_size|, starting at offset
// |disk_offset|.
zx_status_t Write(const fbl::unique_fd& fd, size_t disk_offset, size_t disk_size);
// Allocates new partition (in memory) with a single slice.
zx_status_t AllocatePartition(const fvm::partition_descriptor_t* partition, uint8_t* guid,
uint32_t* vpart_index);
// Allocates new slice for given partition (in memory).
zx_status_t AllocateSlice(uint32_t vpart, uint32_t vslice, uint32_t* pslice);
// Helpers to grab reference to partition/slice from metadata
zx_status_t GetPartition(size_t index, fvm::vpart_entry_t** out) const;
zx_status_t GetSlice(size_t index, fvm::slice_entry_t** out) const;
fvm::fvm_t* SuperBlock() const;
size_t MetadataSize() const { return metadata_size_; }
size_t DiskSize() const { return SuperBlock()->fvm_partition_size; }
size_t SliceSize() const { return SuperBlock()->slice_size; }
// Returns true if the in-memory metadata has been changed from the original values (i.e.
// partitions/slices have been allocated since initialization).
bool IsDirty() const { return dirty_; }
// Returns true if metadata_ contains valid FVM metadata.
bool IsValid() const { return valid_; }
// Checks whether the metadata is valid, and immediately exits the process if it isn't.
void CheckValid() const;
private:
bool valid_;
bool dirty_;
size_t metadata_size_;
uint32_t vpart_hint_;
uint32_t pslice_hint_;
fbl::unique_ptr<uint8_t[]> metadata_;
};