要求和授與檔案鎖定機制(oplocks)
當網路重導程式存取遠端伺服器上的檔案時,它會向遠端伺服器請求 oplock。 只有當鎖定適用於本地伺服器上的檔案時,用戶端應用程式才會直接請求 oplock。
Oplocks 是透過 FSCTLs要求的。 下列 FSCTL 用於的不同
- 若要要求舊版 oplocks:
- 若要請求 Windows 7 oplocks:
若要在使用者模式中要求 Windows 7 oplock,請呼叫 DeviceIoControl:
- 將 dwIoControlCode 設定為 FSCTL_REQUEST_OPLOCK。
- 在 FlagsREQUEST_OPLOCK_INPUT_BUFFER 結構的成員中指定REQUEST_OPLOCK_INPUT_FLAG_REQUEST旗標,這個成員會傳遞為 lpInBuffer 參數。
以類似的方式,在核心模式中要求 Windows 7 機會鎖:
- 非檔案系統迷你篩選程式可以呼叫 ZwFsControlFile。
- 檔案系統小型篩選器必須使用 FltAllocateCallbackData 以及 FltPerformAsynchronousIo。
若要指定四個 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):
以需要的存取模式 FILE_READ_ATTRIBUTES 和 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE 的共用模式開啟檔案。 在此步驟中開啟的句柄不會造成其他應用程式收到共用違規,因為此句柄只會針對屬性存取 (FILE_READ_ATTRIBUTES) 而非數據存取 (FILE_READ_DATA) 開啟。 此句柄適用於要求篩選操作鎖定,但不適合在數據流上執行實際的 I/O。
從步驟 1 要求句柄上的篩選作業鎖定。 此步驟中授與的oplock可讓oplock持有者「走出去」,而不會造成嘗試存取數據流的另一個應用程式發生共享違規。
再次開啟檔案以進行讀取存取。 在此步驟中開啟的句柄可讓 oplock 持有人在數據流上執行 I/O。
NTFS 檔案系統透過 FILE_RESERVE_OPFILTER 建立選項旗標,為這個過程提供優化。 如果在上一個程序的步驟 1 中指定此標誌,並且文件系統能夠判定步驟 2 將失敗,則文件系統允許建立請求失敗,並返回 STATUS_OPLOCK_NOT_GRANTED。 如果步驟 1 成功,則不保證步驟 2 會成功,即使已為建立要求指定FILE_RESERVE_OPFILTER也一樣。
下表列出授予 oplock 所需的必要條件。
要求類型 | 條件 |
---|---|
層級 1 過濾器 批 |
只有在下列所有條件都成立時才授與:
如果目前的 oplock 狀態為:
|
層級 2 |
只有在下列所有條件都成立時才授與:
如果目前的 oplock 狀態為:
|
讀 |
只有在下列所有條件都成立時才授與:
如果目前的「oplock」狀態為:
|
Read-Handle |
只有在下列所有條件都成立時才授與:
如果目前的 oplock 狀態為:
|
Read-Write |
只有在下列所有條件都成立時才授與:
如果目前的 oplock 狀態為:
|
讀取:Write-Handle |
只有在下列所有條件都成立時才授與:
如果目前的 oplock 狀態為:
|
注意
讀取與層級 2 oplock 可以共存於相同的數據流,而讀取與 Read-Handle oplock 可以共存,但層級 2 和 Read-Handle oplock 無法共存。