Uwe Kleine-König
Uwe Kleine-König

Reputation: 3575

Atomically change attributes of a file

I want to atomically change some attributes of a file. (Background: This is for a userspace NFS implementation where the SETATTR call sets several attributes on a file).

The problem I fail to solve is to make the update in an atomic way. That is, a different process that stat()s or rename()s the file should not see partially updated attributes.

Different simplified (i.e. no error checking and symlink handling) approaches with their downsides are:

Am I missing something or isn't there an approach that does what I want?

Upvotes: 4

Views: 765

Answers (3)

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136286

That is, a different process that stat()s or rename()s the file should not see partially updated attributes.

If the file already exists there is little you can do to stop another process from accessing it before you modify it. That ship has sailed.


rename is atomic.

The standard solution has been:

  1. Create a file with a unique temporary name in the destination directory. It must be in the same directory to make sure it is in the filesystem/same-mount point, so that no file content (inode) copy is required.
  2. Populate the file. If the file is written using buffered I/O (anything else than write, pwrite, writev or other syscalls) it needs to be flushed or closed (which causes a flush, which ends up doing one of the above syscalls).
  3. Set correct permissions and attributes, if necessary. The permissions can be set when creating the file.
  4. rename the file to its final filename. rename essentially atomically creates a new filename (hardlink) to the file content (inode) and removes the old filename.

This way when the file exists it is complete and has correct permissions and attributes.

Upvotes: 2

Marco Bonelli
Marco Bonelli

Reputation: 69346

Unfortunately this is not possible without writing your own custom syscall or kernel module for it.

While the Linux kernel itself definitely has the ability to make this happen, it doesn't expose any userspace API for it. This task would require either a single syscall that sets all the attributes at once, or some kind of "locking" mechanism to prevent files from being accessed (that is, open/stat) by other processes even if they have the rights to do so. Since Linux does not provide such a syscall, nor such a "locking" mechanism, what you want to achieve is not possible from userspace.

Upvotes: 1

Goswin von Brederlow
Goswin von Brederlow

Reputation: 12332

You can't and none of the examples you've shown is atomic. There is always a chance some other thread accesses the file between the chown and chmod or chmod and utimes call.

Under Linux there is the concept of a filesystem handle (as opposed to a file descriptor) for such cases as a userspace NFS server. Only thing I can find in google at the moment is the manpage from xfsprogs: handle manpage. But I think this has been generalized in Linux in recent years to work with more filesystems.

Upvotes: 0

Related Questions