Comment les indicateurs O_SYNC et O_DIRECT sont-ils différents / ouverts?

L’utilisation et les effets des indicateurs O_SYNC et O_DIRECT sont très déroutants et semblent varier quelque peu d’une plateforme à l’autre. A partir de la page de manuel Linux (voir un exemple ici ), O_DIRECT fournit des E / S synchrones, minimise les effets de cache et vous oblige à gérer vous-même l’alignement de la taille des blocs. O_SYNC garantit simplement des E / S synchrones. Bien que les deux garantissent que les données sont écrites dans le cache du disque dur, je pense que les opérations d’E / S directes sont supposées être plus rapides que les E / S synchrones car elles contournent le cache de page (la page de manuel de FreeBSD pour open (2) indique que le cache est ignoré lorsque O_SYNC est utilisé (voir ici ).

Quelles sont exactement les différences entre les drapeaux O_DIRECT et O_SYNC? Certaines implémentations suggèrent d’utiliser O_SYNC | O_DIRECT. Pourquoi?

O_DIRECT promet à lui seul que le kernel évitera de copier les données de l’espace utilisateur vers l’espace kernel et l’écrira directement via DMA (access direct à la mémoire, si possible). Les données ne sont pas stockées dans les caches. Il n’y a aucune garantie ssortingcte que la fonction ne sera retournée qu’après que toutes les données aient été transférées.

O_SYNC garantit que l’appel ne sera pas renvoyé avant que toutes les données aient été transférées sur le disque (pour autant que le système d’exploitation le sache). Cela ne garantit toujours pas que les données ne se trouvent pas quelque part dans le cache en écriture du disque dur, mais tout ce que le système d’exploitation peut garantir.

O_DIRECT | O_SYNC est la combinaison de ceux-ci, c.-à-d. “Garantie DMA +”.

Veuillez consulter cet article pour une description claire des rôles de O_DIRECT et O_SYNC et leur impact sur l’intégrité des données:

https://lwn.net/Articles/457667/

Sous Linux 2.6, o_direct est synchrone, voir la page de manuel:

page de manuel ouverte, il y a 2 section à ce sujet ..

Sous 2.4, il n’est pas garanti

O_DIRECT (Depuis Linux 2.4.10) Essayez de minimiser les effets de cache des E / S vers et depuis ce fichier. En général, cela va dégrader les performances, mais il est utile dans des situations spéciales, par exemple lorsque les applications effectuent leur propre mise en cache. Les E / S sur fichiers sont effectuées directement vers / depuis les tampons de l’espace utilisateur. L’indicateur O_DIRECT seul tente de transférer les données de manière synchrone, mais ne donne pas les garanties de l’indicateur O_SYNC que les données et les métadonnées nécessaires sont transférées. Pour garantir les E / S synchrones, O_SYNC doit être utilisé en plus de O_DIRECT. Voir NOTES ci-dessous pour plus de détails.

Une interface sémantiquement similaire (mais déconseillée) pour les périphériques de bloc est décrite dans raw (8).

mais en dessous de 2,6, il est garanti, voir

O_DIRECT

L’indicateur O_DIRECT peut imposer des ressortingctions d’alignement sur la longueur et l’adresse des tampons d’espace utilisateur et le décalage de fichier des E / S. Dans Linux, les ressortingctions d’alignement varient selon le système de fichiers et la version du kernel et peuvent être totalement absentes. Cependant, il n’existe actuellement aucune interface indépendante du système de fichiers pour qu’une application découvre ces ressortingctions pour un fichier ou un système de fichiers donné. Certains systèmes de fichiers fournissent leurs propres interfaces pour cela, par exemple l’opération XFS_IOC_DIOINFO dans xfsctl (3).

Sous Linux 2.4, les tailles de transfert et l’alignement du tampon utilisateur et du décalage de fichier doivent tous être des multiples de la taille de bloc logique du système de fichiers. Sous Linux 2.6, l’alignement sur les limites de 512 octets suffit.

Les E / S O_DIRECT ne doivent jamais être exécutées en même temps que l’appel système fork (2), si la mémoire tampon est une correspondance privée (toute correspondance créée avec l’indicateur MAP_PRIVATE de mmap (2)). tampons alloués). Toutes les entrées / sorties, qu’elles soient soumises via une interface d’E / S asynchrone ou à partir d’un autre thread du processus, doivent être terminées avant l’appel de fork (2). Si vous ne le faites pas, vous risquez de corrompre les données et d’avoir un comportement non défini dans les processus parents et enfants. Cette ressortingction ne s’applique pas lorsque le tampon de mémoire pour les E / S O_DIRECT a été créé à l’aide de shmat (2) ou mmap (2) avec l’indicateur MAP_SHARED. Cette ressortingction ne s’applique pas non plus lorsque le tampon de mémoire a été conseillé en tant que MADV_DONTFORK avec madvise (2), en s’assurant qu’il ne sera pas disponible pour l’enfant après fork (2).

