fuchsia.storage.block

Added: HEAD

PROTOCOLS

Block

Defined in fuchsia.storage.block/block.fidl

Defines access to a device which is accessible in block-granularity chunks for reading and writing.

Destroy

Destroys the current volume, removing it from the VolumeManager, and freeing all underlying storage. The connection to the volume is also closed.

Returns ZX_ERR_NOT_SUPPORTED if the device is not a volume.

Request

<EMPTY>

Response

NameType
status zx/Status

Extend

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).

Returns ZX_ERR_NOT_SUPPORTED if the device is not a volume.

Request

NameType
start_slice uint64
slice_count uint64

Response

NameType
status zx/Status

GetInfo

Get information about the underlying block device.

Request

<EMPTY>

Response

NameType
payload Block_GetInfo_Result

GetInstanceGuid

Gets the instance GUID of the partition (if one exists). If the partition has no instance GUID, ZX_ERR_NOT_SUPPORTED is returned.

Request

<EMPTY>

Response

NameType
status zx/Status
guid Guid?

GetMetadata

Gets the metadata for the partition.

Fields may be absent if the partition doesn't have the given metadata.

Request

<EMPTY>

Response

NameType
payload Block_GetMetadata_Result

GetName

Gets the name of the partition (if one exists). If the partition has no name, ZX_ERR_NOT_SUPPORTED is returned.

Request

<EMPTY>

Response

NameType
status zx/Status
name string:128?

GetTypeGuid

Gets the type GUID of the partition (if one exists). If the partition has no type GUID, ZX_ERR_NOT_SUPPORTED is returned.

Request

<EMPTY>

Response

NameType
status zx/Status
guid Guid?

GetVolumeInfo

Returns the information about this volume and the volume manager it is embedded in.

Returns ZX_ERR_NOT_SUPPORTED if the device is not a volume.

Request

<EMPTY>

Response

NameType
status zx/Status
manager VolumeManagerInfo?
volume VolumeInfo?

OpenSession

Opens a new FIFO-based session on the block device.

Request

NameType
session server_end:Session

OpenSessionWithOffsetMap

Opens a new FIFO-based session on the block device, providing a mapping which is transparently applied to device offsets in block FIFO requests.

This interface is intended to be used internally between nested Block implementations, in order to provide passthrough I/O. For example, a fixed partition map (e.g. GPT) will serve a Block protocol for each partition, and will respond to OpenSession requests by calling OpenSessionWithOffsetMap on the underlying block device, establishing itself as the source for translating client block offsets (relative to the partition start) to absolute offsets. The client can then communicate directly with the underlying block device, and the partition offsets can be transparently applied to requests.

Request

NameType
session server_end:Session
mapping BlockOffsetMapping

QuerySlices

Returns the number of contiguous allocated (or unallocated) vslices starting from each vslice.

Returns ZX_ERR_NOT_SUPPORTED if the device is not a volume.

Request

NameType
start_slices vector<uint64>:16

Response

NameType
status zx/Status
response array<VsliceRange, 16>
response_count uint64

Shrink

Shrinks a virtual partition. Returns ZX_OK if ANY slices are freed, even if part of the requested range contains unallocated slices.

Returns ZX_ERR_NOT_SUPPORTED if the device is not a volume.

Request

NameType
start_slice uint64
slice_count uint64

Response

NameType
status zx/Status

Session

Defined in fuchsia.storage.block/block.fidl

Represents a session with a block device.

This protocol encodes the underlying object's lifetime in both directions; the underlying object is alive iff both ends of the protocol are open. That is:

  • Closing the client end causes the object to be destroyed.
  • Observing a closure of the server end indicates the object no longer exists.

The object can be destroyed synchronously using fuchsia.unknown/Closeable.Close.

AttachVmo

Attaches a VMO to the session.

Returns an identifer that can be used to refer to the VMO.

Request

NameType
vmo handle<vmo>

Response

NameType
payload Session_AttachVmo_Result

Close

Terminates the connection.

After calling Close, the client must not send any other requests.

Servers, after sending the status response, should close the connection regardless of status and without sending an epitaph.

Closing the client end of the channel should be semantically equivalent to calling Close without knowing when the close has completed or its status.

