Comment 156 for bug 317781

Revision history for this message
Olaf van der Spek (olafvdspek) wrote :

@Theodore Ts'o

> 3.a) open and read file ~/.kde/foo/bar/baz
> 3.b) fd = open("~/.kde/foo/bar/baz.new", O_WRONLY|O_TRUNC|O_CREAT)
> 3.c) write(fd, buf-of-new-contents-of-file, size-of-new-contents-of-file)
> 3.d) fsync(fd) --- and check the error return from the fsync
> 3.e) close(fd)
> 3.f) rename("~/.kde/foo/bar/baz", "~/.kde/foo/bar/baz~") --- this is optional
> 3.g) rename("~/.kde/foo/bar/baz.new", "~/.kde/foo/bar/baz")

> (3) is the ***only*** thing which is guaranteed not to lose data.

But it's not right either.
It assumes you have permission to write the .new file.
It assumes this file doesn't exist already (or can be overwritten).
It uses an fsync, which may not be required (if atomicity but no durability is desired).
It doesn't retain permissions of the old file.
If the target is a symlink, it gets replaced by a normal file.
If you do 3.f, there is a window where no file exists at all.
It's too complex, so needs to be wrapped in library funtions.

I think a concept like atomic updates (O_ATOMIC?) is needed. This would guarantee other apps and the disk (after a crash) either see the old file or the new file, but nothing else.