Запрос и предоставление оплоков
Когда сетевой перенаправитель обращается к файлам на удаленных серверах, он запрашивает блокировку с удаленного сервера. Клиентские приложения напрямую запрашивают блокировку, только если блокировка предназначена для файла на локальном сервере.
Запрос блокировок осуществляется через FSCTL. Следующие списки FSCTL используются для различных типов блокировки, которые могут выдаваться как приложениями пользовательского режима, так и драйверами режима ядра:
- Чтобы запросить устаревшие блокировки, выполните приведенные далее действия.
- Чтобы запросить блокировку Windows 7, выполните приведенные далее действия.
Чтобы запросить блокировку Windows 7 в пользовательском режиме, вызовите DeviceIoControl:
- Присвойте dwIoControlCodeзначение FSCTL_REQUEST_OPLOCK.
- Укажите флаг REQUEST_OPLOCK_INPUT_FLAG_REQUEST в элементе Flags структуры REQUEST_OPLOCK_INPUT_BUFFER , который передается в качестве параметра lpInBuffer .
Аналогичным образом, чтобы запросить блокировки Windows 7 в режиме ядра:
- Минифильтр, отличный от файловой системы, может вызывать ZwFsControlFile.
- Минифильтр файловой системы должен использовать FltAllocateCallbackData и FltPerformAsynchronousIo.
Чтобы указать, какой из четырех блокировок Windows 7 требуется, установите один или несколько следующих флагов в элементе RequestedOplockLevel структуры REQUEST_OPLOCK_INPUT_BUFFER :
- OPLOCK_LEVEL_CACHE_READ
- OPLOCK_LEVEL_CACHE_HANDLE
- OPLOCK_LEVEL_CACHE_WRITE
Дополнительные сведения см. в разделе FSCTL_REQUEST_OPLOCK.
Если запрошенную блокировку можно предоставить, файловая система возвращает STATUS_PENDING. По этой причине операции блокировки никогда не предоставляются для синхронных операций ввода-вывода. FSCTL IRP не завершается до тех пор, пока не будет нарушена блокировка.
Если не удается предоставить блокировку, файловая система возвращает соответствующий код ошибки. Чаще всего возвращаются коды ошибок STATUS_OPLOCK_NOT_GRANTED и STATUS_INVALID_PARAMETER (а также их эквивалентные аналоги в пользовательском режиме).
Блокировка фильтра позволяет приложению "вернуться", когда другие приложения или клиенты пытаются получить доступ к тому же потоку. Этот механизм позволяет приложению получить доступ к потоку, не вызывая при попытке открытия потока другие методы доступа к потоку. Чтобы избежать нарушений общего доступа, для запроса блокировки фильтра (FSCTL_REQUEST_FILTER_OPLOCK) следует использовать специальную трехэтапную процедуру:
Откройте файл с требуемым доступом FILE_READ_ATTRIBUTES и режимом общего доступа FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE.
Запрос блокировки фильтра на дескрипторе из шага 1.
Откройте файл еще раз для чтения.
Дескриптор, открытый на шаге 1, не приведет к тому, что другие приложения будут получать нарушения общего доступа, так как он открыт только для доступа к атрибутам (FILE_READ_ATTRIBUTES), а не для доступа к данным (FILE_READ_DATA). Этот дескриптор подходит для запроса блокировки фильтра, но не для выполнения фактических операций ввода-вывода в потоке данных. Дескриптор, открытый на шаге 3, позволяет владельцу блокировки выполнять операции ввода-вывода в потоке; блокировка, предоставленная на шаге 2, позволяет владельцу блокировки "выйти из пути", не вызывая нарушения общего доступа к другому приложению, которое пытается получить доступ к потоку.
Файловая система NTFS обеспечивает оптимизацию для этой процедуры с помощью флага параметра FILE_RESERVE_OPFILTER создания. Если этот флаг указан на шаге 1 предыдущей процедуры, это позволяет файловой системе завершить запрос на создание с STATUS_OPLOCK_NOT_GRANTED если файловая система может определить, что шаг 2 завершится ошибкой. Если шаг 1 завершается успешно, нет никакой гарантии, что шаг 2 будет выполнен успешно, даже если для запроса на создание было указано FILE_RESERVE_OPFILTER.
В следующей таблице указаны необходимые условия, необходимые для предоставления блокировки.
Тип запроса | Условия |
---|---|
уровне 1 Фильтр Пакетная служба |
Предоставляется, только если выполняются все следующие условия:
Если текущее состояние блокировки операции:
|
Уровень 2 |
Предоставляется, только если выполняются все следующие условия:
Если текущее состояние блокировки операции:
|
Read |
Предоставляется, только если выполняются все следующие условия:
Имейте в виду, что, если текущее состояние блокировки:
|
Read-Handle |
Предоставляется, только если выполняются все следующие условия:
Если текущее состояние oplock равно:
|
Read-Write |
Предоставляется, только если выполняются все следующие условия:
Если текущее состояние oplock равно:
|
Дескриптор чтения и записи |
Предоставляется только в том случае, если выполняются все перечисленные ниже условия.
Если текущее состояние oplock равно:
|
Примечание
Операции чтения и операции уровня 2 могут сосуществовать в одном потоке, а операции чтения и Read-Handle могут сосуществовать, но уровни 2 и Read-Handle не могут сосуществовать.
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по