Weekly Padgett

No. 0371 min read

Atomic rename. Read the damned small print.

Unix rename can publish a finished file or claim a queue item. Durability, replacement, NFS, and mounts still get a vote, folks.

A person wearing a bathrobe holds a fish above an open filing cabinet drawer in an office.
File photoDramatization. No unix was harmed.

You can avoid a pleasing amount of machinery by moving a filename. There's some small print I'd want to read before getting carried away with it.

The rename(2) manual[1]Ref. 1rename(2) manual man7.org says replacing an existing destination is atomic. Another process accessing that destination doesn't encounter an intermediate missing pathname.

But you have to finish writing before you rename it. Keep appending afterward and readers can see incomplete content through the final name. Rename doesn't freeze the inode[2]Ref. 2inode en.wikipedia.org, and it certainly doesn't read your payload and decide whether you did a good job. That would be a considerably larger syscall.

I'd create a unique temporary file right in the destination directory, with restrictive permissions from the start. Write it, check every operation, set the intended final metadata, then replace the destination. Staging alongside the destination also keeps me from accidentally putting the temporary file on a different filesystem.

Atomic visibility tells you what another reader can observe while the system is running. I'd still need to check durability to know what survives power loss, however beautiful the filename looks right now.

For a Linux[3]Ref. 3Linux kernel.org local-filesystem publication pattern requiring crash persistence, the usual sequence includes syncing the completed temporary file and renaming it. Then comes syncing the containing directory. The entry is part of what you're trying to preserve. The fsync(2) manual[4]Ref. 4fsync(2) manual man7.org explicitly distinguishes syncing a file from syncing its directory.

If a sync fails, I don't want success printed just because I can still see the filename. No shit, it's there now. The filesystem and storage have to support whatever durability claim we're making. I'd rather deal with the inconvenient error while it's in front of me.

References

  1. rename(2) manual man7.org ↩
  2. inode en.wikipedia.org ↩
  3. Linux kernel.org ↩
  4. fsync(2) manual man7.org ↩
unixfilesystemsconcurrencyoperations

More on this beat