Lorsque le redirecteur réseau accède aux fichiers sur des serveurs distants, il demande l’oplock à partir du serveur distant. Les applications clientes demandent directement des oplocks uniquement lorsque le verrou est destiné à un fichier sur le serveur local.
Les oplocks sont demandés par le biais de FSCTL. Les FSCTL suivantes sont utilisées pour les différents types d’oplock, que les applications en mode utilisateur et les pilotes en mode noyau peuvent émettre :
Spécifiez l’indicateur REQUEST_OPLOCK_INPUT_FLAG_REQUEST dans le membre Flags de la structure REQUEST_OPLOCK_INPUT_BUFFER , qui est passé en tant que paramètre lpInBuffer .
De la même manière, pour demander des oplocks Windows 7 en mode noyau :
Un minifiltre de système non-fichiers peut appeler ZwFsControlFile.
Pour spécifier lequel des quatre oplocks Windows 7 est requis, définissez un ou plusieurs des indicateurs suivants dans le membre RequestedOplockLevel de la structure REQUEST_OPLOCK_INPUT_BUFFER :
Si l’oplock demandé peut être accordé, le système de fichiers retourne STATUS_PENDING. Pour cette raison, les oplocks ne sont jamais accordés pour les E/S synchrones. L’IRP FSCTL ne se termine pas tant que l’oplock n’est pas rompu.
Si l’oplock ne peut pas être accordé, le système de fichiers retourne un code d’erreur approprié. Les codes d’erreur les plus fréquemment retournés sont STATUS_OPLOCK_NOT_GRANTED et STATUS_INVALID_PARAMETER (et leurs analogues en mode utilisateur équivalents).
L’oplock de filtre permet à une application de « reculer » lorsque d’autres applications/clients essaient d’accéder au même flux. Ce mécanisme permet à une application d’accéder à un flux sans que d’autres accesseurs du flux reçoivent des violations de partage lors de la tentative d’ouverture du flux. Pour éviter les violations de partage, une procédure spéciale en trois étapes doit être utilisée pour demander un oplock de filtre (FSCTL_REQUEST_FILTER_OPLOCK) :
Ouvrez le fichier avec un accès obligatoire à FILE_READ_ATTRIBUTES et un mode de partage de FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE.
Demandez un oplock de filtre sur le handle à partir de l’étape 1.
Ouvrez à nouveau le fichier pour un accès en lecture.
Le handle ouvert à l’étape 1 n’entraîne pas de violations de partage pour d’autres applications, car il est ouvert uniquement pour l’accès aux attributs (FILE_READ_ATTRIBUTES), et non pour l’accès aux données (FILE_READ_DATA). Ce handle convient pour demander l’oplock de filtre, mais pas pour effectuer des E/S réelles sur le flux de données. Le handle ouvert à l’étape 3 permet au titulaire de l’oplock d’effectuer des E/S sur le flux ; l’oplock accordé à l’étape 2 permet au titulaire de l’oplock de « sortir du chemin » sans provoquer une violation de partage vers une autre application qui tente d’accéder au flux.
Le système de fichiers NTFS fournit une optimisation de cette procédure via l’indicateur d’option de création FILE_RESERVE_OPFILTER. Si cet indicateur est spécifié à l’étape 1 de la procédure précédente, il permet au système de fichiers d’échouer la demande de création avec STATUS_OPLOCK_NOT_GRANTED si le système de fichiers peut déterminer que l’étape 2 échouera. Si l’étape 1 réussit, rien ne garantit que l’étape 2 réussit, même si FILE_RESERVE_OPFILTER a été spécifié pour la demande de création.
Le tableau suivant identifie les conditions requises pour accorder un oplock.
Type de demande
Conditions
Niveau 1
Filtrer
Batch
Accordé uniquement si toutes les conditions suivantes sont remplies :
La demande concerne un flux donné d’un fichier.
S’il s’agit d’un répertoire, STATUS_INVALID_PARAMETER est retourné.
Le flux est ouvert pour l’accès ASYNCHRONE.
S’il est ouvert pour l’accès SYNCHRONOUS, STATUS_OPLOCK_NOT_GRANTED est retourné (les oplocks ne sont pas accordés pour les demandes d’E/S synchrones).
Il n’existe aucune transaction TxF sur un flux du fichier.
Sinon, STATUS_OPLOCK_NOT_GRANTED est retourné.
Il n’y a pas d’autres ouvertures sur le flux (même par le même thread).
Sinon, STATUS_OPLOCK_NOT_GRANTED est retourné.
Si l’état oplock actuel est :
Pas d’oplock : la demande est accordée.
Niveau 2 : la requête de niveau 2 d’origine est rompue avec FILE_OPLOCK_BROKEN_TO_NONE. L’oplock exclusif demandé est alors accordé.
Niveau 1, Batch, Filter, Read, Read-Handle, Read-Write ou Read-Write-Handle : STATUS_OPLOCK_NOT_GRANTED est retourné.
Niveau 2
Accordé uniquement si toutes les conditions suivantes sont remplies :
La demande concerne un flux donné d’un fichier.
S’il s’agit d’un répertoire, STATUS_INVALID_PARAMETER est retourné.
Le flux est ouvert pour l’accès ASYNCHRONE.
S’il est ouvert pour l’accès SYNCHRONOUS, STATUS_OPLOCK_NOT_GRANTED est retourné.
Il n’y a aucune transaction TxF sur le fichier.
Sinon, STATUS_OPLOCK_NOT_GRANTED est retourné.
Il n’existe aucun verrou de plage d’octets actuel sur le flux.
Sinon, STATUS_OPLOCK_NOT_GRANTED est retourné.
Avant Windows 7, le système d’exploitation vérifie si un verrou de plage d’octets a déjà existé sur le flux depuis la dernière ouverture de celui-ci, et échoue à la demande si c’est le cas.
Si l’état oplock actuel est :
Pas d’oplock : la demande est accordée.
Niveau 2 et/ou Lecture : la demande est accordée. Plusieurs oplocks de niveau 2/Lecture peuvent être accordés sur le même flux en même temps. Plusieurs oplocks de niveau 2 (mais pas en lecture) peuvent même exister sur le même handle.
Si un oplock en lecture est demandé sur un handle qui dispose déjà d’un oplock en lecture, l’IRP du premier oplock en lecture est terminé avec STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE avant que le deuxième oplock en lecture ne soit accordé.
Niveau 1, Batch, Filter, Read-Handle, Read-Write, Read-Write-Handle : STATUS_OPLOCK_NOT_GRANTED est retourné.
Lire
Accordé uniquement si toutes les conditions suivantes sont remplies :
La demande concerne un flux donné d’un fichier.
Le flux est ouvert pour l’accès ASYNCHRONE.
S’il est ouvert pour l’accès SYNCHRONOUS, STATUS_OPLOCK_NOT_GRANTED est retourné.
Il n’y a aucune transaction TxF sur le fichier.
Sinon, STATUS_OPLOCK_NOT_GRANTED est retourné.
Il n’existe aucun verrou de plage d’octets actuel sur le flux.
Sinon, STATUS_OPLOCK_NOT_GRANTED est retourné.
N’oubliez pas que si l’état oplock actuel est :
Pas d’oplock : la demande est accordée.
Niveau 2 et/ou Lecture : la demande est accordée. Plusieurs oplocks de niveau 2/Lecture peuvent être accordés sur le même flux en même temps.
En outre, si un oplock existant a la même clé oplock que la nouvelle requête, son IRP est terminé avec STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE.
Read-Handle et l’oplock existant ont une clé oplock différente de la nouvelle requête : la demande est accordée. Plusieurs oplocks en lecture et Read-Handle peuvent coexister sur le même flux (voir la note ci-dessous).
Sinon (les touches oplock sont identiques) STATUS_OPLOCK_NOT_GRANTED est retourné.
Niveau 1, Batch, Filter, Read-Write, Read-Write-Handle : STATUS_OPLOCK_NOT_GRANTED est retourné.
Read-Handle
Accordé uniquement si toutes les conditions suivantes sont remplies :
La demande concerne un flux donné d’un fichier.
Le flux est ouvert pour l’accès ASYNCHRONE.
S’il est ouvert pour l’accès SYNCHRONOUS, STATUS_OPLOCK_NOT_GRANTED est retourné.
Il n’y a aucune transaction TxF sur le fichier.
Sinon, STATUS_OPLOCK_NOT_GRANTED est retourné.
Il n’existe aucun verrou de plage d’octets actuel sur le flux.
Sinon, STATUS_OPLOCK_NOT_GRANTED est retourné.
Si l’état oplock actuel est :
Aucun oplock : la demande est accordée.
Lecture : la demande est accordée.
Si un oplock read existant a la même clé oplock que la nouvelle requête, son IRP est terminé avec STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE. Le résultat est que l’oplock est mis à niveau de Lecture vers Read-Handle.
Tout oplock read existant qui n’a pas la même clé oplock que la nouvelle requête reste inchangé.
Niveau 2, Niveau 1, Batch, Filter, Read-Write, Read-Write-Handle : STATUS_OPLOCK_NOT_GRANTED est retourné.
Lecture-écriture
Accordé uniquement si toutes les conditions suivantes sont remplies :
La demande concerne un flux donné d’un fichier.
S’il s’agit d’un répertoire, STATUS_INVALID_PARAMETER est retourné.
Le flux est ouvert pour l’accès ASYNCHRONE.
S’il est ouvert pour l’accès SYNCHRONOUS, STATUS_OPLOCK_NOT_GRANTED est retourné.
Il n’y a aucune transaction TxF sur le fichier.
Sinon, STATUS_OPLOCK_NOT_GRANTED est retourné.
S’il existe d’autres ouvertures sur le flux (même par le même thread), elles doivent avoir la même clé oplock.
Sinon, STATUS_OPLOCK_NOT_GRANTED est retourné.
Si l’état oplock actuel est :
Aucun oplock : la demande est accordée.
Lire ou Read-Write et le verrou oplock existant a la même clé oplock que la demande : l’IRP de l’oplock existant est terminé avec STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE, la demande est accordée.
Sinon, STATUS_OPLOCK_NOT_GRANTED est retourné.
Niveau 2, Niveau 1, Batch, Filter, Read-Handle, Read-Write-Handle : STATUS_OPLOCK_NOT_GRANTED est retourné.
Handle en lecture-écriture
Accordé uniquement si toutes les conditions suivantes sont remplies :
La demande concerne un flux donné d’un fichier.
S’il s’agit d’un répertoire, STATUS_INVALID_PARAMETER est retourné.
Le flux est ouvert pour l’accès ASYNCHRONE.
S’il est ouvert pour l’accès SYNCHRONOUS, STATUS_OPLOCK_NOT_GRANTED est retourné.
Il n’y a aucune transaction TxF sur le fichier.
Sinon, STATUS_OPLOCK_NOT_GRANTED est retourné.
S’il existe d’autres requêtes ouvertes sur le flux (même par le même thread), elles doivent avoir la même clé oplock.
Sinon, STATUS_OPLOCK_NOT_GRANTED est retourné.
Si l’état oplock actuel est :
Aucun oplock : la demande est accordée.
Read, Read-Handle, Read-Write ou Read-Write-Handle, et l’oplock existant a la même clé oplock que la requête : l’IRP de l’oplock existant est effectué avec STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE, la demande est accordée.
Sinon, STATUS_OPLOCK_NOT_GRANTED est retourné.
Niveau 2, Niveau 1, Lot, Filtre : STATUS_OPLOCK_NOT_GRANTED est retourné.
Notes
Les oplocks de lecture et de niveau 2 peuvent coexister sur le même flux, et les oplocks de lecture et de Read-Handle peuvent coexister, mais les oplocks de niveau 2 et Read-Handle ne peuvent pas coexister.