blob: d3bb481d26bb05ae55b08a3ac9e4ff82e702ecf9 [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.
#ifndef SRC_STORAGE_FVM_HOST_FVM_INFO_H_
#define SRC_STORAGE_FVM_HOST_FVM_INFO_H_
#include <lib/zx/status.h>
#include <memory>
#include <fbl/unique_fd.h>
#include "src/storage/fvm/format.h"
#include "src/storage/fvm/fvm_sparse.h"
#include "src/storage/fvm/host/file_wrapper.h"
#include "src/storage/fvm/host/format.h"
#include "src/storage/fvm/metadata.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), 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(fvm::host::FileWrapper* file, uint64_t disk_offset, uint64_t disk_size);
// Validates the loaded contents.
bool Validate() const;
// Grows in-memory metadata representation to accomodate an FVM partition with dimensions
// described by |dimensions|. (The contents of |dimensions| are not copied, they are only used to
// decide how large the metadata ought to be.)
zx_status_t Grow(const fvm::Header& dimensions);
// Grows in-memory metadata representation to account for |slice_count| additional slices.
zx_status_t GrowForSlices(size_t slice_count);
// Writes metadata to the file wrapped by |wrapper| of size |disk_size|, starting at offset
// |disk_offset|.
zx_status_t Write(fvm::host::FileWrapper* wrapper, size_t disk_offset, size_t disk_size);
// Allocates new partition (in memory) with a single slice.
zx_status_t AllocatePartition(const fvm::PartitionDescriptor& partition, uint8_t* guid,
uint32_t* vpart_index);
// Allocates new partition (in memory).
zx::status<uint32_t> AllocatePartition(const fvm::VPartitionEntry& entry);
// Allocates a contiguous range of slices for a vslice extent, owned by |vpart|.
// Returns the index of the first pslice for the allocation.
// The allocation contains |info.PslicesNeeded()| slices.
zx::status<uint32_t> AllocateSlicesContiguous(uint32_t vpart, const ExtentInfo& info);
// Helpers to grab reference to partition/slice from metadata
zx_status_t GetPartition(size_t index, fvm::VPartitionEntry** out) const;
zx_status_t GetSlice(size_t index, fvm::SliceEntry** out) const;
const fvm::Header& SuperBlock() const { return metadata_.GetHeader(); }
size_t MetadataSize() const { return metadata_.Get()->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 the initial value that metadata_ was loaded with was valid.
// |CheckValidity| performs an actual verification of the state of metadata_ after all
// modifications.
bool IsValid() const { return valid_; }
// Checks whether IsValid(), and immediately exits the process if it isn't.
void CheckValid() const;
private:
// Reserves |num| contiguous slices, returning the pslice index of the first slice.
zx::status<uint32_t> ReserveSlicesContiguous(size_t num);
bool valid_;
bool dirty_;
uint32_t vpart_hint_;
uint32_t pslice_hint_;
fvm::Metadata metadata_;
};
#endif // SRC_STORAGE_FVM_HOST_FVM_INFO_H_