A.3. Fsync

A.3. Fsync

Считается, что функция fsync выполняет множество операций ввода и вывода, но это не всегда верно. Подробнее об этом можно прочитать в статье по адресу http://thunk.org/tytso/blog/2009/03/15/dont-fear-the-fsync/.
Firefox раньше обращался к библиотеке sqlite при нажатии на любую ссылку. В свою очередь sqlite вызывала fsync, что и служило причиной довольно длительной задержки в ext3 (до 30 секунд), если другой процесс в это время осуществлял копирование большого файла.
Но в других случаях, когда функция fsync не использовалась, возникали проблемы в ext4. Для сравнения, состояние памяти в ext3 сохранялось на диск каждые несколько секунд, в то время как в ext4 (в режиме laptop_mode) интервал значительно увеличивался и возрастал риск потери данных в случае неожиданного отключения компьютера. Эта проблема была исправлена в ext4, но все же стоит соблюдать осторожность при разработке приложений и использовании fsync.
Ниже приведен простой пример чтения и записи файла конфигурации, демонстрирующий создание резервной копии. В этом случае не исключен риск потери данных:
/* открытие и чтение файла ~/.kde/myconfig */
fd = open("./kde/myconfig", O_WRONLY|O_TRUNC|O_CREAT);
read(myconfig);
...
write(fd, bufferOfNewData, sizeof(bufferOfNewData));
close(fd);
Более оптимальный вариант будет выглядеть так:
open("/.kde/myconfig", O_WRONLY|O_TRUNC|O_CREAT);
read(myconfig);
...
fd = open("/.kde/myconfig.suffix", O_WRONLY|O_TRUNC|O_CREAT);
write(fd, bufferOfNewData, sizeof(bufferOfNewData));
fsync; /* paranoia - optional */
...
close(fd);
rename("/.kde/myconfig", "/.kde/myconfig~"); /* paranoia - optional */
rename("/.kde/myconfig.suffix", "/.kde/myconfig");