3 ms·
This doesn't work because the link() syscall fails if the target exists. You use a hardlink only for atomic creation of the initial data: write 'foo~'
by tomtomtom777 6y ago
This doesn't work because the link() syscall fails if the target exists.
You use a hardlink only for atomic creation of the initial data:
write 'foo~'
hardlink 'foo~' onto 'foo'
To atomically update you simply use rename:
read 'foo'
write 'foo~'
rename 'foo~' into 'foo'
I don't know what dan-robertson's claim is based on, but this surely is atomic even on a crash, as the filesystem will never be in a state where 'foo' contains only partially updated data. That would require some severe fs corruption.
- ynik 6y agoIt doesn't require severe FS corruption. In reality "write 'foo~'" just starts an asynchronous write; it's possible for rename to happen before that async write is complete. So in case of a system crash you might end up seeing partial data in 'foo'. fsync() may or may not protect against that depending on what system we're talking about.
- tomtomtom777 6y agoSure, you are still dependent on constraints to durability and atomicity of the filesystem write of the new data. But this is handled properly in most modern filesystems (ext3,ext4,zfs) by default (as data=ordered ensures data writes precede metadata writes). The point of rename() is to prevent a version to ever exist that mixes the old and the new version, which it always does, regardless of the filesystem.
- deleted 6y ago[deleted]