zx_pager_query_dirty_ranges

总结

在分页器拥有的 VMO 中查询连续范围的脏页。

声明

#include <zircon/syscalls.h>

zx_status_t zx_pager_query_dirty_ranges(zx_handle_t pager,
                                        zx_handle_t pager_vmo,
                                        uint64_t offset,
                                        uint64_t length,
                                        void* buffer,
                                        size_t buffer_size,
                                        size_t* actual,
                                        size_t* avail);

说明

针对 [offset, offset + length) 范围内的连续页面查询 pager_vmo,这些页面是脏页,即具有尚未写回分页器来源的待处理修改。pager_vmo 必须是 zx_pager_create_vmo() 之前通过分页器创建的。 offsetlength 无需页面对齐,但它们在执行查询时会被四舍五入为页面边界。

buffer 应指向一个 zx_vmo_dirty_range_t 结构体数组,用于保存查询结果,buffer_size 应可容纳该数组。

typedef struct zx_vmo_dirty_range {
  // Represents the range [offset, offset + length).
  uint64_t offset;
  uint64_t length;
  // Any options applicable to the range.
  // ZX_VMO_DIRTY_RANGE_IS_ZERO indicates that the range contains all zeros.
  uint64_t options;
} zx_vmo_dirty_range_t;

actual 是一个可选指针,用于返回已写入 buffer 的脏范围数。

availability 是一个可选指针,用于返回可供读取的脏范围数量。如果 buffer 不够大,则 availability 将大于 actual

如果成功,“actual”将包含已复制到“缓冲区”的脏范围数量。 调用方可以假定,在进行调用之前被设为脏范围的任何范围要么包含在 buffer 中,要么其起始偏移量严格大于 buffer 中的最后一个范围。因此,调用方可以推进 offset 并执行另一个查询来发现更多脏范围,直到 availability 为零。

想要查询 VMO 中的所有脏范围的用户代码示例可能如下所示:


  zx_vmo_dirty_range_t ranges[5];
  size_t actual = 0;
  size_t avail = 0;
  uint64_t start = 0;
  uint64_t len = vmo_size;

  while (len > 0) {
    zx_status_t st = zx_pager_query_dirty_ranges(pager, vmo, start, len,
                                                 &ranges[0],
                                                 5 * sizeof(zx_vmo_dirty_range_t),
                                                 &actual, &avail);
    // Process the |ranges| returned as needed.
    ProcessDirtyRanges(&ranges[0], actual);

    // We've read all the dirty ranges that existed before the query.
    if (actual == avail) {
      break;
    }
    // We used up the entire |ranges| buffer, but there are more dirty ranges to be read.
    // Advance start beyond the last dirty range found.
    uint64_t new_start = ranges[4].offset + ranges[4].length;
    len -= (new_start - start);
    start = new_start;
  }

权限

pager 必须为 ZX_OBJ_TYPE_PAGER 类型且具有 ZX_RIGHT_MANAGE_VMO

pager_vmo 的类型必须为 ZX_OBJ_TYPE_VMO 且设为 ZX_RIGHT_READ

返回值

zx_pager_query_dirty_ranges() 会在成功时返回 ZX_OK。如果失败,则返回负的错误值。

错误

ZX_ERR_BAD_HANDLE pagerpager_vmo 不是有效的句柄。

ZX_ERR_WRONG_TYPE pager 不是分页器句柄,或 pager_vmo 不是 VMO 句柄。

ZX_ERR_ACCESS_DENIED pager 没有 ZX_RIGHT_MANAGE_VMOpager_vmo 没有 ZX_RIGHT_READ

ZX_ERR_INVALID_ARGS pager_vmo 不是通过 pager 创建的 VMO,或者 buffer 是无效的指针。

ZX_ERR_OUT_OF_RANGEpager_vmo 中指定的范围无效。

另请参阅