fuchsia.storage.block

添加了:HEAD

PROTOCOLS

屏蔽

在 fuchsia.storage.block/block.fidl 中定义

定义对设备的访问权限,该设备可按块粒度分块进行读写。

ConnectMapper

连接到设备的映射器协议,允许只读映射页面调度。 由于调用方已持有对 Block 的句柄(授予对设备的完整读/写访问权限),因此该方法提供了一种直接获取相应 Mapper 协议的方式,而无需使用带外渠道或单独的功能路由。

如果设备或驱动程序不支持 Mapper 协议,则返回 ZX_ERR_NOT_SUPPORTED。

请求

名称类型
server_end server_end:Mapper

响应

名称类型
payload Block_ConnectMapper_Result

销毁

销毁当前卷,将其从 VolumeManager 中移除,并释放所有底层存储空间。与卷的连接也会关闭。

如果设备不是卷,则返回 ZX_ERR_NOT_SUPPORTED。

请求

<EMPTY>

响应

名称类型
status zx/Status

延长

扩展相应分区的映射。

能否扩展分区取决于底层设备是否有足够的可用空间、卷管理器标头中是否有足够的可用 slot 来跟踪字节,以及分区限制(请参阅 VolumeManager.SetPartitionLimit)。

如果设备不是卷,则返回 ZX_ERR_NOT_SUPPORTED。

请求

名称类型
start_slice uint64
slice_count uint64

响应

名称类型
status zx/Status

GetInfo

获取有关底层块设备的信息。

请求

<EMPTY>

响应

名称类型
payload Block_GetInfo_Result

GetInstanceGuid

获取分区(如果存在)的实例 GUID。 如果分区没有实例 GUID,则返回 ZX_ERR_NOT_SUPPORTED。

请求

<EMPTY>

响应

名称类型
status zx/Status
guid Guid?

GetMetadata

获取分区的元数据。

如果分区没有给定的元数据,则字段可能不存在。

请求

<EMPTY>

响应

名称类型
payload Block_GetMetadata_Result

GetName

获取分区的名称(如果存在)。 如果分区没有名称,则返回 ZX_ERR_NOT_SUPPORTED。

请求

<EMPTY>

响应

名称类型
status zx/Status
name string:128?

GetTypeGuid

获取分区(如果存在)的类型 GUID。 如果分区没有类型 GUID,则返回 ZX_ERR_NOT_SUPPORTED。

请求

<EMPTY>

响应

名称类型
status zx/Status
guid Guid?

GetVolumeInfo

返回有关此卷及其嵌入的卷管理器的信息。

如果设备不是卷,则返回 ZX_ERR_NOT_SUPPORTED。

请求

<EMPTY>

响应

名称类型
status zx/Status
manager VolumeManagerInfo?
volume VolumeInfo?

OpenSession

在块设备上打开新的基于 FIFO 的会话。

请求

名称类型
session server_end:Session

OpenSessionWithOptions

在块设备上打开新的基于 FIFO 的会话,并提供其他选项。

映射

mappings 实参是逻辑 -> 物理块映射的列表,服务器将在会话中透明地将其应用于块 FIFO 请求中的设备偏移量。映射在逻辑上是连续的,从逻辑偏移量 0 开始。

此接口旨在供嵌套的 Block 实现之间在内部使用,以提供直通 I/O。例如,固定分区映射(例如 GPT)将为每个分区提供一个块协议,并通过在底层块设备上调用 OpenSessionWithOptions 来响应 OpenSession 请求,从而提供将相对于(且受限于)分区的块偏移量转换为设备上的绝对偏移量的映射。

映射只能限制设备的可见范围;服务器会拒绝超出设备范围的映射。

如果 mappings 为空,会话渠道将关闭,并显示墓志铭 ZX_ERR_INVALID_ARGS。

请求

名称类型
session server_end:Session
mappings vector<BlockOffsetMapping>:4

