Interruption des oplocks
Une fois qu'un oplock est demandé et accordé, le propriétaire de cet oplock a accès au flux en fonction du type d'oplock qui a été demandé. Si l’opération reçue n’est pas compatible avec le verrou d’opération actuel, le système interrompt l’opération.
Lorsqu'un oplock est accordé, le système suspend l'IRP de la requête. Lorsqu'un oplock est rompu, l'IRP de requête de l'oplock suspendu se termine avec STATUS_SUCCESS. Pour les oplocks de niveau 1, de lot et de filtre, le membre IoStatus.Information de l'IRP est défini pour indiquer le niveau auquel l'oplock est brisé. Ces niveaux sont les suivants :
FILE_OPLOCK_BROKEN_TO_NONE : L'oplock a été cassé et il n'y a pas d'oplock en cours sur le flux. On dit que la serrure est « cassée à zéro ».
FILE_OPLOCK_BROKEN_TO_LEVEL_2 : Le verrou actuel (niveau 1 ou Batch) a été converti en verrou de niveau 2. Les oplocks de filtrage ne passent jamais au niveau 2, ils passent toujours à None.
Pour les oplocks de type Read-Handle, Read-Write et Read-Write-Handle, le niveau auquel l'oplock passe est décrit comme une combinaison d'au moins zéro des indicateurs OPLOCK_LEVEL_CACHE_READ, OPLOCK_LEVEL_CACHE_HANDLE ou OPLOCK_LEVEL_CACHE_WRITE dans le membre NewOplockLevel de la structure REQUEST_OPLOCK_OUTPUT_BUFFER transmise en tant que paramètre lpOutBuffer de la commande DeviceIoControl. De la même manière, fltFsControlFile et ZwFsControlFile peuvent être utilisés pour demander des oplocks Windows 7 à partir du mode noyau. Pour obtenir plus d’informations, reportez-vous à FSCTL_REQUEST_OPLOCK.
Lorsque le package oplock du système rompt un oplock de niveau 1, Batch, Filter, Read-Write, Read-Write-Handle ou, dans certaines circonstances, un Read-Handle :
- Le package oplock termine l'IRP de requête d'oplock en suspens.
- L'opération qui a causé l'interruption de l'oplock est elle-même suspendue.
Le gestionnaire d’E/S provoque le blocage de l’opération, au lieu de retourner STATUS_PENDING, si l’opération :
- est émise sur un handle synchrone.
- Il s'agit d'une IRP_MJ_CREATE, qui est toujours synchrone.
Le gestionnaire d'E/S attend un accusé de réception du propriétaire de l'oplock pour indiquer au package de l'oplock qu'il a terminé son traitement et que l'opération suspendue peut se poursuivre en toute sécurité. Ce délai permet au propriétaire oplock de remettre le flux dans un état cohérent avant que l’opération actuelle ne se poursuive. Le système attendrait indéfiniment de recevoir l'accusé de réception car il n'y a pas de délai d'attente. Il incombe donc au propriétaire de l'oplock d'accuser réception de l'interruption en temps utile. L'IRP de l'opération suspendue est placée dans un état annulable. Si l'application ou le pilote qui effectue l'attente se termine, le package de l'oplock termine immédiatement l'IRP avec STATUS_CANCELLED.
Une IRP_MJ_CREATE peut spécifier l'option de création FILE_COMPLETE_IF_OPLOCKED pour éviter d'être bloquée dans le cadre de l'acquittement de la rupture oplock. Cette option indique au package oplock de ne pas bloquer l'IRP de création jusqu'à ce que l'accusé de réception de la rupture d'oplock soit reçu. Au lieu de cela, la création est autorisée. Si une création réussie entraîne un arrêt d’oplock, le code de retour est STATUS_OPLOCK_BREAK_IN_PROGRESS, au lieu de STATUS_SUCCESS. L’indicateur FILE_COMPLETE_IF_OPLOCKED est généralement utilisé pour éviter les interblocages. Par exemple, si un client possède un oplock sur un flux et que le même client ouvre ensuite le même flux, le client se bloquera en attendant que lui-même accuse réception de l'interruption de l'oplock. Dans ce scénario, l’utilisation de l’indicateur de FILE_COMPLETE_IF_OPLOCKED évite l’interblocage.
Le système de fichiers NTFS initie les ruptures d'oplocks pour les oplocks Batch et Filter avant de vérifier les violations de partage. Il est donc possible qu'une création spécifiant FILE_COMPLETE_IF_OPLOCKED échoue avec STATUS_SHARING_VIOLATION tout en provoquant la rupture d'un oplock Batch ou Filter. Dans ce cas, le membre d'information de la structure IO_STATUS_BLOCK est mis à FILE_OPBATCH_BREAK_UNDERWAY pour permettre à l'appelant de détecter ce cas.
Pour les oplocks Read-Handle et Read-Write-Handle, la rupture d'oplock est initiée après que NTFS ait vérifié et détecté une violation de partage. Cette séquence donne aux détenteurs d'oplocks la possibilité de fermer leurs handles et de se retirer, ce qui permet de ne pas renvoyer la violation de partage à l'utilisateur. Elle permet également d'éviter la rupture inconditionnelle de l'oplock dans les cas où le handle mis en cache par l'oplock n'entre pas en conflit avec le nouveau create.
Lorsque les oplocks de niveau 2, de lecture et, dans certaines circonstances, de lecture de poignée se rompent, le système n'attend pas d'accusé de réception. La raison est qu’il ne doit pas y avoir d’état mis en cache sur le flux qui doit être restauré dans le fichier avant d’autoriser d’autres clients à y accéder.
Il existe certaines opérations de système de fichiers qui vérifient l’état d’oplock actuel pour déterminer si l’oplock doit être rompu. Les articles suivants, spécifiques à certaines opérations, décrivent ce qui déclenche le déblocage d'un oplock, ce qui détermine le niveau de déblocage de l'oplock et si un accusé de réception du déblocage est nécessaire :
- 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
- FS_FILTER_ACQUIRE_FOR_SECTION_SYNCHRONIZATION
La rupture d'un oplock Windows 7 nécessite un accusé de réception si l'indicateur REQUEST_OPLOCK_OUTPUT_FLAG_ACK_REQUIRED est défini dans le membre Flags de la structure REQUEST_OPLOCK_OUTPUT_BUFFER transmise en tant que paramètre de sortie de DeviceIoControl(lpOutBuffer), FltFsControlFile(OutBuffer) ou ZwFsControlFile(OutBuffer). Pour plus d'informations, voir FSCTL_REQUEST_OPLOCK.
Les articles énumérés par opération décrivent les détails du moment où la rupture d'un oplock Read-Handle entraîne la mise en attente de l'opération qui a rompu l'oplock. Par exemple, l’article IRP_MJ_CREATE contient les détails Read-Handle associés.