Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Quando o redirecionador de rede acessa arquivos em servidores remotos, ele solicita o oplock do servidor remoto. Os aplicativos cliente solicitam oplocks diretamente somente quando o bloqueio é destinado a um arquivo no servidor local.
Oplocks são solicitados através FSCTLs. As FSCTLs a seguir são usados para os diferentes tipos de oplock, que tanto as aplicações de modo utilizador quanto os drivers de modo núcleo podem emitir.
- Para solicitar os oplocks do Windows 7:
- Para solicitar oplocks herdados:
Solicitando um oplock no modo de usuário
Para solicitar um oplock do Windows 7 no modo de usuário, chame DeviceIoControl:
- Defina dwIoControlCode como FSCTL_REQUEST_OPLOCK.
- Passe um ponteiro para uma estrutura REQUEST_OPLOCK_INPUT_BUFFER no parâmetro lpInBuffer.
- Consulte a documentação dessa estrutura para obter informações sobre como formatar a solicitação de oplock.
- Passe um ponteiro para uma estrutura REQUEST_OPLOCK_OUTPUT_BUFFER no parâmetro lpOutBuffer.
Para obter mais informações, consulte FSCTL_REQUEST_OPLOCK.
Se o oplock solicitado puder ser concedido, DeviceIoControl retornará FALSE e GetLastError retornará ERROR_IO_PENDING. Por esse motivo, os oplocks nunca são concedidos para E/S síncronas. A operação sobreposta não é concluída até que o oplock seja quebrado. Após a conclusão da operação, o REQUEST_OPLOCK_OUTPUT_BUFFER conterá informações sobre a quebra do oplock.
Se o oplock não puder ser concedido, o sistema de arquivos retornará um código de erro apropriado. Os códigos de erro mais comumente retornados são ERROR_OPLOCK_NOT_GRANTED e ERROR_INVALID_PARAMETER.
Solicitar um oplock em modo kernel
Para solicitar oplocks do Windows 7 em modo kernel:
Minifiltros do sistema de arquivos
Um minifiltro do sistema de arquivos deve usar FltAllocateCallbackData e preencher a FLT_CALLBACK_DATA alocada da seguinte forma:
- Defina seu campo Iopb->MajorFunction como IRP_MJ_FILE_SYSETM_CONTROL.
- Defina o campo Iopb->MinorFunction como IRP_MN_USER_FS_REQUEST.
- Defina os parâmetros Iopb->do membro FileSystemControl.Buffered.FsControlCode para FSCTL_REQUEST_OPLOCK.
- Aloque um buffer cujo tamanho seja igual ao maior dos REQUEST_OPLOCK_INPUT_BUFFER ou REQUEST_OPLOCK_OUTPUT_BUFFER.
- Defina o do FLT_CALLBACK_DATAalocado Iopb->Parameters.FileSystemControl.Buffered.SystemBuffer membro para apontar para esse buffer.
- Defina o alocado do FLT_CALLBACK_DATAIopb->Parameters.FileSystemControl.Buffered.InputBufferLength e campos Iopb->Parameters.FileSystemControl.Buffered.OutputBufferLength para o tamanho desse buffer.
Consulte a documentação da estrutura REQUEST_OPLOCK_INPUT_BUFFER para obter informações sobre como formatar a solicitação de oplock.
Em seguida, o minifiltro do sistema de arquivos deve chamar FltPerformAsynchronousIo, passando FLT_CALLBACK_DATA alocado como parâmetro CallbackData.
Se o oplock solicitado puder ser concedido, a chamada FltPerformAsynchronousIo retornará STATUS_PENDING. Por esse motivo, os oplocks nunca são concedidos para E/S síncronas. A operação não é concluída até que o "oplock" seja quebrado. Após a conclusão da operação, o REQUEST_OPLOCK_OUTPUT_BUFFER conterá informações sobre a quebra do oplock.
Se o oplock não puder ser concedido, o sistema de arquivos retornará um código de erro apropriado. Os códigos de erro mais comumente retornados são STATUS_OPLOCK_NOT_GRANTED e STATUS_INVALID_PARAMETER.
Outros Tipos de Drivers
Outros tipos de drivers podem chamar ZwFsControlFile:
- Defina FsControlCode como FSCTL_REQUEST_OPLOCK.
- Passe um ponteiro para uma estrutura de REQUEST_OPLOCK_INPUT_BUFFER no parâmetro InputBuffer do e defina o parâmetro InputBufferLength para o tamanho desse buffer.
- Passe um ponteiro para uma estrutura de REQUEST_OPLOCK_OUTPUT_BUFFER no parâmetro OutputBuffer do e defina o parâmetro OutputBufferLength para o tamanho desse buffer.
Consulte a documentação da estrutura REQUEST_OPLOCK_INPUT_BUFFER para obter informações sobre como formatar a solicitação de oplock.
Se o oplock solicitado puder ser concedido, a chamada ZwFsControlFile devolverá STATUS_PENDING. Por esse motivo, os oplocks nunca são concedidos para E/S síncronas. A operação não é concluída até que o oplock seja quebrado. Após a conclusão da operação, o REQUEST_OPLOCK_OUTPUT_BUFFER conterá informações sobre a quebra do oplock.
Se o oplock não puder ser concedido, o sistema de arquivos retornará um código de erro apropriado. Os códigos de erro mais comumente retornados são STATUS_OPLOCK_NOT_GRANTED e STATUS_INVALID_PARAMETER.
Evitando violações de compartilhamento ao solicitar Oplocks
Usando o método Atomic Create-With-Oplock
Atomic create-with-oplock não é um tipo de oplock. Em vez disso, é um procedimento que permite operações abertas para evitar causar violações do modo de compartilhamento no intervalo de tempo entre a abertura de um arquivo e o recebimento de um oplock. Com oplocks legados, é necessário filtrar oplocks e abrir duas alças. Com os oplocks do Windows 7, um aplicativo ou driver pode solicitar qualquer tipo de oplock usando este procedimento e precisa de abrir apenas um handle.
Para executar o procedimento create-with-oplock atômico, você deve:
- Use FltCreateFileEx2 ou ZwCreateFile, conforme apropriado, para abrir o arquivo. No parâmetro CreateOptions, passe o indicador FILE_OPEN_REQUIRING_OPLOCK. Você pode definir os parâmetros DesiredAccess e ShareAccess conforme desejado. Por exemplo, no parâmetro DesiredAccess, defina GENERIC_READ para poder ler o arquivo, e no parâmetro ShareAccess, defina os sinalizadores FILE_SHARE_READ | FILE_SHARE_DELETE para permitir que outras pessoas leiam, renomeiem e/ou marquem o arquivo para eliminação enquanto o tiver aberto.
- Use o código de controlo FSCTL_REQUEST_OPLOCK para solicitar um oplock no objeto ou identificador de ficheiro resultante, conforme descrito em Solicitar um Oplock no Modo Kernel.
Não execute nenhuma operação do sistema de arquivos no arquivo entre as etapas 1 e 2. Fazer isso pode causar impasses.
O oplock mais comum a ser solicitado através deste procedimento é o tipo Read-Handle. Isso permite que você permita que outros chamadores tenham o máximo de acesso simultâneo possível, enquanto ainda permite que você seja notificado se precisar fechar seu identificador para evitar causar uma violação de compartilhamento em uma abertura conflitante.
Usando o filtro herdado Oplock
O filtro oplock legado também permite que um aplicativo retroceda quando outros aplicativos/clientes tentam acessar o mesmo fluxo, mas é menos flexível do que o método de criação-com-oplock atômico. Esse mecanismo permite que um aplicativo acesse um fluxo sem fazer com que outros acessadores do fluxo recebam violações de compartilhamento ao tentar abrir o fluxo. Para evitar violações de compartilhamento, o procedimento de três etapas a seguir deve ser usado para solicitar um bloqueio de filtro:
Abra o ficheiro com um acesso requerido de FILE_READ_ATTRIBUTES e um modo de partilha de FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE. O identificador aberto nesta etapa não fará com que outros aplicativos recebam violações de compartilhamento porque está aberto apenas para acesso a atributos (FILE_READ_ATTRIBUTES) e não para acesso a dados (FILE_READ_DATA). Este identificador é adequado para solicitar a operação de bloqueio de filtro, mas não para executar E/S reais no fluxo de dados.
Solicite um filtro oplock (FSCTL_REQUEST_FILTER_OPLOCK) no handle do passo 1. O oplock concedido nesta etapa permite que o detentor do oplock "saia do caminho" sem causar uma violação de compartilhamento para outro aplicativo que tenta acessar o fluxo.
Abra o arquivo novamente para acesso de leitura. O identificador aberto nesta etapa permite que o detentor do oplock execute operações de Entrada/Saída no fluxo.
O sistema de ficheiros NTFS fornece uma otimização para este procedimento através do sinalizador de opção de criação FILE_RESERVE_OPFILTER. Se este sinalizador for especificado na etapa 1 do procedimento anterior, isso permite que o sistema de ficheiros recuse a solicitação de criação com STATUS_OPLOCK_NOT_GRANTED se puder determinar que a etapa 2 irá falhar. Se a etapa 1 for bem-sucedida, não há garantia de que a etapa 2 será bem-sucedida, mesmo que FILE_RESERVE_OPFILTER tenha sido especificada para a solicitação de criação.
Condições para a concessão de Oplocks
A tabela a seguir identifica as condições requeridas para a concessão de um oplock.
| Tipo de pedido | Condições |
|---|---|
Nível 1 Filtrar Lote |
Concedido somente se todas as seguintes condições forem verdadeiras:
Se o estado de oplock atual for:
|
Nível 2 |
Concedido somente se todas as seguintes condições forem verdadeiras:
Se o estado de oplock atual for:
|
Ler |
Concedido somente se todas as seguintes condições forem verdadeiras:
Se o estado de oplock atual for:
|
Read-Handle |
Concedido somente se todas as seguintes condições forem verdadeiras:
Se o estado de oplock atual for:
|
Read-Write |
Concedido somente se todas as seguintes condições forem verdadeiras:
Se o estado de oplock atual for:
|
Ler-Write-Handle |
Concedido somente se todas as seguintes condições forem verdadeiras:
Se o estado de oplock atual for:
|
Observação
Os oplocks de leitura e de nível 2 podem coexistir no mesmo fluxo, e os oplocks de leitura e Read-Handle podem coexistir, mas os oplocks de nível 2 e Read-Handle não podem coexistir.