Subject: bug#10686: mv: moving hardlink of a softlink to the softlink does nothing

From: Eric Blake <[email-masked]>
Date: Sat, 11 Feb 2012 05:43:15 -0700

On 02/11/2012 04:23 AM, Jim Meyering wrote:
> +++ b/NEWS
> @@ -11,6 +11,11 @@ GNU coreutils NEWS                                    -*- outline -*-
>    referent, there is no risk of data loss, since the symlink will
>    typically still point to one of the hard links.
> 
> +  "mv A B" could succeed, yet A would remain.  This would happen only when
> +  both A and B were hard links to the same symlink, and with a kernel for
> +  which rename("A","B") would do nothing and return 0.  Now, in this
> +  unusual case, mv does not call rename, and instead simply unlinks A.

You make it sound like a kernel where rename("A","B") returns 0 is
unusual; on the contrary, that is normal, since it is the POSIX-mandated
behavior for kernels.  What is unusual is having two hardlinks to the
same symlink.  Maybe we should reword this slightly, to attach the
"unusual" modifier to the correct phrase, or even take "kernel" out of
the description:

"mv A B" could succeed, yet A would remain.  This would only happen
in the unusual case when both A and B were hard links to the same
symlink, due to the standard behavior of rename.  Now, mv recognizes
the case and simply unlinks A.

> +++ b/tests/mv/symlink-onto-hardlink-to-self
> @@ -0,0 +1,56 @@
> +#!/bin/sh
> +# Demonstrate that when moving a symlink onto a hardlink-to-that-symlink, the
> +# source symlink is removed.  Depending on your kernel (e.g., with the linux
> +# kernel), prior to coreutils-8.16, the mv would successfully perform a no-op.

Again, this is the POSIX-required behavior of ALL kernels, and not
something special to Linux.

-- 
Eric Blake   [email-masked]    +1-919-301-3266
Libvirt virtualization library http://libvirt.org