QuerySlices

返回从每个 vslice 开始的连续已分配(或未分配)vslice 的数量。

如果设备不是卷,则返回 ZX_ERR_NOT_SUPPORTED。

请求

名称类型
start_slices vector<uint64>:16

响应

名称类型
status zx/Status
response array<VsliceRange, 16>
response_count uint64

缩小

缩小虚拟分区。如果释放了任何切片,即使所请求范围的一部分包含未分配的切片,也会返回 ZX_OK。

如果设备不是卷,则返回 ZX_ERR_NOT_SUPPORTED。

请求

名称类型
start_slice uint64
slice_count uint64

响应

名称类型
status zx/Status

Mapper

在 fuchsia.storage.block/block.fidl 中定义

由块驱动程序公开,通过 fshost 路由到 pkg-cache。

OpenSession

使用映射 VMO 和验证器句柄来引导驱动程序映射器。

请求

名称类型
session server_end:MapperSession
mapping_vmo handle<vmo>
port handle<port>?
delivery_queue handle<vmo>?

响应

名称类型
payload Mapper_OpenSession_Result

MapperSession

在 fuchsia.storage.block/block.fidl 中定义

表示有效的驱动程序映射会话。

关闭

终止连接。

调用 Close 后,客户端不得发送任何其他请求。

服务器在发送状态响应后,应关闭连接,无论状态如何,且不发送墓志铭。

关闭通道的客户端端在语义上应等同于调用 Close,但不知道关闭何时完成或其状态。

请求

<EMPTY>

响应

名称类型
payload fuchsia.unknown/Closeable_Close_Result

CreateVmo

创建与 key 关联的 size 字节的基于分页内存的 VMO。 此 VMO 上的页面错误由驱动程序映射器直接处理。

请求

名称类型
key uint64
size uint64
options CreateVmoOptions

响应

名称类型
payload MapperSession_CreateVmo_Result

OpenChildSession

打开一个子映射器会话,其读取操作通过父会话中的 parent_key 进行映射。 当父会话关闭时,从中打开的所有子会话也会随之关闭。

请求

名称类型
session server_end:MapperSession
mapping_vmo handle<vmo>
parent_key uint64
port handle<port>?
delivery_queue handle<vmo>?

响应

名称类型
payload MapperSession_OpenChildSession_Result

会话

在 fuchsia.storage.block/block.fidl 中定义

表示与块设备的会话。

此协议在两个方向上对底层对象的生命周期进行编码;当且仅当协议的两端都处于打开状态时,底层对象才处于活动状态。即:

  • 关闭客户端会导致对象被销毁。
  • 观察到服务器端关闭表示对象不再存在。

可以使用 fuchsia.unknown/Closeable.Close 同步销毁对象。

AttachVmo

将 VMO 附加到会话。不支持可调整大小的 VMO,并将返回 ZX_ERR_INVALID_ARGS。

返回可用于引用 VMO 的标识符。

请求

名称类型
vmo handle<vmo>

响应

名称类型
payload Session_AttachVmo_Result

关闭

终止连接。

调用 Close 后,客户端不得发送任何其他请求。

服务器在发送状态响应后,应关闭连接,无论状态如何,且不发送墓志铭。

关闭通道的客户端端在语义上应等同于调用 Close,但不知道关闭何时完成或其状态。

请求

<EMPTY>

响应

名称类型
payload fuchsia.unknown/Closeable_Close_Result

GetFifo

返回 FIFO 客户端端的句柄。

请求

<EMPTY>

响应

名称类型
payload Session_GetFifo_Result

VolumeManager

在 fuchsia.storage.block/block.fidl 中定义

VolumeManager 用于控制一组卷。

启用

以原子方式将一个虚拟分区(按实例 GUID)标记为非活动状态,同时查找另一个分区(按实例 GUID)并将其标记为活动状态。

