Thread (1 message) 1 message, 1 author, 2014-11-21

Re: RFC: renameat(): Add a RENAME_REMOVE flag to unlink hardlinks

From: Pádraig Brady <hidden>
Date: 2014-11-21 22:20:54
Also in: linux-fsdevel

On 21/11/14 21:29, Andy Lutomirski wrote:
On Fri, Nov 21, 2014 at 1:18 PM, Eric Blake [off-list ref] wrote:
quoted
On 11/21/2014 01:48 PM, Pádraig Brady wrote:
quoted
On 21/11/14 19:55, Andy Lutomirski wrote:
quoted
On Fri, Nov 21, 2014 at 10:39 AM, Pádraig Brady [off-list ref] wrote:
quoted
On 21/11/14 18:09, Andy Lutomirski wrote:
quoted
On Fri, Nov 21, 2014 at 6:17 AM, Pádraig Brady [off-list ref] wrote:
quoted
If 'a' and 'b' are hardlinks, then the command `mv a b & mv b a`
can result in both being removed as mv needs to emulate the
move with an unlink of the source file.  This can only be done
without races in the kernel and so mv was recently changed
to not allow this operation at all.  mv could safely reintroduce
this feature by leveraging a new flag for renameat() for which
an illustrative/untested patch is attached.
ISTM the issue is that rename(2) does nothing if the source and dest
are hardlinks to each other.  Is that intentional?  I don't see that
behavior as required in the POSIX rename docs.
Yes, POSIX unfortunately requires that behavior:

http://pubs.opengroup.org/onlinepubs/9699919799/functions/rename.html

"If the old argument and the new argument resolve to either the same
existing directory entry or different directory entries for the same
existing file, rename() shall return successfully and perform no other
action."
quoted
quoted
quoted
It's surprising and annoying that existing systems do this,
but they're conforming to the wording of POSIX I thinkg as
it says that rename() does nothing when the source and dest
_file_ is the same. What POSIX really meant I suppose was _file name_.
Eric, perhaps an adjustment could be proposed to POSIX, as I can't
see anything relying on the current behavior?
The POSIX wording describes existing practice of all implementations,
and as annoying as it is, requiring all implementations to change would
be too invasive, and going against that wording without the use of an
extension to renameat would catch software off-guard that is expecting
the baked-in POSIX semantics.

That said, would you still like me to take a stab at a proposal to the
POSIX folks that would relax the requirements to allow
implementation-defined behavior when the two arguments to rename
describe the same file but via different directory entries?
I guess there is no point discussing in POSIX and adding extra
implementation options if no implementations do/will act accordingly.

Linux can decide to do that independently, if appropriate.
This is one of those borderline cases where we balance
accretion of cruft vs incompatibility.
On consideration, I'm OK with keeping the existing
rename() behavior for compat and adding the new flag.
That said I still can't think of anything depending
rename() doing nothing with hardlinked source and dest.
quoted
Note that I
am NOT proposing a change to rename("a", "a") which must always succeed
(true even when two spellings are different but still resolve to the
same directory entry, as in rename("a", "./a")).  Rather, this is only a
question about the behavior of rename("a", "b") when they are two
different hardlinks resolving to the same file.

At any rate, regardless of what POSIX says, I'm totally in favor of a
renameat flag that gives us fine-tune control over the behavior; we can
implement it now as an extension, and once it hits mainline kernel, I
would have no problems proposing that flag for POSIX standardization
(the POSIX folks have a thing for preferring existing implementations,
after all)
+1
renameat has no flags -- this would be renameat2.  Standardizing that
might be quite nice (at least the RENAME_NOREPLACE part).

My two cents: the new flag could be RENAME_HARDLINKS.
+1

thanks guys!
Pádraig.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help