摘要
对分页器拥有的一系列 VMO 执行操作。
声明
#include <zircon/syscalls.h>
zx_status_t zx_pager_op_range(zx_handle_t pager,
uint32_t op,
zx_handle_t pager_vmo,
uint64_t offset,
uint64_t length,
uint64_t data);
说明
对 pager_vmo 上 [offset、offset +
length)。pager_vmo 必须是之前由 pager 创建的
zx_pager_create_vmo()
。offset 和 length 必须页面对齐。data 是可选的
参数(如果指定的 op 支持此参数)。
可以执行的操作,即 op 可以采用的值:
ZX_PAGER_OP_DIRTY
- 用户空间分页器想要转换 [offset,
offset + length)从干净到脏。这将解除所有正在等待的写入操作
针对指定范围的 ZX_PAGER_VMO_DIRTY
个页面请求。
ZX_PAGER_OP_FAIL
- 用户空间分页器未能满足对 pager_vmo 中
使用 ZX_PAGER_VMO_READ
或 ZX_PAGER_VMO_DIRTY
命令时,将范围 [offset]、offset + 长度 [offset] 设为长度)。
data 包含遇到的错误(zx_status_t
错误代码符号扩展为 uint64_t
值)- 允许的值包括 ZX_ERR_IO
、ZX_ERR_IO_DATA_INTEGRITY
、ZX_ERR_BAD_STATE
ZX_ERR_NO_SPACE
和 ZX_ERR_BUFFER_TOO_SMALL
。
这将指示可能正在等待该范围内的页面请求的线程,从而解除对它们的阻塞。如果
被屏蔽的线程正在通过 zx_vmo_read()
/ zx_vmo_write()
或
zx_vmo_op_range()
使用 ZX_VMO_OP_COMMIT
,调用将失败并显示错误状态(数据)
返回的值。如果被屏蔽的线程正在通过 VMAR 映射请求页面,该线程将会
发生严重的页面错误异常。
ZX_PAGER_OP_WRITEBACK_BEGIN
- 用户空间分页器想要开始回写该范围内的页面
[offset、offset + length)。这表示想要清理指定
范围(通过 ZX_PAGER_OP_WRITEBACK_END
发出信号)。请参阅
请参阅下面的示例代码,了解建议的用法。
data 可以选择性地设置为 ZX_VMO_DIRTY_RANGE_IS_ZERO
,以表明调用方想要
将指定范围写回为 0。此字段适用于调用方处理
由 zx_pager_query_dirty_ranges()
返回的范围,其 options
设置为
ZX_VMO_DIRTY_RANGE_IS_ZERO
。它可确保在该范围内创建的任何非零内容
在查询之后、开始回写之前,如果错误地假定
并将其标记为干净(因此可逐出)。
ZX_PAGER_OP_WRITEBACK_END
- 用户空间分页器完成了对该范围内的页面写回
[offset、offset + length)。这表示指定范围内的所有脏页
之前带有 ZX_PAGER_OP_WRITEBACK_BEGIN
信号的 API 可以标记为“安全”。请参阅
请参阅下面的示例代码,了解建议的用法。
内核可以随意逐出已标记为干净的任何页面或零个范围,之后 如果需要,用户空间分页器需要再次提供这些值。这也意味着 应注意避免任何正在投放中的过时用品, 刚刚撰写的内容。
用于发现和清理脏页的示例代码(模数错误处理)可能如下所示: 这个。
zx_vmo_dirty_range_t ranges[kMaxRanges];
uint64_t num_ranges;
zx_status_t st =
zx_pager_query_dirty_ranges(pager, vmo, 0, vmo_size, &ranges[0],
kMaxRanges * sizeof(zx_vmo_dirty_range_t), &num_ranges, nullptr);
for (uint64_t i = 0; i < num_ranges; i++) {
uint64_t start = ranges[i].offset;
uint64_t len = ranges[i].length;
st = zx_pager_op_range(pager, ZX_PAGER_OP_WRITEBACK_BEGIN, vmo, start, len, 0);
WritebackToDisk(vmo, start, len);
st = zx_pager_op_range(pager, ZX_PAGER_OP_WRITEBACK_END, vmo, start, len, 0);
}
权限
pager 的类型必须为 ZX_OBJ_TYPE_PAGER
且包含 ZX_RIGHT_MANAGE_VMO
。
pager_vmo 的类型必须为 ZX_OBJ_TYPE_VMO
且包含 ZX_RIGHT_WRITE
。
返回值
zx_pager_op_range()
在成功时返回 ZX_OK,或者在失败时返回以下某个错误代码。
错误
ZX_ERR_BAD_HANDLE
pager 或 pager_vmo 不是有效的句柄。
ZX_ERR_WRONG_TYPE
pager 不是分页器句柄,或 pager_vmo 不是 VMO 句柄。
ZX_ERR_ACCESS_DENIED
分页器不含 ZX_RIGHT_MANAGE_VMO
或 pager_vmo 不含
ZX_RIGHT_WRITE
。
ZX_ERR_INVALID_ARGS
:
- pager_vmo 不是通过 pager 创建的 VMO。
- offset 或 length 未页面对齐。
- op 为 ZX_PAGER_OP_FAIL
,data 不是 ZX_ERR_IO
和 ZX_ERR_IO_DATA_INTEGRITY
其中之一
或 ZX_ERR_BAD_STATE
。
- op 为 ZX_PAGER_OP_WRITEBACK_BEGIN
,data 不是 0 或 ZX_VMO_DIRTY_RANGE_IS_ZERO
。
ZX_ERR_OUT_OF_RANGE
pager_vmo 中指定的范围无效。
pager_vmo 中的指定范围不支持 ZX_ERR_NOT_SUPPORTED
op。
ZX_ERR_NOT_FOUND
op 为 ZX_PAGER_OP_DIRTY
,范围由 offset 和
length 包含未提供的区域,或之前填充过但后来填充的区域
被内核逐出。
ZX_ERR_BAD_STATE
op 为 ZX_PAGER_OP_DIRTY
或 ZX_PAGER_OP_FAIL
,并且 pager_vmo 已
与分页器分离。