Чем флаги O_SYNC и O_DIRECT в open (2) различны / похожи? - PullRequest
47 голосов
/ 20 февраля 2011

Использование и эффекты флагов O_SYNC и O_DIRECT очень запутаны и, похоже, различаются для разных платформ. На странице руководства Linux (см. Пример здесь ) O_DIRECT обеспечивает синхронный ввод-вывод, минимизирует эффекты кэширования и требует, чтобы вы обрабатывали выравнивание размера блока самостоятельно. O_SYNC просто гарантирует синхронный ввод / вывод. Хотя оба гарантируют, что данные будут записаны в кэш жесткого диска, я считаю, что прямые операции ввода-вывода должны выполняться быстрее, чем обычные синхронные операции ввода-вывода, поскольку они обходят кеш страниц (хотя man-страница FreeBSD для open (2) утверждает, что кеш обходится при использовании O_SYNC. См. здесь ).

Каковы различия между флагами O_DIRECT и O_SYNC? Некоторые реализации предлагают использовать O_SYNC | O_DIRECT. Зачем?

Ответы [ 4 ]

83 голосов
/ 22 марта 2011

Только O_DIRECT обещает, что ядро ​​не будет копировать данные из пространства пользователя в пространство ядра, и вместо этого запишет их напрямую через DMA (прямой доступ к памяти; если возможно). Данные не попадают в кеши. Нет строгой гарантии, что функция вернется только после передачи всех данных.

O_SYNC гарантирует, что вызов не вернет , пока все данные не будут перенесены на диск (насколько операционная система может сказать). Это все еще не гарантирует, что данные не находятся где-то в кэше записи жесткого диска, но это то, что ОС может гарантировать.

O_DIRECT | O_SYNC является их комбинацией, то есть «гарантия DMA +».

8 голосов
/ 24 мая 2016

Пожалуйста, см. Эту статью для ясного описания ролей O_DIRECT и O_SYNC и их влияния на целостность данных:

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

8 голосов
/ 28 апреля 2013

Actuall под Linux 2.6, o_direct является синхронным, см. Справочную страницу:

man-страница open, есть 2 раздела об этом ..

Менее 2,4 не гарантируется

O_DIRECT (начиная с Linux 2.4.10) Постарайтесь минимизировать эффекты кэширования ввода-вывода в этот файл и из него. В целом это ухудшит производительность, но полезно в особых ситуациях, например, когда приложения выполняют свое собственное кэширование. файл Ввод / вывод выполняется непосредственно в / из буферов пространства пользователя. Флаг O_DIRECT сам по себе пытается передавать данные синхронно, но не дает гарантии флага O_SYNC, что данные и необходимые метаданные передаются. Чтобы гарантировать синхронный ввод-вывод, в дополнение к O_DIRECT необходимо использовать O_SYNC. См. Примечания ниже для дальнейшего обсуждения.

Семантически подобный (но не рекомендуемый) интерфейс для блочных устройств описан в raw (8).

но под 2.6 это гарантировано, см.

O_DIRECT

Флаг O_DIRECT может накладывать ограничения выравнивания на длину и адрес буферов пользовательского пространства и смещение файлов ввода-вывода. В Linux ограничения выравнивания зависят от файловой системы и версии ядра и могут отсутствовать полностью. Однако в настоящее время нет приложения, независимого от файловой системы, чтобы приложение обнаружило эти ограничения для данного файла или файловой системы. Некоторые файловые системы предоставляют свои собственные интерфейсы для этого, например, операция XFS_IOC_DIOINFO в xfsctl (3).

В Linux 2.4 размеры передачи, а также выравнивание пользовательского буфера и смещение файла должны быть кратны размеру логического блока файловой системы. В Linux 2.6 достаточно выравнивания по границам в 512 байт.

Операции ввода-вывода O_DIRECT никогда не должны выполняться одновременно с системным вызовом fork (2), если буфер памяти является частным отображением (т. Е. Любое отображение, созданное с флагом mmap (2) MAP_PRIVATE, включая память, выделенную на куча и статически размещенные буферы). Любые такие операции ввода-вывода, отправленные через интерфейс асинхронного ввода-вывода или из другого потока в процессе, должны быть завершены до вызова fork (2). Невыполнение этого требования может привести к повреждению данных и неопределенному поведению в родительских и дочерних процессах. Это ограничение не применяется, когда буфер памяти для операций ввода-вывода O_DIRECT был создан с использованием shmat (2) или mmap (2) с флагом MAP_SHARED. Также это ограничение не применяется, когда буфер памяти был рекомендован как MADV_DONTFORK с madvise (2), гарантируя, что он не будет доступен потомку после fork (2).

Флаг O_DIRECT был введен в SGI IRIX, где он имеет ограничения выравнивания, аналогичные ограничениям в Linux 2.4. IRIX также имеет вызов fcntl (2) для запроса соответствующих выравниваний и размеров. В FreeBSD 4.x появился флаг с тем же именем, но без ограничений на выравнивание.

Добавлена ​​поддержка O_DIRECT под Linux в версии ядра 2.4.10. Старые ядра Linux просто игнорируют этот флаг. Некоторые файловые системы могут не реализовывать флаг и open () завершится с ошибкой EINVAL, если он используется.

Приложения должны избегать смешивания O_DIRECT и обычного ввода-вывода в одном и том же файле, особенно с перекрывающимися областями байтов в одном и том же файле. Даже когда файловая система правильно обрабатывает проблемы когерентности в этой ситуации, общая пропускная способность ввода-вывода, вероятно, будет медленнее, чем при использовании любого из этих режимов. Аналогичным образом, приложениям следует избегать смешивания mmap (2) файлов с прямым вводом-выводом для одних и тех же файлов.

Поведение O_DIRECT с NFS будет отличаться от локальных файловых систем. Старые ядра или ядра, сконфигурированные определенным образом, могут не поддерживать эту комбинацию. Протокол NFS не поддерживает передачу флага на сервер, поэтому ввод-вывод O_DIRECT будет обходить только кеш страниц на клиенте; сервер все еще может кэшировать ввод / вывод. Клиент просит сервер сделать синхронный ввод-вывод, чтобы сохранить синхронную семантику O_DIRECT. Некоторые серверы будут работать плохо в этих условиях, особенно если размер ввода-вывода невелик. Некоторые серверы также могут быть настроены так, чтобы лгать клиентам о том, что ввод / вывод достиг стабильного хранилища; это позволит избежать снижения производительности при некотором риске для целостности данных в случае сбоя питания сервера. Клиент Linux NFS не накладывает ограничений на выравнивание ввода-вывода O_DIRECT.

Таким образом, O_DIRECT - потенциально мощный инструмент, который следует использовать с осторожностью. В приложениях рекомендуется использовать O_DIRECT как параметр производительности, который по умолчанию отключен.

«Что меня всегда беспокоило в O_DIRECT, так это то, что весь интерфейс просто глупый и, вероятно, был спроектирован обезумевшей обезьяной на некоторых серьезных веществах, контролирующих разум». --- Линус

1 голос
/ 22 марта 2011

AFAIK, O_DIRECT обходит кеш страницы. O_SYNC использует кеш страниц, но синхронизирует его немедленно. Кеш страниц разделяется между процессами, поэтому, если есть другой процесс, работающий с тем же файлом без флага O_DIRECT, может прочитать правильные данные.

...