如果“旧”分区不存在,系统会忽略该 GUID。 如果“旧”分区与“新”分区相同,则忽略“旧”GUID。 如果“新”分区不存在,则返回 ZX_ERR_NOT_FOUND。

此函数不会销毁“旧”分区,只会将其标记为不活动状态。如需回收该空间,必须明确销毁“旧”分区。当 FVM 驱动程序重新绑定时(即在重新启动时),也会自动发生这种销毁。

此函数可能对 FVM 中的 A/B 更新很有用,因为它允许激活更新后的分区。

请求

名称类型
old_guid Guid
new_guid Guid

响应

名称类型
status zx/Status

AllocatePartition

分配具有所请求功能的虚拟分区。

slice_count 是最初分配给偏移量为零的分区的切片数。分配给新分区的 slice 数量必须至少为 1。 type 和 value 分别表示分区类型和实例 GUID。 name 表示新分区的名称。

请求

名称类型
slice_count uint64
type Guid
instance Guid
name string:128
flags uint32

响应

名称类型
status zx/Status

GetInfo

获取描述 VolumeManager 的相应 VolumeManagerInfo。

NOTE:GetInfo() 用于将子分区设备可见性与 devfs 同步。实现必须仅在 VolumeManager 的所有子分区都已添加到 devfs 后才进行响应,以保证客户端可以安全地枚举它们。

如需了解详情,请参阅 https://fxbug.dev/42077585。

请求

<EMPTY>

响应

名称类型
status zx/Status
info VolumeManagerInfo?

GetPartitionLimit

检索分区对应的分配限制。返回值为 0 表示没有限制,只要设备上有可用空间,就可以扩展分区。

如果分区已增长到当前大小,但之后应用了较小的限制,则分区可能会大于此限制。

目前,分区限制不会在重新启动后保留,但未来可能会发生变化。

请求

名称类型
guid Guid

响应

名称类型
status zx/Status
slice_count uint64

SetPartitionLimit

设置分区的分配限制。分区无法扩展到其分配限制之外。分区限制永远不会缩小分区,因此如果此值小于当前分区大小,系统将保留当前大小,但会阻止进一步增长。

分配限制位于 VolumeManager API 上,而不是位于分区上,因为它们代表更高的功能级别。这些限制旨在为块设备(以及 Volume API)的用户提供保护。

目前,分区限制不会在重启后保留,但未来可能会发生变化。

请求

名称类型
guid Guid
slice_count uint64

响应

名称类型
status zx/Status

SetPartitionName

重命名指定的分区。任何在其拓扑路径中包含分区名称的现有设备可能不会反映名称更改,直到下次实例化设备时才会反映。

请求

名称类型
guid Guid
name string:128

响应

名称类型
payload VolumeManager_SetPartitionName_Result

STRUCTS

BlockInfo

在 fuchsia.storage.block/block.fidl 中定义

字段类型说明默认
block_count uint64

相应块设备中的块数。

无默认值
block_size uint32

单个块的大小。

无默认值
max_transfer_size uint32

一次传输的最大大小(以字节为单位)。如果不存在此类上限,则设置为 MAX_TRANSFER_UNBOUNDED。

无默认值
flags DeviceFlag

有关设备的标识符。

无默认值

BlockOffsetMapping

在 fuchsia.storage.block/block.fidl 中定义

描述块范围的重新映射。逻辑偏移量由传递给 OpenSessionWithOptions 的列表中的位置隐含,该列表是逻辑上连续的映射列表。请注意,所有字段均以块为单位,而非以字节为单位。

字段类型说明默认
target_block_offset uint64 无默认值
length uint64 无默认值

Block_ConnectMapper_Response

在 fuchsia.storage.block/block.fidl 中定义

<EMPTY>

Block_GetInfo_Response

在 fuchsia.storage.block/block.fidl 中定义

字段类型说明默认
info BlockInfo 无默认值

Guid

在 fuchsia.storage.block/block.fidl 中定义