Request

<EMPTY>

Response

NameType
payload fuchsia.unknown/Closeable_Close_Result

GetFifo

Returns a handle to the client end of the FIFO.

Request

<EMPTY>

Response

NameType
payload Session_GetFifo_Result

VolumeManager

Defined in fuchsia.storage.block/block.fidl

VolumeManager controls a collection of Volumes.

Activate

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.

Request

NameType
old_guid Guid
new_guid Guid

Response

NameType
status zx/Status

AllocatePartition

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.

Request

NameType
slice_count uint64
type Guid
instance Guid
name string:128
flags uint32

Response

NameType
status zx/Status

GetInfo

Gets the VolumeManagerInfo describing this instance of the VolumeManager.

NOTE: GetInfo() is used to synchronize child partition device visibility with devfs. Implementations must only respond once all child partitions of VolumeManager have been added to devfs, to guarantee clients can safely enumerate them.

See https://fxbug.dev/42077585 for more information.

Request

<EMPTY>

Response

NameType
status zx/Status
info VolumeManagerInfo?

GetPartitionLimit

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.

The partition may be larger than this limit if a smaller limit was applied after the partition had already grown to the current size.

Currently the partition limit is not persisted across reboots but this may change in the future.

Request

NameType
guid Guid

Response

NameType
status zx/Status
slice_count uint64

SetPartitionLimit

Sets the allocation limit for the partition. Partitions can not be extended beyond their allocation limit. The partition limit will never shrink partitions so if this value is less than the current partition size, it will keep the current size but prevent further growth.

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.

Request

NameType
guid Guid
slice_count uint64

Response

NameType
status zx/Status

SetPartitionName

Renames the specified partition. Any existing devices that include the name of the partition in their topological path might not reflect the name change until the next time that the device is instantiated.

Request

NameType
guid Guid
name string:128

Response

NameType
payload VolumeManager_SetPartitionName_Result

STRUCTS

BlockInfo

Defined in fuchsia.storage.block/block.fidl

FieldTypeDescriptionDefault
block_count uint64

The number of blocks in this block device.

No default
block_size uint32

The size of a single block.

No default
max_transfer_size uint32

The maximum size, in bytes, of a transfer. Set to MAX_TRANSFER_UNBOUNDED if no such maximum exists.

No default
flags DeviceFlag

Identifiers about the device.

No default

BlockOffsetMapping

Defined in fuchsia.storage.block/block.fidl

Describes a re-mapping of a block range. See OffsetMap. Note that all fields are in blocks, not bytes.

FieldTypeDescriptionDefault
source_block_offset uint64 No default
target_block_offset uint64 No default
length uint64 No default

Block_GetInfo_Response

Defined in fuchsia.storage.block/block.fidl

FieldTypeDescriptionDefault
info BlockInfo No default

Guid

Defined in fuchsia.storage.block/block.fidl

A Globally Unique IDentifier, which may be utilized to identify a partition.

FieldTypeDescriptionDefault
value array<uint8, 16> No default

Session_AttachVmo_Response

Defined in fuchsia.storage.block/block.fidl

FieldTypeDescriptionDefault
vmoid VmoId No default

Session_GetFifo_Response resource

Defined in fuchsia.storage.block/block.fidl

FieldTypeDescriptionDefault
fifo handle<fifo> No default

VmoId

Defined in fuchsia.storage.block/block.fidl

FieldTypeDescriptionDefault
id uint16 No default

VolumeInfo

Defined in fuchsia.storage.block/block.fidl

FieldTypeDescriptionDefault
partition_slice_count uint64

Number of slices allocated to the volume.

No default
slice_limit uint64

Limit on the maximum slices assigned to this partition, if there is one. If the size of the partition is not limited, this value will be 0. Partitions can grow into free slices available in the volume manager as long as their slices are less than or equal to this value.

The partition may be larger than this limit if a smaller limit was applied after the partition had already grown to the current size.

See VolumeManager.GetPartitionLimit()

No default

VolumeManagerInfo

Defined in fuchsia.storage.block/block.fidl

VolumeManagerInfo describes the properties of the volume manager and not each individual volume.

FieldTypeDescriptionDefault
slice_size uint64

