LINUX.ORG.RU

Как производится запись при помощи системного вызова write

 


0

2

Добрый день, правильно ли я понимаю, что при вызове системного вызова write,данные из программы сперва попадают в такую структуру как буфер операционной системы, а потом в буфер блочного устройства (например hdd), потом возможно в кэш этого диска и только потом уже на диск. Сам write возвращает кол-во байт записанных именно в буфер ОС? Затем по flush этот буфер сбрасывается на устройство. Мне непонятно, после какого вызова я могу быть твердо уверен, что данные записаны не в буфер HDD, а непосредственно на сам HDD. Да и в общем хотел уточнить правильно ли я понимаю процесс записи или где про это можно почитать детально.


Мне непонятно, после какого вызова я могу быть твердо уверен, что данные записаны не в буфер HDD, а непосредственно на сам HDD.

Теоретически для этого сделан флаг O_DIRECT для функции open, но и с его помощью ты не всегда можешь быть уверен в 100% записи. Но, кажется, это максимум - что ты можешь добиться для обычной прикладной программы.

Atlant ★★★★★
()

а в общем практически правильно, если по точнее, то в начале идет буферизация языка программирования, далее буферизация используемого фреймворка, далее буферизация *libc, далее драйвера ядра-файловой системы, далее ядро-возможных оверлеев и т.д., далее ядро-поддержка блочного устройства, ядро-поддержка конкретного SATA/MD/LVM и т.д. далее уже буферы железа.

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

Это практически Ахилес и Черепаха. Мы никогда не сможем записать байты непосредственно на пластину. Так и будут они переходить из буфера верхнего уровня в буфер нижнего уровня, пока само течение времени не затихнет в вечности.

areful
()

никого не слушай…

Мне непонятно, после какого вызова я могу быть твердо уверен, что данные записаны не в буфер HDD, а непосредственно на сам HDD

man fsync

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

В общем мне кажется, я понимаю, что гарантий то прям записи в железку быть не может, и где-то использовали специальные жесткие диски с батарейкой, которые в случае обрыва по питанию, что-то там дописывали, но вот в очередной раз столкнулся и захотелось уж ОКОНЧАТЕЛЬНО РАЗОБРАТЬСЯ.

da17
() автор топика
Последнее исправление: da17 (всего исправлений: 1)

после какого вызова я могу быть твердо уверен, что данные записаны не в буфер HDD, а непосредственно на сам HDD

в теории после вызова fsync. Как правило этого хватает, но иногда если совсем хочется быть уверенным, стоит прочитать, правда прочитаешь из кеша.

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

Для «окончательно разобраться» используют fsync(). Если он реализован правильно, то есть возвращается только после физической записи на диск всех забуферизованных изменений в файловой системе, то он может считаться надёжной точкой невозврата.

Бывают неправильно реализованные fsync(), которые могут работать так же как write() - забуферизовать и сказать что мамой клянусь всё записалось, а на самом деле не записать. Например считается, что RAID-контроллер имеет своё питание и диски имеют своё питание и всё что попало в буфер RAID-контроллера - точно запишется, но потом. Тогда fsync() возвращается, а запись будет когда-то потом. Это пример «неправильного» fsunc() – на этом этапе надо разобраться какой у тебя, почитать какие-то спеки на систему, незнаю… Незнаю какой флаг и где в системе посмотреть, чтобы отличить нормальный fsync() от либерально-демократического.

У fsync() главное свойство - барьер - всё, что было write() после этого fsync() - оно запишется на диск точно позже, чем то, что было write() перед этим fsync(). Это ключевое средство упорядочения чего-то. Упорядочение - это важнейшая еболда в некоторых частях баз данных, без которых не получается гарантировать всю глубину глубин. Но нормальный fsync() должен вернуться только после того, как байтики физически контроллером диска/ssd будут на флешки/диски забодяжены все. Какие байтики - все, которые файловая система уже до этого момента успела отправить на запись.

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

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

lesopilorama
()
Последнее исправление: lesopilorama (всего исправлений: 5)