Вначале чтение через O_DIRECT сбрасывает грязные страницы? - PullRequest
0 голосов
/ 21 сентября 2018

Предположим, у меня есть простая программа, которая выполняет следующее:

fdWrite = open("file", O_WRONLY);
fdRead = open("file", O_RDONLY | O_DIRECT);
writeBuffer = <some data>;
write(fdWrite, writeBuffer);
readBuffer = read(fdRead, sizeof(writeBuffer));

Будет ли гарантировано, что readBuffer == writeBuffer?(Очевидно, что при отсутствии других файлов для этого файла в настоящее время)

Некоторое простое тестирование в Linux предполагает, что да, грязные страницы из вызова write будут сброшены на диск перед чтением через O_DIRECT,но я нигде не могу найти упоминания об этом сценарии.Насколько я знаю, это может быть полным совпадением того, что это сработало, и я понятия не имею, что произойдет на других POSIX-подобных платформах.Я хотел бы получить некоторые "веские доказательства" по этому поводу, по крайней мере.

Почему вы это делаете?

Это в контексте приложения, распространяющего большие файлыкоторые кешируются.Как только новая часть файла получена, я хотел бы проверить новую часть.Я вижу два преимущества использования O_DIRECT: во-первых, я не только проверяю, были ли данные получены правильно, но и может быть получен надлежащим образом с носителя.Без O_DIRECT я гарантированно получаю данные из кеша страниц.Чтобы добиться того же самого без O_DIRECT, мне пришлось использовать непереносимые вызовы, такие как sync_file_range в Linux, чтобы получить данные на диск, затем очистить их из кэша страниц через madvise и, наконец, прочитать их обратно.(Так как я однажды усвоил трудный способ, что вызов madvise с MADV_DONTNEED на грязной странице - это, по сути, пустяк.): -)

1 Ответ

0 голосов
/ 18 ноября 2018

Я не только проверяю, что данные были получены правильно, но и может быть правильно извлечен с носителя.

Для этого вам необходимо победить кэширование.устройством .

Большинство кэшей данных устройства относительно невелики - мегабайты, а не гигабайты. [*] При условии, что ваши большие файлы достаточно велики, вы можете выполнить write () + fsync () иВы переполните кеш устройства.Затем используйте DONTNEED, чтобы удалить его из кэша страниц Linux.Затем вы можете перечитать () файл с устройства.

[*] Некоторые виртуальные среды нарушают это ожидание.https://unix.stackexchange.com/questions/420299/why-is-sync-drop-caches-not-dropping-caches/

...