共用方式為


要求和授與 oplock

當網路重新導向器存取遠端伺服器上的檔案時,它會從遠端伺服器要求 oplock。 只有在鎖定適用於本機伺服器上的檔案時,用戶端應用程式才會直接要求oplock。

Oplock 是透過 FSCTL 要求。 下列 FSCTL 用於不同的 oplock 類型,使用者模式應用程式和核心模式驅動程式都可以發出:

若要在使用者模式中要求 Windows 7 oplock,請呼叫 DeviceIoControl

以類似的方式要求核心模式中的 Windows 7 oplock:

若要指定需要四個 Windows 7 oplock 中的哪一個,請在 REQUEST_OPLOCK_INPUT_BUFFER 結構的 RequestedOplockLevel 成員中設定下列一或多個旗標:

  • OPLOCK_LEVEL_CACHE_READ
  • OPLOCK_LEVEL_CACHE_HANDLE
  • OPLOCK_LEVEL_CACHE_WRITE

如需詳細資訊,請參閱 FSCTL_REQUEST_OPLOCK

如果可以授與要求的 oplock,文件系統會傳回STATUS_PENDING。 基於這個理由,永遠不會授與同步 I/O 的 oplock。 FSCTL IRP 在作業鎖定中斷之前不會完成。

如果無法授與 oplock,則會傳回文件系統傳回適當的錯誤碼。 最常見的傳回錯誤碼是STATUS_OPLOCK_NOT_GRANTED和STATUS_INVALID_PARAMETER (,以及其對等的使用者模式類比) 。

當其他應用程式/用戶端嘗試存取相同的數據流時,Filter oplock 可讓應用程式「回復」。 此機制可讓應用程式存取數據流,而不會造成數據流的其他存取子在嘗試開啟數據流時收到共享違規。 若要避免共用違規,應該使用特殊的三步驟程式來要求篩選 oplock (FSCTL_REQUEST_FILTER_OPLOCK) :

  1. 開啟具有必要存取權的檔案,FILE_READ_ATTRIBUTES和FILE_SHARE_READ的共用模式 |FILE_SHARE_WRITE |FILE_SHARE_DELETE。

  2. 從步驟 1 要求句柄上的篩選作業鎖定。

  3. 再次開啟檔案以供讀取存取。

在步驟 1 中開啟的句柄不會造成其他應用程式收到共用違規,因為它只會針對屬性存取 (FILE_READ_ATTRIBUTES) 開啟,而不是數據存取 (FILE_READ_DATA) 。 此句柄適用於要求篩選作業鎖定,但不適用於在數據流上執行實際 I/O。 在步驟 3 中開啟的句柄可讓 oplock 的持有者在數據流上執行 I/O;在步驟 2 中授與的 oplock 可讓 oplock 的持有者「離開」,而不會造成嘗試存取數據流的另一個應用程式發生共享違規。

NTFS 檔案系統透過建立選項旗標FILE_RESERVE_OPFILTER提供此程序的優化。 如果在上一個程式的步驟 1 中指定這個旗標,它可讓文件系統在文件系統判斷步驟 2 將會失敗時,讓建立要求失敗,並STATUS_OPLOCK_NOT_GRANTED。 如果步驟 1 成功,則即使為建立要求指定了FILE_RESERVE_OPFILTER,步驟 2 也不會保證會成功。

下表識別授與 oplock 所需的必要條件。

要求類型 條件

層級 1

篩選

Batch

只有在下列所有條件都成立時,才會授與:

  • 要求適用於檔案的指定數據流。
    • 如果目錄,則會傳回STATUS_INVALID_PARAMETER。
  • 數據流會開啟以進行異步存取。
    • 如果為同步存取開啟,STATUS_OPLOCK_NOT_GRANTED會傳回 (作業鎖定不會授與同步 I/O 要求) 。
  • 檔案的任何數據流上沒有任何 TxF 交易。
    • 否則會傳回STATUS_OPLOCK_NOT_GRANTED。
  • 數據流上沒有任何其他開啟 (,即使相同的線程) 也一樣。
    • 否則會傳回STATUS_OPLOCK_NOT_GRANTED。

如果目前的 oplock 狀態為:

  • 沒有 oplock:會授與要求。

  • 層級 2:原始層級 2 要求會隨著FILE_OPLOCK_BROKEN_TO_NONE而中斷。 接著會授與要求的獨佔 oplock。

  • 層級 1、Batch、Filter、Read、Read-Handle、Read-Write 或 Read-Write-Handle:傳回STATUS_OPLOCK_NOT_GRANTED。

層級 2

只有在下列所有條件都成立時,才會授與:

  • 要求適用於檔案的指定數據流。
    • 如果目錄,則會傳回STATUS_INVALID_PARAMETER。
  • 數據流會開啟以進行異步存取。
    • 如果為同步存取開啟,則會傳回STATUS_OPLOCK_NOT_GRANTED。
  • 檔案上沒有 TxF 交易。
    • 否則會傳回STATUS_OPLOCK_NOT_GRANTED。
  • 數據流上沒有目前的位元組範圍鎖定。
    • 否則會傳回STATUS_OPLOCK_NOT_GRANTED。
    • 在 Windows 7 之前,操作系統會確認自上次開啟數據流以來數據流上是否有位元組範圍鎖定存在,如果開啟,則要求會失敗。

