Exchanging two files
The problem Miklos is trying to solve is the problem of exchanging two files — both files continue to exist, but their names have been swapped. To achieve this, he has posted a patch set adding a new renameat2() system call:
int renameat2(int olddir, const char *oldname, int newdir, const char *newname, unsigned int flags);
This system call differs from renameat() in that it has the new flags argument; if flags is zero, renameat2() behaves exactly as renameat(). If, instead, flags contains RENAME_EXCHANGE, an existing file at newname will not be deleted; instead, it will be renamed to oldname. Thus, with this flag, renameat2() can be used to atomically exchange two files. The main use case for renameat2() is to support union filesystems, where it is often desirable to atomically replace files or directories with "whiteouts" indicating that they have been deleted. One could imagine other possibilities as well; Miklos suggests atomically replacing a directory with a symbolic link as one of them.
No review comments have been posted as of this writing.
Index entries for this article | |
---|---|
Kernel | renameat2() |
Posted Oct 3, 2013 14:44 UTC (Thu)
by rvfh (guest, #31018)
[Link] (7 responses)
Posted Oct 3, 2013 17:34 UTC (Thu)
by rwmj (subscriber, #5474)
[Link] (6 responses)
This has been going on for a very long time, eg: dup & dup2 (dup2, I am told, first appeared in Unix v7 so that would be 1979).
Posted Oct 3, 2013 21:33 UTC (Thu)
by khim (subscriber, #9252)
[Link] (5 responses)
Posted Oct 4, 2013 10:36 UTC (Fri)
by nix (subscriber, #2304)
[Link] (4 responses)
i.e., this was a kludge workaround for C not supporting C++ function overloading, not a way for people to not bother to think up good names for their syscalls. (That way like Microsoft's OpenEx2() horrors.)
(I started writing a comment much like the original one, but it seemed uncharitable because I couldn't think of a better name myself. renameat_with_flags(), bleah, no. frenameat(), no. renameat+(), not a valid C identifier and people would shoot me and they'd be right.)
Posted Oct 4, 2013 11:03 UTC (Fri)
by dlang (guest, #313)
[Link]
some people use the number to indicate the number of parameters, some people use it as a generation number
I suspect some of it is just the personality of the people involved, but that some of it may also be how much they expect the new version to completely replace the old version (as opposed to both versions being used for writing new software)
Posted Oct 4, 2013 23:57 UTC (Fri)
by giraffedata (guest, #1954)
[Link] (2 responses)
I think the proper naming would be to keep renameat for renaming and add exchangeat for exchanging.
Posted Oct 7, 2013 21:04 UTC (Mon)
by nix (subscriber, #2304)
[Link]
Posted Jun 9, 2014 12:25 UTC (Mon)
by roblucid (guest, #48964)
[Link]
0 - same as renameat() behaviour
So it's a modal renameat(2).
Posted Oct 3, 2013 14:59 UTC (Thu)
by Seegras (guest, #20463)
[Link] (3 responses)
Now I can move incoming to archive-20130309 and create a new incoming in one go; while files are incoming ;).
Posted Oct 3, 2013 20:33 UTC (Thu)
by epa (subscriber, #39769)
[Link] (2 responses)
Posted Oct 3, 2013 22:04 UTC (Thu)
by khim (subscriber, #9252)
[Link] (1 responses)
Posted Oct 4, 2013 2:17 UTC (Fri)
by mathstuf (subscriber, #69389)
[Link]
Posted Oct 3, 2013 18:21 UTC (Thu)
by Yorick (guest, #19241)
[Link] (2 responses)
It's almost like the old MacOS function FspExchangeFiles, except that the latter only swapped the data, not the file identities or metadata. Keeping the creation date, permissions and so on is quite useful, but clearly not what renameat2 is about.
I'm curious to know what happens if two processes try to swap the same files simultaneously. Will they both fail (nothing happens), both succeed (same), or one succeed (accomplishing the task for either, but arbitrarily signalling a failure to one of them)?
Posted Oct 4, 2013 12:37 UTC (Fri)
by fishface60 (subscriber, #88700)
[Link] (1 responses)
Posted Oct 6, 2013 8:29 UTC (Sun)
by jzbiciak (guest, #5246)
[Link]
If they were both doing swap(a, b) then yes I'd expect the outcome to be a double-swap, leaving a and b in their original state. A perhaps more interesting thought experiment is if one process tries to do swap(a, b) in a race with another process trying to do swap(a, c). You get two possible outcomes:
and I can't immediately think of why this might be useful, but it could certainly lead to some head scratching.
Posted Oct 4, 2013 7:42 UTC (Fri)
by hansl (subscriber, #5086)
[Link]
A complication is that the original directory must be empty, and checking that with a separate call reintroduces a race condition. So renameat2 would need to gain a flag saying that it must fail if oldname is a non-emtpy directory.
Exchanging two files
Exchanging two files
Well, Exchanging two files
dup
has one argument, dup2
has two and dup3
has three thus I've always thought about this number as about number of arguments.
Exchanging two files
Exchanging two files
I think the reason you can't think of a better name for renameat2 is that it does two barely related things. This would be an abuse of C++ function overloading if that were an option.
Exchanging two files
Exchanging two files
Exchanging two files
RENAME_NOREPLACE - avoids overwriting
RENAME_EXCHANGE - atomic exchange
Exchanging two files
Exchanging two files
AFAICS mv(1) does not have any options which can actually be used for this behavior. Perhaps they could be added in the future, but as it is now it just changes the name of file, it can not swap two filenames!
Exchanging two files
Exchanging two files
Exchanging two files
Exchanging two files
Exchanging two files
// swap(a,b) happens before swap(a,c). a', b', and c' are the new files
a' = c
b' = a
c' = b
// swap(a,c) happens before swap(a,b). a', b', and c' are the new files
a' = b
b' = c
c' = a
Exchanging two files