一个全局唯一标识符,可用于标识分区。

字段类型说明默认
value array<uint8, 16> 无默认值

MapperSession_CreateVmo_Response resource

在 fuchsia.storage.block/block.fidl 中定义

字段类型说明默认
vmo handle<vmo> 无默认值

MapperSession_OpenChildSession_Response

在 fuchsia.storage.block/block.fidl 中定义

<EMPTY>

Mapper_OpenSession_Response

在 fuchsia.storage.block/block.fidl 中定义

<EMPTY>

Session_AttachVmo_Response

在 fuchsia.storage.block/block.fidl 中定义

字段类型说明默认
vmoid VmoId 无默认值

Session_GetFifo_Response 资源

在 fuchsia.storage.block/block.fidl 中定义

字段类型说明默认
fifo handle<fifo> 无默认值

VmoId

在 fuchsia.storage.block/block.fidl 中定义

字段类型说明默认
id uint16 无默认值

VolumeInfo

在 fuchsia.storage.block/block.fidl 中定义

字段类型说明默认
partition_slice_count uint64

分配给卷的切片数。

无默认值
slice_limit uint64

分配给相应分区的切片数量上限(如果有)。如果分区的大小不受限制,则此值为 0。只要分区的切片小于或等于此值,分区就可以扩展为卷管理器中可用的空闲切片。

如果分区已增长到当前大小,但之后应用了较小的限制,则分区可能会大于此限制。

请访问 VolumeManager.GetPartitionLimit()

无默认值

VolumeManagerInfo

在 fuchsia.storage.block/block.fidl 中定义

VolumeManagerInfo 描述的是音量管理器的属性,而不是每个单独的音量。

字段类型说明默认
slice_size uint64

单个切片的大小(以字节为单位)。

无默认值
slice_count uint64

卷管理器目前能够使用的切片数量。此指标会统计 allocated_slice_count 加上可用 slice 的数量。

无默认值
assigned_slice_count uint64

当前分配给分区的 slice 数量。

无默认值
maximum_slice_count uint64

如果包含卷管理器的分区本身扩展(即,卷管理器在已扩展到超出最初分配容量的 GPT 分区上初始化),则卷管理器可增长到的最大容量。此值是卷管理器标头中预留的条目数,与实体设备的大小(可能更大或更小)无关。

无默认值
max_virtual_slice uint64

可用于虚拟切片编号的最大值。

无默认值

VolumeManager_SetPartitionName_Response

在 fuchsia.storage.block/block.fidl 中定义

<EMPTY>

VsliceRange

在 fuchsia.storage.block/block.fidl 中定义

VsliceRange 描述了虚拟切片的范围:起始位置、长度和分配状态。

这些范围会以有序容器的形式返回,其中隐式描述了从“索引零”切片开始的起始偏移量。

字段类型说明默认
allocated bool

如果已分配虚拟切片,则为 True;否则为 False。

无默认值
count uint64

连续虚拟切片的数量。

无默认值

枚举

BlockOpcode strict

类型:uint8

在 fuchsia.storage.block/block.fidl 中定义

FIFO 请求中使用的操作码。

名称值说明
1

执行从设备的常规数据读取或写入。该操作可能会在内部缓存。

2
3

将所有控制器或设备缓存数据写入非易失性存储空间。

4

指示设备使若干个块失效,以便将这些块用于存储其他内容。这基本上是一种“删除”优化,其中设备负责舍弃旧内容,而无需客户端写入给定的模式。该操作可能会在内部缓存。

5

从块设备分离 VMO。

TABLES

PartitionInfo

在 fuchsia.storage.block/block.fidl 中定义

描述分区的元数据。

序数字段类型说明
name string:128
type_guid Guid
instance_guid Guid
start_block_offset uint64

如果分区是多个物理分区的组合,则 start_block_offset 将不存在。请参阅 fuchsia.storage.partitions.OverlayPartition。

num_blocks uint64

