共用方式為


要求和授與檔案鎖定機制(oplocks)

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

Oplocks 是透過 FSCTLs要求的。 下列 FSCTL 用於的不同 oplock 類型,使用者模式應用程式和內核模式驅動程式都可能會發出此問題。

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

以類似的方式,在核心模式中要求 Windows 7 機會鎖:

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

  • OPLOCK_LEVEL_快取讀取
  • OPLOCK_LEVEL_CACHE_HANDLE
  • OPLOCK_LEVEL_CACHE_WRITE

如需詳細資訊,請參閱 FSCTL_REQUEST_OPLOCK

如果可以授與要求的 oplock,則文件系統會傳回STATUS_PENDING。 因此,同步 I/O 永遠不會被提供鎖定機制。 FSCTL IRP 直到 oplock 中斷後才會完成。

如果無法授與 oplock,檔案系統會傳回適當的錯誤碼。 最常見的傳回錯誤碼是 STATUS_OPLOCK_NOT_GRANTED 和 STATUS_INVALID_PARAMETER(及其對應的使用者模式等效項)。

當其他應用程式/用戶端嘗試存取相同的數據流時,Filter oplock 可讓應用程式「回復」。 此機制可讓應用程式存取串流,而不會造成其他存取者在嘗試開啟串流時發生共用衝突。 為了避免共用違規,應該遵循以下三個步驟程序來請求篩選作業鎖定(FSCTL_REQUEST_FILTER_OPLOCK):

  1. 以需要的存取模式 FILE_READ_ATTRIBUTES 和 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE 的共用模式開啟檔案。 在此步驟中開啟的句柄不會造成其他應用程式收到共用違規,因為此句柄只會針對屬性存取 (FILE_READ_ATTRIBUTES) 而非數據存取 (FILE_READ_DATA) 開啟。 此句柄適用於要求篩選操作鎖定,但不適合在數據流上執行實際的 I/O。

  2. 從步驟 1 要求句柄上的篩選作業鎖定。 此步驟中授與的oplock可讓oplock持有者「走出去」,而不會造成嘗試存取數據流的另一個應用程式發生共享違規。

  3. 再次開啟檔案以進行讀取存取。 在此步驟中開啟的句柄可讓 oplock 持有人在數據流上執行 I/O。

NTFS 檔案系統透過 FILE_RESERVE_OPFILTER 建立選項旗標,為這個過程提供優化。 如果在上一個程序的步驟 1 中指定此標誌,並且文件系統能夠判定步驟 2 將失敗,則文件系統允許建立請求失敗,並返回 STATUS_OPLOCK_NOT_GRANTED。 如果步驟 1 成功,則不保證步驟 2 會成功,即使已為建立要求指定FILE_RESERVE_OPFILTER也一樣。

下表列出授予 oplock 所需的必要條件。

要求類型 條件

層級 1

過濾器

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

  • 要求提供檔案的特定資料流。
    • 如果檢測到是目錄,則會傳回STATUS_INVALID_PARAMETER。
  • 資料流已開啟以便進行非同步存取。
    • 如果以同步方式開啟存取,則會回傳 STATUS_OPLOCK_NOT_GRANTED(因為同步 I/O 請求不會授予 oplocks)。
  • 任何檔案數據流上沒有任何 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。
  • 資料串流已開啟以進行異步存取。
    • 如果針對 SYNCHRONOUS 存取開啟,則會傳回 STATUS_OPLOCK_NOT_GRANTED。
  • 檔案上沒有 TxF 交易。
    • 否則會傳回STATUS_OPLOCK_NOT_GRANTED。
  • 當前數據流沒有位元組範圍鎖定。
    • 否則,會傳回 STATUS_OPLOCK_NOT_GRANTED。
    • 在 Windows 7 之前,操作系統會驗證自上次開啟串流以來是否曾存在位元組範圍鎖定,如果是這樣,則要求會失敗。

如果目前的 oplock 狀態為:

  • 沒有 oplock:需求已被批准。

  • 層級 2 和/或讀取權限:請求已被批准。 您可以同時在同一資料流中授予多個第二級/讀取型 oplock。 多個二級(但不包括讀取的)oplocks 甚至可以存在於同一個文件上。
    • 如果在已授予 Read oplock 的句柄上再次請求 Read oplock,則第一個 Read oplock 的 IRP 將以 STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE 完成,然後再授予第二個 Read oplock。
  • 當層級為 1、Batch、Filter、Read-Handle、Read-Write 和 Read-Write-Handle 時,系統會傳回 STATUS_OPLOCK_NOT_GRANTED。

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

  • 這項請求針對特定檔案流。
  • 資料流被打開用來做異步存取。
    • 如果針對同步存取開啟,系統會傳回 STATUS_OPLOCK_NOT_GRANTED 的狀態。
  • 檔案上沒有 TxF 交易。
    • 否則會返回STATUS_OPLOCK_NOT_GRANTED。
  • 現在資料流上沒有任何位元組範圍鎖定。
    • 否則會傳回STATUS_OPLOCK_NOT_GRANTED。

如果目前的「oplock」狀態為:

  • 沒有 oplock:請求已被授予。

  • 層級 2 和/或讀取:已授與要求。 您可以在相同數據流上同時授予多個層級 2/讀取 oplock。
    • 此外,如果現有的 oplock 與新請求具有相同的 oplock 鍵,其 IRP 會以 STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE 完成。
  • Read-Handle 和現有的 oplock 具有與新要求不同的 oplock 密鑰。請求已被允許。 多個讀取和 Read-Handle oplock 可以共存於相同的數據流上(請參閱下表後面的附注)。
    • 否則,如果 oplock 鍵相同,則傳回 STATUS_OPLOCK_NOT_GRANTED。
  • 層級 1、Batch、Filter、Read-Write、Read-Write-Handle:會傳回STATUS_OPLOCK_NOT_GRANTED。

Read-Handle

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

  • 請求是針對檔案中特定的數據流。
  • 數據流會開啟以進行異步存取。
    • 如果開啟以進行 SYNCHRONOUS 存取,則會傳回 STATUS_OPLOCK_NOT_GRANTED。
  • 檔案上沒有 TxF 交易。
    • 否則會傳回狀態代碼 STATUS_OPLOCK_NOT_GRANTED。
  • 數據流上沒有當前的位元組範圍鎖定。
    • 否則會傳回STATUS_OPLOCK_NOT_GRANTED。

如果目前的 oplock 狀態為:

  • 無機會鎖定:請求已被批准。

  • 通知:請求已被批准。
    • 如果現有的 Read oplock 與新要求具有相同的 oplock 機碼,其 IRP 會以STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE完成。 結果是 oplock 從 Read 升級為 Read-Handle。
    • 任何現有的 Read oplock,如果其 oplock 機碼與新要求不相同,則不會改變。
  • 層級 2、層級 1、Batch、Filter、Read-Write、Read-Write-Handle:將傳回狀態 STATUS_OPLOCK_NOT_GRANTED。

Read-Write

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

  • 要求適用於檔案的指定數據流。
    • 如果是目錄,則會傳回 STATUS_INVALID_PARAMETER。
  • 資料流已開啟以進行異步存取。
    • 如果針對 SYNCHRONOUS 存取開啟,則會傳回 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。

讀取:Write-Handle

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

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

如果目前的 oplock 狀態為:

  • 沒有 oplock:要求已被授予。

  • 讀取、讀取-操作、讀寫或讀取-Write-Handle,且現有的 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 無法共存。