L'utilisation et les effets des indicateurs O_SYNC et O_DIRECT sont très déroutants et semblent varier quelque peu d'une plate-forme à l'autre. Depuis la page de manuel Linux (voir un exemple ici ), O_DIRECT fournit des E/S synchrones, réduit les effets de cache et vous oblige à gérer vous-même l’alignement de la taille des blocs. O_SYNC ne garantit que les 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 simples et synchrones car elles contournent le cache de pages le cache est ignoré lorsque O_SYNC est utilisé (voir ici ).
Quelles sont exactement les différences entre les indicateurs O_DIRECT et O_SYNC? Certaines implémentations suggèrent d'utiliser O_SYNC | O_DIRECT. Pourquoi?
O_DIRECT seul promet seulement que le noyau évitera de copier les données de l'espace utilisateur vers l'espace du noyau et les écrira directement via DMA (accès direct à la mémoire; si possible). Les données ne vont pas dans les caches. Il n'y a pas de garantie stricte que la fonction ne reviendra que lorsque toutes les données auront été transférées.
O_SYNC garantit que l'appel ne retournera pas avant que toutes les données aient été transférées sur le disque (dans la mesure où le système d'exploitation le sait). Cela ne garantit toujours pas que les données ne se trouvent pas quelque part dans le cache d'écriture du disque dur, mais dans la mesure où le système d'exploitation peut le garantir.
O_DIRECT | O_SYNC est la combinaison de ces éléments, c’est-à-dire "garantie DMA +".
Actuall sous linux 2.6, o_direct est synchrone, voir la page de manuel:
La page de manuel de open, il y a 2 sections à ce sujet ..
Sous 2.4 cela 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. Généralement, cela dégrade les performances, mais cela est utile dans des situations spéciales, telles que lorsque les applications font leur propre mise en cache. Fichier Les E/S sont effectuées directement vers/depuis les tampons de l'espace utilisateur. L’indicateur O_DIRECT s’efforce par lui-même de transférer des 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 des entrées/sorties synchrones, O_SYNC doit être utilisé en plus de O_DIRECT. Voir NOTES ci-dessous pour une discussion plus approfondie.
Une interface sémantiquement similaire (mais déconseillée) pour les périphériques en mode bloc est décrite dans raw (8).
mais sous 2.6 c'est garanti, voir
O_DIRECT
L'indicateur O_DIRECT peut imposer des restrictions d'alignement sur la longueur et l'adresse des tampons de l'espace utilisateur et le décalage de fichier des E/S. Sous Linux, les restrictions d’alignement varient en fonction du système de fichiers et de la version du noyau et peuvent être totalement absentes. Toutefois, il n’existe actuellement aucune interface indépendante du système de fichiers permettant à une application de découvrir ces restrictions pour un fichier ou un système de fichiers donné. Certains systèmes de fichiers fournissent leurs propres interfaces, par exemple l'opération XFS_IOC_DIOINFO dans xfsctl (3).
Sous Linux 2.4, les tailles de transfert, l'alignement du tampon utilisateur et le décalage de fichier doivent tous être des multiples de la taille de bloc logique du système de fichiers. Sous Linux 2.6, un alignement sur les limites de 512 octets suffit.
Les entrées/sorties O_DIRECT ne doivent jamais être exécutées simultanément avec l'appel système fork (2), si la mémoire tampon est un mappage privé (c'est-à-dire tout mappage créé avec l'indicateur mmap (2) MAP_PRIVATE; cela inclut la mémoire allouée sur le tas et de manière statique). tampons alloués). Toutes ces E/S, 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). Ne pas le faire peut entraîner une corruption des données et un comportement non défini dans les processus parent et enfant. Cette restriction ne s'applique pas lorsque la mémoire tampon des E/S O_DIRECT a été créée à l'aide de shmat (2) ou mmap (2) avec l'indicateur MAP_SHARED. Cette restriction ne s'applique pas non plus lorsque la mémoire tampon a été conseillée sous la forme MADV_DONTFORK avec madvise (2), ce qui garantit qu'elle ne sera pas disponible pour l'enfant après le fork (2).
L'indicateur O_DIRECT a été introduit dans SGI IRIX, où des restrictions d'alignement similaires à celles de Linux 2.4 ont été appliquées. 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 restriction d’alignement.
Le support O_DIRECT a été ajouté sous Linux dans la version 2.4.10 du noyau. Les noyaux Linux plus anciens ignorent tout simplement ce drapeau. Certains systèmes de fichiers peuvent ne pas implémenter l'indicateur et open () échouera avec EINVAL s'il est utilisé.
Les applications doivent éviter de mélanger les entrées/sorties normales O_DIRECT et normale dans le même fichier, et en particulier dans les zones de 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 global d'E/S risque d'être plus lent que d'utiliser l'un ou l'autre mode seul. De même, les applications doivent éviter de mélanger mmap (2) de fichiers avec des E/S directes vers les mêmes fichiers.
Le comportement de O_DIRECT avec NFS sera différent de celui des systèmes de fichiers locaux. Les noyaux plus anciens, ou configurés de certaines manières, peuvent ne pas prendre en charge cette combinaison. Le protocole NFS ne prend pas en charge le passage de l'indicateur au serveur. Par conséquent, les E/S O_DIRECT contournent uniquement le cache de page sur le client. le serveur peut toujours mettre en cache les E/S. Le client demande au serveur de rendre les E/S synchrones afin de préserver la sémantique synchrone de O_DIRECT. Certains serveurs ne fonctionneront pas correctement dans ces circonstances, surtout si la taille des E/S est petite. Certains serveurs peuvent également être configurés pour indiquer aux clients que les E/S ont atteint un stockage stable. Cela évitera la dégradation des performances, avec un risque pour l'intégrité des données en cas de panne d'alimentation du serveur. Le client Linux NFS n'impose aucune restriction 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é aux applications de considérer l'utilisation de O_DIRECT comme une option de performance désactivée par défaut.
"Ce qui m'a toujours dérangé dans O_DIRECT, c'est que toute l'interface est stupide et qu'elle a probablement été conçue par un singe dérangé utilisant des substances qui contrôlent l'esprit de manière sérieuse." --- Linus
Veuillez consulter cet article de lwn pour une description claire des rôles de O_DIRECT et de O_SYNC et de leur impact sur l’intégrité des données:
Autant que je sache, O_DIRECT contourne le cache de page. O_SYNC utilise le cache de page mais le synchronise immédiatement. Le cache de page est partagé entre les processus. Ainsi, si un autre processus travaille sur le même fichier sans l'indicateur O_DIRECT, il peut lire les données appropriées.