如果分区是卷,则 num_blocks 将不存在,该卷的大小是动态的,可以通过 fuchsia.storage.block.Block/Extend 增长。如需获取当前大小,请使用 fuchsia.storage.block.Block/GetVolumeInfo。

flags uint64

分区表条目标志(例如,在 GPT 分区中,为 GPT 分区表条目标志)。请注意,这与 BlockInfo 中返回的设备标志不同。对于复合分区,此字段将不存在。

UNIONS

Block_ConnectMapper_Result strict

在 fuchsia.storage.block/block.fidl 中定义

序数变体类型说明
response Block_ConnectMapper_Response
err zx/Status

Block_GetInfo_Result strict

在 fuchsia.storage.block/block.fidl 中定义

序数变体类型说明
response Block_GetInfo_Response
err zx/Status

Block_GetMetadata_Result 严格

在 fuchsia.storage.block/block.fidl 中定义

序数变体类型说明
response PartitionInfo
err zx/Status

MapperSession_CreateVmo_Result 严格 资源

在 fuchsia.storage.block/block.fidl 中定义

序数变体类型说明
response MapperSession_CreateVmo_Response
err zx/Status
framework_err internal

MapperSession_OpenChildSession_Result 严格

在 fuchsia.storage.block/block.fidl 中定义

序数变体类型说明
response MapperSession_OpenChildSession_Response
err zx/Status
framework_err internal

Mapper_OpenSession_Result strict

在 fuchsia.storage.block/block.fidl 中定义

序数变体类型说明
response Mapper_OpenSession_Response
err zx/Status
framework_err internal

Session_AttachVmo_Result 严格

在 fuchsia.storage.block/block.fidl 中定义

序数变体类型说明
response Session_AttachVmo_Response
err zx/Status

Session_GetFifo_Result strict resource

在 fuchsia.storage.block/block.fidl 中定义

序数变体类型说明
response Session_GetFifo_Response
err zx/Status

VolumeManager_SetPartitionName_Result strict

在 fuchsia.storage.block/block.fidl 中定义

序数变体类型说明
response VolumeManager_SetPartitionName_Response
err zx/Status

BITS

BlockIoFlag 严格

类型:uint32

在 fuchsia.storage.block/block.fidl 中定义

可附加到 FIFO 请求的标志。

名称值说明
1

将以下请求与 group 相关联。

2

仅在此请求(以及组内的所有先前请求)完成后才进行响应。此参数必须与 GROUP_ITEM 共同使用才能生效。

4

将此操作标记为“强制单元访问”(FUA),表示在数据写入非易失性介质(写入)之前,此操作不应完成,并且读取应绕过任何设备端缓存。

8

将屏障前置附加到请求。这样可确保在相应请求之前执行的任何请求都不会重新排序,以在相应请求之后执行。

注意:屏障不保证进行中的请求的顺序。客户端尚未收到响应的任何请求都被视为正在处理中,并且不保证此请求的相对顺序。这对分组请求有重要影响:设置了 PRE_BARRIER 的组中间的请求不会相对于同一组中的其他请求有排序保证。

16

如果设置,则表示请求需要解压缩。

32

使用 slot 和 dun 内嵌加密(写入)或解密(读取)参数。 仅当底层硬件支持内嵌加密时才能使用。

CreateVmoOptions strict

类型:uint32

在 fuchsia.storage.block/block.fidl 中定义

MapperSession.CreateVmo 的选项。

名称值说明
1

如果设置,在缺页中断期间发生 I/O 错误时,会提供零填充页面并在 VMO 上断言 ZX_USER_SIGNAL_0,而不是因 ZX_ERR_IO 而导致页面请求失败。

DeviceFlag strict

类型:uint32

在 fuchsia.storage.block/block.fidl 中定义

名称值说明
1

对块设备的所有写入操作都将失败。

2

在运行期间,可能会从设备中移除块设备。

8

