On Mon, Feb 17, 2014 at 2:54 PM, Thiago Macieira <thi...@macieira.org> wrote: > > Let me see if I understand: > 1) create temp file > 2) write data to it > 3) fsync > 4) link backup to backup^2 > 5) rename $ORIG to backup
No. You can't do (5) as a rename. You need to do it as a link(), because the orig file must always exist. And yes, that means "unlink" on the backup, and possibly a "rinse and repeat" if you race with somebody and the link() still returns EEXIST. But because you did the link() on the backup first, that means that you still do have *a* backup (even if you now have multiple possible names for the backup file). > 6) rename temp to $ORIG > 7) unlink backup^2 So with step 5 fixed, it should be safe, even if two different processes do it at the same time: you'll always have a backup file, and you'll always have an original file. Now, obviously, you do not know *which* of the two processes won the race, and the original file could be either version, and the backup file could be either a backup of the first process that created the new file *or* it could be a backup of the file as it was *before* either of the two processes. Now, there are better ways to guarantee safety, but they tend to be more restrictive. "git", for example, has its own way to guarantee that multiple creators cannot screw each other up, but it depends on the fact that the name of the file involved is uniquely determined by the contents of the file, so if you hit a race with two processes creating the same filename you don't care - you know they wrote the exact same thing. So you can ignore any preexisting files, and the final "tempfile to real file" can just use a "link()", and if it fails with EEXIST you're already done. You can also ignore some races on network filesystems for the same reason. But that really requires that you control the name of the destination file, which is not generally the case. Linus _______________________________________________ subsurface mailing list subsurface@hohndel.org http://lists.hohndel.org/cgi-bin/mailman/listinfo/subsurface