Le drapeau O_DIRECT a été introduit dans SGI IRIX, avec des ressortingctions d’alignement similaires à celles de Linux 2.4. IRIX a également un appel fcntl (2) pour interroger les alignements et les tailles appropriés. FreeBSD 4.x a introduit un drapeau du même nom, mais sans ressortingctions d’alignement.

Le support O_DIRECT a été ajouté sous Linux dans la version 2.4.10 du kernel. Les kernelx Linux plus anciens ignorent simplement cet indicateur. Certains systèmes de fichiers ne peuvent pas implémenter l’indicateur et open () échouera avec EINVAL s’il est utilisé.

Les applications doivent éviter de mélanger O / IDirect et des E / S normales sur le même fichier, et en particulier aux régions d’octets qui se chevauchent dans le même fichier. Même lorsque le système de fichiers gère correctement les problèmes de cohérence dans cette situation, le débit d’E / S global risque d’être plus lent que l’utilisation de l’un ou l’autre mode uniquement. De même, les applications devraient éviter de mélanger les fichiers mmap (2) avec des E / S directes aux mêmes fichiers.

Le comportement de O_DIRECT avec NFS sera différent de celui des systèmes de fichiers locaux. Les kernelx plus anciens, ou kernelx configurés de certaines manières, peuvent ne pas prendre en charge cette combinaison. Le protocole NFS ne prend pas en charge la transmission de l’indicateur au serveur, de sorte que les E / S O_DIRECT contourneront uniquement le cache de page sur le client; le serveur peut toujours mettre en cache les E / S. Le client demande au serveur de synchroniser les E / S pour préserver la sémantique synchrone de O_DIRECT. Certains serveurs fonctionnent mal dans ces circonstances, surtout si la taille des E / S est faible. Certains serveurs peuvent également être configurés pour mentir aux clients à propos des E / S ayant atteint un stockage stable; Cela évitera que les performances ne soient compromises pour l’intégrité des données en cas de panne de courant du serveur. Le client Linux NFS ne place aucune ressortingction d’alignement sur les E / S O_DIRECT.

En résumé, O_DIRECT est un outil potentiellement puissant qui doit être utilisé avec prudence. Il est recommandé que les applications traitent l’utilisation d’O_DIRECT comme une option de performance désactivée par défaut.

“Ce qui m’a toujours dérangé à propos d’O_DIRECT, c’est que toute l’interface est simplement stupide, et qu’elle a probablement été conçue par un singe dérangé sur certaines substances de contrôle de l’esprit sérieuses.” — Linus

AFAIK, O_DIRECT contourne le cache de la page. O_SYNC utilise le cache de la page mais le synchronise immédiatement. Le cache de pages est partagé entre les processus. Par conséquent, si un autre processus fonctionne sur le même fichier sans indicateur O_DIRECT, il peut lire les données correctes.