设备提供 TRIM 支持。

16

设备提供强制单元访问 (FUA) 支持。

如果未设置此位,并且发送的请求设置了 FORCE_ACCESS 选项,则设备会在请求完成后(但在响应客户端之前)执行设备刷新来模拟 FUA。强烈建议客户端探测 FUA 支持,并避免在设备不支持的情况下使用 FORCE_ACCESS,因为这会产生高昂的费用。

32

设备提供 zstd 解压缩支持。

64

设备提供 Barrier 支持。

如果未设置此位,并且发送的请求设置了 PRE_BARRIER 选项,设备将在提交请求之前执行设备刷新来模拟屏障。强烈建议客户端探测屏障支持,并避免在设备不支持的情况下使用 PRE_BARRIER,因为这会产生高昂的开销。

常量

名称值类型说明
ALLOCATE_PARTITION_FLAG_INACTIVE 1 uint32

表示应将分区创建为非活动状态,这意味着分区将在重新启动时被销毁(除非通过调用“激活”来激活)。

GUID_LENGTH 16 uint32
MAX_DECOMPRESSED_BYTES 134217728 uint64

在单个解压缩操作组中可以解压缩的最大数据量。

MAX_MAPPINGS 4 uint32

打开会话时可提供的块偏移量映射数量上限。 此限制是任意的,可以根据需要增加。

MAX_SLICE_REQUESTS 16 uint32

在从卷查询分配信息时,可请求的切片数量的任意上限。

MAX_TRANSFER_UNBOUNDED 4294967295 uint32

传输大小的最大值,用于标识单个操作实际上没有最大值。

MAX_TXN_GROUP_COUNT 8 uint32

在实际发送响应之前,可能会同时发送多个块 I/O 操作。块 I/O 操作可以同时发送到不同的 vmoid,也可以随时发送到不同的组。

MAX_TXN_GROUP_COUNT“组”是预先分配的通道,在块服务器上分隔。使用群组可让多个消息在单个通信渠道上同时缓冲,然后再接收响应。

群组的使用由 GROUP_ITEM 标志标识,是可选的。

这些群组可以通过“groupid”来引用,范围为 [0, MAX_TXN_GROUP_COUNT)。

与单个群组通信的协议如下:

  1. 发送 [N - 1] 条消息,并为任意值 1 <= N 分配 groupid。 系统会为这些消息设置 GROUP_ITEM 标志。
  2. 发送具有相同 groupid 的最终第 N 条消息。此消息设置了 GROUP_ITEM | GROUP_LAST 标志。
  3. 在所有 N 个请求完成后,从块 I/O 服务器接收单个响应。当所有操作完成或单个操作失败时,系统会发送此响应。此时,可能会针对同一 groupid 再次开始执行步骤 (1)。

对于 READ 和 WRITE,N 可以大于 1。否则,N == 1(跳过上述协议中的第 (1) 步)。

注意:

  • groupids 可以同时对任意数量的 vmoid 进行操作。
  • 如果在步骤 (3) 完成之前针对同一 groupid 发送了其他请求,则系统不会处理这些额外请求。如果设置了 GROUP_LAST,则会返回错误。否则,系统会静默地丢弃该请求。
  • 无法保证组内消息的处理顺序。
  • 所有请求都会收到响应,但设置了 GROUP_ITEM 且未设置 GROUP_LAST 的请求除外。

例如,以下是一系列有效的交易:

-> (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

每个事务从设备读取或写入最多 length 个块,从 dev_offset 个块开始,写入与 vmoid 关联的 VMO,从 vmo_offset 个块开始。如果交易超出范围,例如 length 过大或 dev_offset 超出设备末尾,则返回 ZX_ERR_OUT_OF_RANGE。

NAME_LENGTH 128 uint32
VMOID_INVALID 0 uint16

为“无效”VmoId 保留的值。永远不会由服务器分配,并且可用作未分配 ID 的本地值。