On 01/04/2012 02:00 PM, Jim Meyering wrote: >>> mv --backup=numbered is not atomic; it expands to two rename() syscalls, >>> between which the target doesn’t exist at all. >> >> Maybe we should fix that, to make mv --backup use link()/rename() rather >> than rename()/rename(), so that there is no window where the target >> doesn't exist. > > Note that we can use link/rename only some of the time. > E.g., the rename will always fail when they're on different partitions. It's a two-edged sword - POSIX _requires_ mv(1) to be atomic (no period where target does not exist) if no EXDEV would occur from rename(2), but does _not_ require atomicity otherwise. If rename(2) fails because you cross partitions, then you already _expect_ a window where the target is bogus, per the POSIX requirements on mv(1); so whether we rename()/creat() or link()/unlink()/creat(), the behavior is the same. Is it worth shaving off the extra syscall by using rename(target,target-backup) instead of link()/unlink() when we can detect a-priori that rename(source,target) would fail with EXDEV? Or should we _always_ favor link(target,target-backup), and only if the rename(source,target) fails do we fall back to unlink(target) followed by creating the file with the moved contents? Or do we go one step further, and guarantee atomicity even where POSIX does not require it in the EXDEV situation, by doing: link(target,target-backup) creat(temp) in dirname(target) copy source to temp rename(temp,target) Then again, that takes up more disk space when there is no target-backup created, so it seems like it might be worth providing that extra level of atomicity guarantees only via a command line option. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org