Подтвердить что ты не робот

Как открываются флаги O_SYNC и O_DIRECT (2) разные/одинаковые?

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

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

4b9b3361

Ответ 1

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

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

O_DIRECT | O_SYNC - это комбинация этих, то есть "гарантия DMA +".

Ответ 2

Пожалуйста, просмотрите эту статью в разделе, чтобы получить четкое описание ролей O_DIRECT и O_SYNC и их влияние на целостность данных:

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

Ответ 3

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

manpage of open, есть 2 раздела об этом..

До 2.4 не гарантируется

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

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

, но ниже 2.6 гарантируется, см.

O_DIRECT

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

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

O_DIRECT I/O никогда не следует запускать одновременно с системным вызовом fork (2), если буфер памяти является приватным сопоставлением (т.е. любым сопоставлением, созданным с флагом MAP_PRIVATE от mmap (2), включая память, выделенную на кучи и статически распределенные буферы). Любые такие операции ввода/вывода, передаваемые через асинхронный интерфейс ввода-вывода или из другого потока процесса, должны быть завершены до вызова fork (2). Несоблюдение этого требования может привести к повреждению данных и поведению undefined в родительских и дочерних процессах. Это ограничение не применяется, когда буфер памяти для ввода/вывода 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 I/O будет только обходить кеш страницы на клиенте; сервер все еще может кэшировать ввод-вывод. Клиент запрашивает сервер для синхронного ввода-вывода для сохранения синхронной семантики O_DIRECT. В некоторых случаях некоторые серверы будут плохо работать, особенно если размер ввода-вывода мал. Некоторые серверы также могут быть настроены так, чтобы лгать клиентам о том, что ввод-вывод достиг стабильного хранилища; это позволит избежать штрафа за производительность при некотором риске целостности данных в случае сбоя питания сервера. Клиент NFS Linux не устанавливает ограничений на выравнивание для O_DIRECT I/O.

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

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

Ответ 4

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