4 ms·
If you're generating an immutable file, a common technique is to play fsync + rename tricks although I think a more modern technique would be: 1. open dire
by vlovich123 3y ago
If you're generating an immutable file, a common technique is to play fsync + rename tricks although I think a more modern technique would be:
1. open directory (dir_fd)
2. create an unnamed O_TMPFILE file (file_fd)
3. write to file_fd
4. fdatasync(file_fd)
5. linkat(dir_fd, "", dir_fd, "file name", AT_EMPTY_PATH)
5. fsync(dir_fd)
This should guarantee that either "file name" will have the old contents or the new contents and no transient version is observed. The "old" mechanism is similar in that you write out to a temporary sibling and rename (these days you'd use RENAME_EXCHANGE w/ renameat2 to guarantee the atomicity or get an error) with the differentiating difference being that the temporary data could be observed on the filesystem / left around if you have a machine reboot.
- vlovich123 3y agoCorrection to typo: 5. linkat(file_fd, "", dir_fd, "file name", AT_EMPTY_PATH)
- pradn 3y agoThank you - it's baffling to me that something as basic as saving some data to a file has become so convoluted!
- vlovich123 3y agoIt was always this convoluted because the POSIX APIs suck and the Linux kernel still refuses to provide an API to write large amounts of data transactionally so you have to know the magic incantation for doing it. And note this is when you have all the data up-front. Doing an append is significantly expensive or requires specific filesystem support for reflinks.