Subject: bug#14763: mv directory cross-filesystem where destination exists fails to remove dest with EISDIR

From: Eric Blake <[email-masked]>
Date: Mon, 01 Jul 2013 16:41:07 -0600

On 07/01/2013 04:34 PM, Eric Blake wrote:
>>> If the destination path exists, mv shall attempt to remove it. If this fails for any reason, mv shall write a diagnostic message to standard error, do nothing more with the current source_file, and go on to any remaining source_files.
> 
> Aha - we are attempting to remove it with unlink().  But for empty
> directories, we should be using rmdir(), or even better, we should be
> using remove() (which subsumes both unlink() and rmdir() at once).  I
> wonder if a simpler patch would be to just s/unlink/rmdir/ in the line
> of code where you were adding special-casing on errno values.

Then again, we DON'T want to replace a non-directory with a directory
(or vice-versa, we don't want to replace an empty directory with a
non-directory); so maybe it pays to be more careful about explicitly
using unlink() vs. rmdir() on the destination (and not the shortcut of
remove() which does not care about type), all based on what file type we
already know that the source is, so that we can give the same sorts of
failures as rename() would give on a local file system when attempting a
cross-file-type rename.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org