如果目前的 oplock 狀態為:

  • 沒有 oplock:會授與要求。

  • 層級 2 和/或讀取:會授與要求。 您可以同時在相同數據流上授與多個層級 2/讀取作業鎖定。 多個層級 2 (,但無法讀取) oplock 甚至存在於相同的句柄上。
    • 如果在已經授與讀取 oplock 的句柄上要求讀取 oplock,則第一個讀取 oplock 的 IRP 會在授與第二個讀取 oplock 之前完成STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE。
  • 層級 1、批次、篩選、讀取句柄、讀寫、讀寫句柄:傳回STATUS_OPLOCK_NOT_GRANTED。

讀取

只有在下列所有條件都成立時,才會授與:

  • 要求適用於檔案的指定數據流。
  • 數據流會開啟以進行異步存取。
    • 如果為同步存取開啟,則會傳回STATUS_OPLOCK_NOT_GRANTED。
  • 檔案上沒有 TxF 交易。
    • 否則會傳回STATUS_OPLOCK_NOT_GRANTED。
  • 數據流上沒有目前的位元組範圍鎖定。
    • 否則會傳回STATUS_OPLOCK_NOT_GRANTED。

請注意,如果目前的 oplock 狀態為:

  • 沒有 oplock:會授與要求。

  • 層級 2 和/或讀取:會授與要求。 您可以同時在相同數據流上授與多個層級 2/讀取作業鎖定。
    • 此外,如果現有的 oplock 與新要求具有相同的 oplock 密鑰,則其 IRP 已完成STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE。
  • Read-Handle 和現有的 oplock 具有與新要求不同的 oplock 密鑰:會授與要求。 多個讀取和 Read-Handle oplock 可以共存於相同的數據流上, (請參閱下表) 附注。
    • 否則會傳回 (oplock 機碼) STATUS_OPLOCK_NOT_GRANTED 相同。
  • 層級 1、Batch、篩選、讀取寫入、讀取寫入句柄:傳回STATUS_OPLOCK_NOT_GRANTED。

Read-Handle

只有在下列所有條件都成立時,才會授與:

  • 要求適用於檔案的指定數據流。
  • 數據流會開啟以進行異步存取。
    • 如果為同步存取開啟,則會傳回STATUS_OPLOCK_NOT_GRANTED。
  • 檔案上沒有 TxF 交易。
    • 否則會傳回STATUS_OPLOCK_NOT_GRANTED。
  • 數據流上沒有目前的位元組範圍鎖定。
    • 否則會傳回STATUS_OPLOCK_NOT_GRANTED。

如果目前的 oplock 狀態為:

  • 沒有 oplock:會授與要求。

  • 讀取:會授與要求。
    • 如果現有的 Read oplock 與新要求具有相同的 oplock 機碼,其 IRP 會以STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE完成。 結果是將 oplock 從讀取升級為讀取句柄。
    • 任何沒有與新要求相同的 Oplock 金鑰的現有讀取 oplock 都會保持不變。
  • 層級 2、層級 1、批次、篩選、讀取寫入、讀寫句柄:傳回STATUS_OPLOCK_NOT_GRANTED。

Read-Write

只有在下列所有條件都成立時,才會授與:

  • 要求適用於檔案的指定數據流。
    • 如果目錄,則會傳回STATUS_INVALID_PARAMETER。
  • 數據流會開啟以進行異步存取。
    • 如果為同步存取開啟,則會傳回STATUS_OPLOCK_NOT_GRANTED。
  • 檔案上沒有 TxF 交易。
    • 否則會傳回STATUS_OPLOCK_NOT_GRANTED。
  • 如果數據流上有其他開啟 (,即使相同的線程) ,它們也必須有相同的 oplock 密鑰。
    • 否則會傳回STATUS_OPLOCK_NOT_GRANTED。

如果目前的 oplock 狀態為:

  • 沒有 oplock:會授與要求。

  • 讀取或 Read-Write,而現有的 oplock 索引鍵與要求相同:現有 oplock 的 IRP 已完成STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE,則會授與要求。
    • 否則會傳回STATUS_OPLOCK_NOT_GRANTED。
  • 層級 2、層級 1、批次、篩選、讀取句柄、讀取寫入句柄:傳回STATUS_OPLOCK_NOT_GRANTED。

可擦寫的句柄

只有在下列所有專案都成立時,才會授與:

  • 要求適用於檔案的指定數據流。
    • 如果目錄,則會傳回STATUS_INVALID_PARAMETER。
  • 數據流會開啟以進行異步存取。
    • 如果為同步存取開啟,則會傳回STATUS_OPLOCK_NOT_GRANTED。
  • 檔案上沒有 TxF 交易。
    • 否則會傳回STATUS_OPLOCK_NOT_GRANTED。
  • 如果數據流上有其他開啟的要求 (即使由相同的線程) 也必須有相同的 oplock 金鑰。
    • 否則會傳回STATUS_OPLOCK_NOT_GRANTED。

如果目前的 oplock 狀態為:

  • 沒有 oplock:會授與要求。

  • 讀取、讀取句柄、讀寫或讀寫句柄,而現有的 oplock 索引鍵與要求相同:現有 oplock 的 IRP 已完成STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE,則會授與要求。
    • 否則會傳回STATUS_OPLOCK_NOT_GRANTED。
  • 層級 2、層級 1、批次、篩選:傳回STATUS_OPLOCK_NOT_GRANTED。

注意

讀取和層級 2 oplock 可以共存於相同的數據流上,而讀取和 Read-Handle oplock 可以共存,但層級 2 和 Read-Handle oplock 無法共存。