中斷 Oplocks
oplock要求並授與之後,該 oplock 的擁有者會根據所要求的 oplock 類型存取數據流。 如果收到的作業與目前的 oplock 不相容,系統就會中斷 oplock。
授與 oplock 時,系統會延遲處理要求的 IRP。 當 oplock 中斷時,掛起的 oplock 要求 IRP 會以 STATUS_SUCCESS 完成。 對於層級 1、Batch 和 Filter oplock,IRP 的 IoStatus.Information 成員會設定為指出 oplock 中斷的層級。 這些層級包括:
FILE_OPLOCK_BROKEN_TO_NONE:oplock 已中斷,目前資料流上沒有當前的 oplock。 據說 oplock 被解除到無效狀態。
FILE_OPLOCK_BROKEN_TO_LEVEL_2:當前的文件鎖(層級 1 或批次)已轉換為層級 2 的文件鎖。 篩選鎖從不會中斷至層級 2,它們一律會中斷為 None。
針對讀取句柄、可擦寫的 、 和 Read-Write-Handle oplocks,oplock 中斷的層級會描述為
當系統的 oplock 套件中斷層級 1、Batch、Filter、Read-Write、Read-Write-Handle,或是在某些情況下,Read-Handle oplock:
- oplock 套件包會完成掛起的 oplock 要求的 IRP。
- 造成 oplock 中斷的作業本身會被掛起。
在以下情況下,I/O 管理員會使作業阻塞,而不是傳回 STATUS_PENDING:
- 在同步控制器上發出。
- 這是IRP_MJ_CREATE,一律為同步。
I/O 管理員會等候 oplock 擁有者的通知,告知 oplock 套件他們已完成處理,且確保等候的操作能夠安全繼續。 此延遲可讓 oplock 擁有者將資料流恢復至一致的狀態,再繼續執行目前的操作。 系統會永遠等候接收通知,因為沒有逾時。 因此,Oplock 的擁有者有責任及時確認鎖中斷狀況。 延遲的操作的 IRP 會設定為可取消的狀態。 如果執行等候的應用程式或驅動程式終止,oplock 套件會立即完成具有 STATUS_CANCELLED 的 IRP。
IRP_MJ_CREATE IRP 可以指定FILE_COMPLETE_IF_OPLOCKED建立選項,以避免在oplock中斷通知中遭到封鎖。 此選項會告知 oplock 套件在收到 oplock 中斷通知之前,不要封鎖建立 IRP。 相反地,允許創建繼續進行。 如果成功建立會導致 oplock 中斷,則會傳回 STATUS_OPLOCK_BREAK_IN_PROGRESS,而不是 STATUS_SUCCESS。 FILE_COMPLETE_IF_OPLOCKED旗標通常用於避免死結。 例如,如果用戶端在資料流上擁有 oplock,而相同的用戶端稍後打開相同的資料流,用戶端將會阻塞並等待自己確認 oplock 解除。 在此案例中,使用 FILE_COMPLETE_IF_OPLOCKED 旗標可避免死結。
NTFS 文件系統會在檢查共享違規之前,啟動批次和篩選機制 oplock 的中斷。 因此,建立指定的FILE_COMPLETE_IF_OPLOCKED可能會因為STATUS_SHARING_VIOLATION而失敗,但仍會導致 Batch 或 Filter oplock 中斷。 在此情況下,IO_STATUS_BLOCK 結構的信息成員會設定為 FILE_OPBATCH_BREAK_UNDERWAY,以允許呼叫端偵測此案例。
針對 Read-Handle 和Write-Handle 讀取 oplock,當 NTFS 檢查並偵測到共用違規後,即會啟動 oplock 中斷程序。 此序列可讓 oplock 持有者有機會關閉其控點並避免影響,從而避免共用違規傳回給使用者。 如果 oplock 快取的句柄與新建立不衝突,它也會避免無條件中斷 oplock。
當層級 2、讀取和在某些特定情況下 Read-Handle oplock 中斷時,系統不會等待確認。 原因是在允許其他用戶端存取檔案之前,數據流上不應該有任何需要還原至檔案的快取狀態。
某些文件系統作業會檢查目前的 oplock 狀態,以判斷 oplock 是否需要中斷。 以下針對特定操作的文章描述什麼會觸發 oplock 中斷、決定中斷的層級,以及是否需要確認該中斷:
- IRP_MJ_CREATE
- IRP_MJ_READ
- IRP_MJ_WRITE
- IRP_MJ_CLEANUP
- IRP_MJ_LOCK_CONTROL
- IRP_MJ_SET_INFORMATION
- IRP_MJ_FILE_SYSTEM_CONTROL
如果REQUEST_OPLOCK_OUTPUT_FLAG_ACK_REQUIRED旗標是在傳遞為 deviceIoControl
列出的每項作業相關的文章描述中斷 Read-Handle oplock 時,會導致該作業擱置的詳細資訊。 例如,IRP_MJ_CREATE 文章包含相關聯的 Read-Handle 詳細數據。