Create backup file when writing new xml file?

Linus Torvalds torvalds at linux-foundation.org
Mon Feb 17 15:09:58 UTC 2014


On Mon, Feb 17, 2014 at 2:54 PM, Thiago Macieira <thiago at 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


More information about the subsurface mailing list