Size of a single slice, in bytes.

No default
slice_count uint64

Number of slices the volume manager is able use right now. This counts the allocated_slice_count plus the number of available slices.

No default
assigned_slice_count uint64

Number of slices currently assigned to partitions.

No default
maximum_slice_count uint64

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 value is the number of entries reserved in the volume manager header and is not related to the size of the physical device (which may be larger or smaller).

No default
max_virtual_slice uint64

Largest value that can be used for a virtual slice number.

No default

VolumeManager_SetPartitionName_Response

Defined in fuchsia.storage.block/block.fidl

<EMPTY>

VsliceRange

Defined in fuchsia.storage.block/block.fidl

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.

FieldTypeDescriptionDefault
allocated bool

True if the virtual slices are allocated, false otherwise.

No default
count uint64

The number of contiguous virtual slices.

No default

ENUMS

BlockOpcode strict

Type: uint8

Defined in fuchsia.storage.block/block.fidl

The opcode used in FIFO requests.

NameValueDescription
1

Performs a regular data read or write from the device. The operation may be cached internally.

2
3

Write any controller or device cached data to nonvolatile storage.

4

Instructs the device to invalidate a number of blocks, making them usable for storing something else. This is basically a "delete" optimization, where the device is in charge of discarding the old content without clients having to write a given pattern. The operation may be cached internally.

5

Detaches the VMO from the block device.

TABLES

Block_GetMetadata_Response

Defined in fuchsia.storage.block/block.fidl

OrdinalFieldTypeDescription
name string:128
type_guid Guid
instance_guid Guid
start_block_offset uint64

start_block_offset will be absent if the partition is non-contiguous.

num_blocks uint64

num_blocks will be absent if the partition is a dynamic volume, in which case fuchsia.storage.block.Block/GetVolumeInfo should be called instead.

flags uint64

UNIONS

Block_GetInfo_Result strict

Defined in fuchsia.storage.block/block.fidl

OrdinalVariantTypeDescription
response Block_GetInfo_Response
err zx/Status

Block_GetMetadata_Result strict

Defined in fuchsia.storage.block/block.fidl

OrdinalVariantTypeDescription
response Block_GetMetadata_Response
err zx/Status

Session_AttachVmo_Result strict

Defined in fuchsia.storage.block/block.fidl

OrdinalVariantTypeDescription
response Session_AttachVmo_Response
err zx/Status

Session_GetFifo_Result strict resource

Defined in fuchsia.storage.block/block.fidl

OrdinalVariantTypeDescription
response Session_GetFifo_Response
err zx/Status

VolumeManager_SetPartitionName_Result strict

Defined in fuchsia.storage.block/block.fidl

OrdinalVariantTypeDescription
response VolumeManager_SetPartitionName_Response
err zx/Status

BITS

BlockIoFlag strict

Type: uint32

Defined in fuchsia.storage.block/block.fidl

Flags which may be attached to FIFO requests.

NameValueDescription
1

Associate the following request with group.

2

Only respond after this request (and all previous within group) have completed. Only valid with GROUP_ITEM.

4

Mark this operation as "Force Unit Access" (FUA), indicating that it should not complete until the data is written to the non-volatile medium (write), and that reads should bypass any on-device caches.

8

Attaches a pre-barrier to a request. This will ensure that no request which was executed before this request will be re-ordered to execute after this request.

NOTE: Barriers do NOT guarantee ordering of in-flight requests. Any request which the client has not yet received a response for is considered in-flight, and no guarantees are made about relative ordering with this request. This has important implications for grouped requests: A request in the middle of a group with PRE_BARRIER set will NOT have ordering guarantees relative to the other requests in the same group.

16

If set, the request is to be decompressed.

32

Use the slot and dun inline encryption (write) or decryption (read) parameters. Can only be used if the underlying hardware supports inline encryption.

DeviceFlag strict

Type: uint32

Defined in fuchsia.storage.block/block.fidl

NameValueDescription
1

All writes to the block device will fail.

2

The block device may be removed from the device during operation.

8

The device provides trim support.

16

The device provides Force Unit Access (FUA) support.

