zx_pager_op_range

摘要

在 Pager 擁有的 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);

說明

執行由 op 指定,位於範圍 [offsetoffset + length] 的分頁器作業。pager_vmo 必須先前已由 zx_pager_create_vmo() 透過 pager 建立。offsetlength 必須對齊頁面。如果指定的 op 支援參數,data 即為選用參數。

可執行的作業,也就是 op 可採用的值:

ZX_PAGER_OP_DIRTY - 使用者空間頁面器想要將 [offsetoffset + length] 範圍的頁面從乾淨到骯髒。這麼做將解除封鎖所有等待於 ZX_PAGER_VMO_DIRTY 頁面要求指定範圍的寫入。

ZX_PAGER_OP_FAIL - 使用者空間呼叫器無法以 ZX_PAGER_VMO_READZX_PAGER_VMO_DIRTY 指令執行 [offsetoffset + length] 範圍中 pager_vmo 的網頁要求。data 包含發生的錯誤 (zx_status_t 錯誤代碼擴充為 uint64_t 值),允許的值包括 ZX_ERR_IOZX_ERR_IO_DATA_INTEGRITYZX_ERR_BAD_STATEZX_ERR_NO_SPACEZX_ERR_BUFFER_TOO_SMALL

如此一來,可能等待該範圍內的網頁請求的執行緒就會解除封鎖。如果已封鎖的執行緒透過 zx_vmo_read() / zx_vmo_write() 或包含 ZX_VMO_OP_COMMITzx_vmo_op_range() 要求頁面,呼叫將會失敗,並傳回錯誤狀態 (資料)。如果封鎖的執行緒透過 VMAR 對應要求頁面,該執行緒就會發生嚴重頁面錯誤例外狀況。

ZX_PAGER_OP_WRITEBACK_BEGIN - 使用者空間頁面器想要開始寫入位於 [offsetoffset + length] 範圍的頁面。這表示在完成寫回後 (以 ZX_PAGER_OP_WRITEBACK_END 標記) 的意圖,會在指定範圍中清除任何骯髒頁面。請參閱下列程式碼範例,瞭解建議用法。

「data」可視需要設為 ZX_VMO_DIRTY_RANGE_IS_ZERO,表示呼叫端想寫回指定範圍為零。此用途適用於呼叫端處理 zx_pager_query_dirty_ranges() 傳回的範圍,並將 options 設為 ZX_VMO_DIRTY_RANGE_IS_ZERO。這麼做可確保在查詢之後建立、但回寫啟動前建立的任何非零內容不會遺失,因為這樣會誤假設其為零,並標示為清理 (因此可收回)。

ZX_PAGER_OP_WRITEBACK_END:使用者空間分頁器在 [offsetoffset + length] 範圍寫入返回頁面。這表示如果指定範圍中有先前使用 ZX_PAGER_OP_WRITEBACK_BEGIN 發出訊號的骯髒頁面,就會標示為乾淨。請參閱以下程式碼範例,瞭解建議的使用方式。

核心可自由剔除任何標示為「乾淨」的頁面或零範圍,之後使用者空間分頁器就會視需要再次提供這些頁面。此外,這也表示呼叫器應小心不要在檔期內提供任何過時的內容,且只應提供剛寫入的新內容。

找出並清理任何骯髒頁面的程式碼範例 (模數錯誤處理) 可能如下所示。

  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 pagerpager_vmo 不是有效的控制代碼。

ZX_ERR_WRONG_TYPE pager 不是呼叫器控點,或者 pager_vmo 不是 VMO 控制代碼。

ZX_ERR_ACCESS_DENIED pager 沒有 ZX_RIGHT_MANAGE_VMOpager_vmo 沒有 ZX_RIGHT_WRITE

符合以下任一條件的 ZX_ERR_INVALID_ARGS: - pager_vmo 並非透過 pager 建立的 VMO。 - offsetlength 未對齊頁面。 - opZX_PAGER_OP_FAIL,且 data 不是 ZX_ERR_IOZX_ERR_IO_DATA_INTEGRITYZX_ERR_BAD_STATE 之一。 - 運算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 opZX_PAGER_OP_DIRTY,且以 offsetlength 表示的範圍包含未提供的區域,或之前已填入但尚未被核心撤銷的區域。

ZX_ERR_BAD_STATE opZX_PAGER_OP_DIRTYZX_PAGER_OP_FAIL,且 pager_vmo 已從 pager 卸離。

另請參閱