LINUX.ORG.RU

fsync() и гарантии записи на диск.

 , ,


0

4

Правильно ли воспринимать fsync() как «барьер» файловой системы, а не столько как гарантию какой-либо записи?

Развёрнутый вопрос:

Если я сделал пару write() по 100 МБ каждый, то к какому реальному физическому порядку записи секторов на диск это приведёт гарантий никаких нет: нельзя утверждать, что если записался последний байт из этих 200МБ, то записалось и всё остальное: файловая система вольна переупорядочивать пищущие обращения к диску, повышая свою производительность.

Потому в разных областях говнокодинга существует такое понятие как барьер. Есть барьеры памяти - всякие там std::memory_order в C++, например. И есть барьеры в файловой системе.

Является ли таким барьером fsync()? То есть, можно ли утверждать, что если я вижу записанным сектор «B», который уходил в ФС через write() после вызова fsync(), то всё что ушло в ФС через write() ДО этого вызова fsync() записалось стопудняк?

То есть, гарантируется ли отсутствие переупорядочения записей между двумя моментами времени, разделёнными fsync() ?

Иными словами:


int f = open(...);

// пускай физические операции записи всех секторов, составляющие запись этих 100МБ, будут переупорядочены
write(f, buff, 1024*1024*100);

fsync();

// делаем запись не жирнее 1 сектора, чтобы в ней самой нечего было переупорядочивать
write(f, buff2, 4096);

// есть тут fsync() или нет - пофиг.
//fsync();
close();

Можно ли утверждать, что если после вышеприведённого кода я вижу на диске buff2 в том месте куда его записывали, то значит все 100MB buff точно дошли до диска? (при условии абсолютной исправности диска, дров, кода ядра).

Если нет, то почему. Напоминаю: вопрос не на тему гарантий записи, а на тему барьера.

Есть же man, ну:

ОПИСАНИЕ
       Вызов  fsync()  пересылает  («сбрасывает»)  все  изменённые  в  памяти (in-core) данные (т.е., изменённые страницы буферного кэша) файла, на который указывает
       файловый дескриптор fd, на дисковое устройство (или другое устройство постоянного хранения) таким образом, что вся изменённая информация может  быть  получена
       даже  после падения системы или внезапной перезагрузки. При этом выполняется непосредственная запись или сброс дискового кэша (если он есть).Вызов блокируется
       до тех пор, пока устройство не сообщит, что пересылка завершена. Он также сбрасывает информацию о метаданных, связанную с файлом (см. stat(2)).

       Вызов fsync() необязательно приводит к тому, что элемент каталога, содержащий файл, также будет сброшен на диск. Для этого нужно явно  выполнить  fsync()  для
       файлового дескриптора каталога.

joy4eg ★★★★★ ()
Ответ на: комментарий от joy4eg

за что я люблю линуксовые маны, так это за точность и строгость изложения :)

посикс считает вот так:

The fsync() function shall request that all data for the open file descriptor named by fildes is to be transferred to the storage device associated with the file described by fildes. The nature of the transfer is implementation-defined.

anonymous ()

Господа, вопроса о том является ли fsync() какой-либо гарантией доставки данных до диска не было. Вопрос был в том, является ли он гарантией вышеописанного барьера?

hlamotron ()

Ну вот вроде эти треды проясняют ситуацию:

* write and fsync «В Linux при записи на ФС, расположенную на локальном диске, на время write() процесс находится в uninterruptable состоянии и его нельзя „убить“, а после write() данные находятся в дисковом кеше, и ядро при всем желании не может связать их с процессом, производившим write(), то есть не может очистить их по „Segmentation fault“.»

* https://stackoverflow.com/questions/10371017/fsync-vs-write-system-call?answe...

fprintf (myFileHandle, "something\n");  // output it
fflush (myFileHandle);                  // flush to OS
fsync (fileno (myFileHandle));          // flush to disk

cast mky

Mirage1_ ()
Ответ на: комментарий от hlamotron

в си каждый sequence point является барьером. так что ответ очевиден: да. но область его действия — адресное пространство программы. ядро (в виде файловой системы и дискового драйвера) клало на него с прибором.

anonymous ()
Ответ на: комментарий от anonymous

в си каждый sequence point

Си и sequence point, а также барьеры памяти тут ни при чём.

hlamotron ()
Ответ на: комментарий от anonymous

posix то же самое описывает. А по сети будет контент сливаться или через южный мост на флоппик - пофигу.

dzidzitop ★★ ()

Три раза перечитал, но так и не понял, что именно подразумевается под «я вижу на диске buff2» — чтение диска в обход файловой системы, чтение диска в обход ядра, чтение поверхности диска неведомо чем в обход его электоники.

Вот гуглится кусочек инфы http://milek.blogspot.ru/2010/12/linux-osync-and-write-barriers.html с почившего кернелтрапа. Там показано, что далеко не каждый fsync на ext3 раньше вызывал дисковую операцию. И даже гуглится идея делать chmod() на файл перед fsync(), чтобы точно сбрасывался кеш записи диска.

В общем, точно, что fsync() пропихивает данные поближе к повехности диска, вызывается ли при этом команда сброса дискового кеша записи мне точно не известно, но вроде как не факт, и похоже это ещё может зависить от файловой системы.

mky ★★★★★ ()

Является, но только если не используются ССЗБ опции монтирования файловой системы типа nobarrier.

Reset ★★★★★ ()

Можно ли утверждать, что если после вышеприведённого кода я вижу на диске buff2 в том месте куда его записывали, то значит все 100MB buff точно дошли до диска?

А как может быть по другому? У тебя write 4096 в коде идёт _после_ fsync, следовательно всё что до fsync уже записано на диск иначе fsync не завершился бы и выполнение до write 4096 бы не дошло.

anonymous ()
Ответ на: комментарий от joy4eg

Вызов fsync() необязательно приводит к тому, что элемент каталога, содержащий файл, также будет сброшен на диск. Для этого нужно явно выполнить fsync() для файлового дескриптора каталога.

Хрень какая-то. Какое обновление каталога? В каталоге есть только номер инода и имя файла. Как это может менятся от write()? Более того, если мы будет делать fsync(fd_directory), то с чего оно будет его синхронизировать, если в fd_directory мы ничего не можем записать в принципе, даже открыть на запись не сможем.

vodz ★★★★★ ()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от anonymous

А как может быть по другому?

Может быть так: fsync() реализация в данной системе «оптимизированная», которая фактически ничего до диска не доводит, а кладёт всё в некий буфер, в котором всё может переупорядочиваться - всё что было ДО fsync и после него.

hlamotron ()
Ответ на: комментарий от hlamotron

Но ты же сам в вопросе написал:

(при условии абсолютной исправности диска, дров, кода ядра).

в таком случае не может быть никаких буферов.

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.