blob: 3c9e4ada6195fcf726c7da14ee730230d7978347 [file] [log] [blame]
// Copyright 2019 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.
library fuchsia.hardware.block.volume;
using zx;
using fuchsia.hardware.block.partition as partition;
/// VolumeInfo describes characteristics of either a single Volume, or all
/// Volumes combined.
struct VolumeInfo {
/// Size of a single slice, in bytes.
uint64 slice_size;
/// Number of addressable slices.
uint64 vslice_count;
/// Total number of allocatable slices.
uint64 pslice_total_count;
/// Total number of currently allocated slices.
uint64 pslice_allocated_count;
/// VolumeManagerInfo describes the properties of the existing volume manager.
/// This properties are specific for the VolumeManager and are not specific
/// to each Volume.
struct VolumeManagerInfo {
/// Size of a single slice, in bytes.
uint64 slice_size;
/// Size in bytes of the partition the VolumeManager is able to address with respect to the available space.
uint64 current_slice_count;
/// The maximum capacity which the Volume Manager could grow to utilize, if the
/// partition containing the Volume Manager itself expands (i.e., the Volume Manager
/// is initialized on a GPT partition that has extended beyond the originally allocated
/// capacity).
/// This resize occurs automatically on initialization of the Volume Manager,
/// and adjusts the result of `current_slice_count` to reflect the currently usable size.
uint64 maximum_slice_count;
/// Indicates that the partition should be created as inactive, implying that it
/// will be destroyed on reboot (unless activated by a call to "Activate").
const uint32 ALLOCATE_PARTITION_FLAG_INACTIVE = 0x00000001;
/// VolumeManager controls a collection of Volumes.
protocol VolumeManager {
/// Allocates a virtual partition with the requested features.
/// `slice_count` is the number of slices initially allocated to the partition, at
/// offset zero. The number of slices allocated to a new partition must be at least one.
/// `type` and `value` indicate type and instance GUIDs for the partition, respectively.
/// `name` indicates the name of the new partition.
AllocatePartition(uint64 slice_count, partition.GUID type,
partition.GUID instance, string:partition.NAME_LENGTH name,
uint32 flags) -> (zx.status status);
/// Gets slice size information about all volumes.
Query() -> (zx.status status, VolumeInfo? info);
/// Gets the VolumeManagerInfo describing this instance of the `VolumeManager`.
GetInfo() -> (zx.status status, VolumeManagerInfo? info);
/// Atomically marks a vpartition (by instance GUID) as inactive, while finding
/// another partition (by instance GUID) and marking it as active.
/// If the "old" partition does not exist, the GUID is ignored.
/// If the "old" partition is the same as the "new" partition, the "old"
/// GUID is ignored.
/// If the "new" partition does not exist, `ZX_ERR_NOT_FOUND` is returned.
/// This function does not destroy the "old" partition, it just marks it as
/// inactive -- to reclaim that space, the "old" partition must be explicitly
/// destroyed. This destruction can also occur automatically when the FVM driver
/// is rebound (i.e., on reboot).
/// This function may be useful for A/B updates within the FVM,
/// since it will allow activating updated partitions.
Activate(partition.GUID old_guid, partition.GUID new_guid) -> (zx.status status);
/// Retrieves the allocation limit for the partition. A return value of 0 indicates that there
/// is no limit and the partition can be extended as long as there is available space on the
/// device.
/// Currently the partition limit is not persisted across reboots but this may change in the
/// future.
GetPartitionLimit(partition.GUID guid) -> (zx.status status, uint64 byte_count);
/// Sets the allocation limit for the partition. Partitions can not be extended beyond their
/// allocation limit.
/// The allocation limits are on the VolumeManager API rather than on the partition because
/// they represent a higher capability level. These limits are designed to put guards on
/// users of the block device (and hence the Volume API).
/// Currently the partition limit is not persisted across reboots but this may change in the
/// future.
SetPartitionLimit(partition.GUID guid, uint64 byte_count) -> (zx.status status);
/// An arbitrary cap on the number of slices which may be requested when querying
/// for allocation information from a volume.
const uint32 MAX_SLICE_REQUESTS = 16;
/// VsliceRange describes a range of virtual slices: start, length, and allocated status.
/// These ranges are returned in an ordered container, which implicitly describes the
/// starting offset, starting from the "index zero" slice.
struct VsliceRange {
/// True if the virtual slices are allocated, false otherwise.
bool allocated;
/// The number of contiguous virtual slices.
uint64 count;
/// Volume is a partition which may access virtually-mapped blocks within a device.
protocol Volume {
compose partition.Partition;
/// Gets slice size information about the parent volume.
Query() -> (zx.status status, VolumeInfo? info);
/// Returns the number of contiguous allocated (or unallocated) vslices
/// starting from each vslice.
// TODO(smklein): Replace array with vector; doing so would be non-simple.
QuerySlices(vector<uint64>:MAX_SLICE_REQUESTS start_slices)
-> (zx.status status, array<VsliceRange>:MAX_SLICE_REQUESTS response, uint64 response_count);
/// Extends the mapping of this partition.
/// The ability to extend the partition is dependent on having sufficient free space on the
/// underlying device, having sufficient free slots for tracking the bytes in the volume
/// manager header, and the partition limit (see VolumeManager.SetPartitionLimit).
Extend(uint64 start_slice, uint64 slice_count) -> (zx.status status);
/// Shrinks a virtual partition. Returns `ZX_OK` if ANY slices are
/// freed, even if part of the requested range contains unallocated slices.
Shrink(uint64 start_slice, uint64 slice_count) -> (zx.status status);
/// Destroys the current partition, removing it from the VolumeManager, and
/// freeing all underlying storage. The connection to the volume is also closed.
Destroy() -> (zx.status status);