fuchsia.storage.block

Added: HEAD

协议

屏蔽

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

定义对设备的访问权限,该设备可按块粒度区块进行访问,以进行读取和写入。

ConnectMapper

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

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

请求

名称类型
server_end server_end:Mapper

响应

名称类型
payload Block_ConnectMapper_Result

销毁

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

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

请求

<EMPTY>

响应

名称类型
status zx/Result

延长

扩展此分区的映射。

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

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

请求

名称类型
start_slice uint64
slice_count uint64

响应

名称类型
status zx/Result

GetInfo

获取底层块存储设备的相关信息。

请求

<EMPTY>

响应

名称类型
payload Block_GetInfo_Result

GetInstanceGuid

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

请求

<EMPTY>

响应

名称类型
status zx/Result
guid Guid?

GetMetadata

获取分区的元数据。

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

请求

<EMPTY>

响应

名称类型
payload Block_GetMetadata_Result

GetName

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

请求

<EMPTY>

响应

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

GetTypeGuid

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

请求

<EMPTY>

响应

名称类型
status zx/Result
guid Guid?

GetVolumeInfo

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

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

请求

<EMPTY>

响应

名称类型
status zx/Result
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/Result
response array<VsliceRange, 16>
response_count uint64

缩小

缩减虚拟分区。如果释放了任何切片,则返回 ZX_OK,即使请求的范围中有一部分包含未分配的切片也是如此。

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

请求

名称类型
start_slice uint64
slice_count uint64

响应

名称类型
status zx/Result

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

RecordProfile

开始为此映射器会话录制访问配置文件。

请求

名称类型
recording server_end:Recording

响应

名称类型
payload MapperSession_RecordProfile_Result

录制

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

表示 MapperSession 上的活跃配置文件录制。

停止

停止性能分析记录,并返回 vmo 中记录的性能分析数据(对会话 key 和每次读取的预读对齐逻辑字节偏移量进行编码)。

请求

<EMPTY>

响应

名称类型
payload Recording_Stop_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

RegisterKey

向此会话注册内嵌加密密钥句柄(key_token 由 fuchsia.hardware.inlineencryption/Device.ProgramKey 返回)。

返回一个会话级范围的 slot 令牌,该令牌可在设置 BlockIoFlag.INLINE_ENCRYPTION_ENABLED 时在 BlockFifoRequest.slot 中传递。

  • 如果 key_token 不是此块存储设备的有效内嵌加密密钥令牌,或者密钥已被逐出,则会返回错误 ZX_ERR_ACCESS_DENIED。
  • 如果设备不支持内嵌加密,则会返回错误 ZX_ERR_NOT_SUPPORTED。

请求

名称类型
key_token handle<eventpair>

响应

名称类型
payload Session_RegisterKey_Result

VolumeManager

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

VolumeManager 控制一系列 Volume。

启用

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

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

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

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

请求

名称类型
old_guid Guid
new_guid Guid

响应

名称类型
status zx/Result

AllocatePartition

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

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

请求

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

响应

名称类型
status zx/Result

GetInfo

获取描述此 VolumeManager 实例的 VolumeManagerInfo。

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

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

请求

<EMPTY>

响应

名称类型
status zx/Result
info VolumeManagerInfo?

GetPartitionLimit

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

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

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

请求

名称类型
guid Guid

响应

名称类型
status zx/Result
slice_count uint64

SetPartitionLimit

设置分区的分配限制。分区无法扩展到超出其分配限制。分区限制绝不会缩减分区,因此,如果此值小于当前分区大小,则会保持当前大小,但会阻止进一步增长。

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

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

请求

名称类型
guid Guid
slice_count uint64

响应

名称类型
status zx/Result

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 资源

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

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

MapperSession_OpenChildSession_Response

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

<EMPTY>

MapperSession_RecordProfile_Response

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

<EMPTY>

Mapper_OpenSession_Response

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

<EMPTY>

Recording_Stop_Response 资源

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

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

Session_AttachVmo_Response

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

字段类型说明默认
vmoid VmoId 无默认应用

Session_GetFifo_Response 资源

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

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

Session_RegisterKey_Response

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

字段类型说明默认
slot uint8 无默认应用

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 加上可用切片数量。

无默认应用
assigned_slice_count uint64

当前分配给分区的切片数量。

无默认应用
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 strict

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

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

MapperSession_CreateVmo_Result strict resource

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

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

MapperSession_OpenChildSession_Result strict

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

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

MapperSession_RecordProfile_Result strict

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

序数变体类型说明
response MapperSession_RecordProfile_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

Recording_Stop_Result strict resource

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

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

Session_AttachVmo_Result strict

在 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

Session_RegisterKey_Result strict

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

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

VolumeManager_SetPartitionName_Result strict

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

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

BITS

BlockIoFlag strict

类型: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

设备提供剪辑支持。

16

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

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

32

设备提供 zstd 解压缩支持。

64

设备提供 Barrier 支持。

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

常量

名称值类型说明
ALLOCATE_PARTITION_FLAG_INACTIVE 1 uint32

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

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

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

注意:

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

例如,以下是有效的事务序列:

-> (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 的本地值。