If this bit is unset, and a request is sent with the FORCE_ACCESS option set, the device will simulate a FUA by executing a device flush after the request completes (but before responding to the client). Clients are strongly encouraged to probe for FUA support and avoid usage of FORCE_ACCESS without device support, since this is expensive.

32

The device provides zstd decompression support.

64

The device provides Barrier support.

If this bit is unset, and a request is sent with the PRE_BARRIER option set, the device will simulate a barrier by executing a device flush before the request is submitted. Clients are strongly encouraged to probe for barrier support and avoid usage of PRE_BARRIER without device support, since this is expensive.

CONSTANTS

NameValueTypeDescription
ALLOCATE_PARTITION_FLAG_INACTIVE 1 uint32

Indicates that the partition should be created as inactive, implying that it will be destroyed on reboot (unless activated by a call to "Activate").

GUID_LENGTH 16 uint32
MAX_DECOMPRESSED_BYTES 134217728 uint64

The maximum amount of data that can be decompressed in a single group of decompression operations.

MAX_SLICE_REQUESTS 16 uint32

An arbitrary cap on the number of slices which may be requested when querying for allocation information from a volume.

MAX_TRANSFER_UNBOUNDED 4294967295 uint32

The maximum value for a transfer size, identifying that there effectively exists no maximum for a single operation.

MAX_TXN_GROUP_COUNT 8 uint32

Multiple block I/O operations may be sent at once before a response is actually sent back. Block I/O ops may be sent concurrently to different vmoids, and they also may be sent to different groups at any point in time.

MAX_TXN_GROUP_COUNT "groups" are pre-allocated lanes separated on the block server. Using a group allows multiple message to be buffered at once on a single communication channel before receiving a response.

Usage of groups is identified by the GROUP_ITEM flag, and is optional.

These groups may be referred to with a "groupid", in the range [0, MAX_TXN_GROUP_COUNT).

The protocol to communicate with a single group is as follows:

  1. SEND [N - 1] messages with an allocated groupid for any value of 1 <= N. The GROUP_ITEM flag is set for these messages.
  2. SEND a final Nth message with the same groupid. The GROUP_ITEM | GROUP_LAST flags are set for this message.
  3. RECEIVE a single response from the Block I/O server after all N requests have completed. This response is sent once all operations either complete or a single operation fails. At this point, step (1) may begin again for the same groupid.

For READ and WRITE, N may be greater than 1. Otherwise, N == 1 (skipping step (1) in the protocol above).

Notes:

  • groupids may operate on any number of vmoids at once.
  • If additional requests are sent on the same groupid before step (3) has completed, then the additional request will not be processed. If GROUP_LAST is set, an error will be returned. Otherwise, the request will be silently dropped.
  • Messages within a group are not guaranteed to be processed in any order relative to each other.
  • All requests receive responses, except for ones with GROUP_ITEM that do not have GROUP_LAST set.

For example, the following is a valid sequence of transactions:

-> (groupid = 1, vmoid = 1, OP = Write | GroupItem, reqid = 1) -> (groupid = 1, vmoid = 2, OP = Write | GroupItem, reqid = 2) -> (groupid = 2, vmoid = 3, OP = Write | GroupItem | GroupLast, reqid = 0) <- Response sent to groupid = 2, reqid = 0 -> (groupid = 1, vmoid = 1, OP = Read | GroupItem | GroupLast, reqid = 3) <- Response sent to groupid = 1, reqid = 3 -> (groupid = 3, vmoid = 1, OP = Write | GroupItem, reqid = 4) -> (groupid = don't care, vmoid = 1, OP = Read, reqid = 5) <- Response sent to reqid = 5 -> (groupid = 3, vmoid = 1, OP = Read | GroupItem | GroupLast, reqid = 6) <- Response sent to groupid = 3, reqid = 6

Each transaction reads or writes up to length blocks from the device, starting at dev_offset blocks, into the VMO associated with vmoid, starting at vmo_offset blocks. If the transaction is out of range, for example if length is too large or if dev_offset is beyond the end of the device, ZX_ERR_OUT_OF_RANGE is returned.

NAME_LENGTH 128 uint32
VMOID_INVALID 0 uint16

Value reserved for "invalid" VmoId. Will never be allocated by the server, and may be utilized as a local value for an unallocated ID.