摘要
在 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 指定,位於範圍 [offset、offset +
length] 的分頁器作業。pager_vmo 必須先前已由 zx_pager_create_vmo()
透過 pager 建立。offset 和 length 必須對齊頁面。如果指定的 op 支援參數,data 即為選用參數。
可執行的作業,也就是 op 可採用的值:
ZX_PAGER_OP_DIRTY
- 使用者空間頁面器想要將 [offset、offset + length] 範圍的頁面從乾淨到骯髒。這麼做將解除封鎖所有等待於 ZX_PAGER_VMO_DIRTY
頁面要求指定範圍的寫入。
ZX_PAGER_OP_FAIL
- 使用者空間呼叫器無法以 ZX_PAGER_VMO_READ
或 ZX_PAGER_VMO_DIRTY
指令執行 [offset、offset + length] 範圍中 pager_vmo 的網頁要求。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_COMMIT
的 zx_vmo_op_range()
要求頁面,呼叫將會失敗,並傳回錯誤狀態 (資料)。如果封鎖的執行緒透過 VMAR 對應要求頁面,該執行緒就會發生嚴重頁面錯誤例外狀況。
ZX_PAGER_OP_WRITEBACK_BEGIN
- 使用者空間頁面器想要開始寫入位於 [offset、offset + 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
:使用者空間分頁器在 [offset、offset + 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
pager 或 pager_vmo 不是有效的控制代碼。
ZX_ERR_WRONG_TYPE
pager 不是呼叫器控點,或者 pager_vmo 不是 VMO 控制代碼。
ZX_ERR_ACCESS_DENIED
pager 沒有 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
之一。
- 運算為 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 已從 pager 卸離。