[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#6960: mv refuses to move a symlink over a hard link to the same file
From: |
Jim Meyering |
Subject: |
bug#6960: mv refuses to move a symlink over a hard link to the same file |
Date: |
Mon, 30 Jan 2012 12:41:16 +0100 |
Pádraig Brady wrote:
> On 01/29/2012 09:33 PM, Jim Meyering wrote:
>
>> diff --git a/src/copy.c b/src/copy.c
>> index 51f51be..af79ed3 100644
>> --- a/src/copy.c
>> +++ b/src/copy.c
>> @@ -34,6 +34,7 @@
>> #include "acl.h"
>> #include "backupfile.h"
>> #include "buffer-lcm.h"
>> +#include "canonicalize.h"
>> #include "copy.h"
>> #include "cp-hash.h"
>> #include "extent-scan.h"
>> @@ -1349,6 +1350,38 @@ same_file_ok (char const *src_name, struct stat const
>> *src_sb,
>> }
>> }
>>
>> + /* At this point, it is normally an error (data loss) to move a symlink
>> + onto its referent, but in at least one narrow case, it is not:
>> + In move mode, when
>> + src is a symlink,
>> + dest is not a symlink,
>> + dest has a link count of 2 or more and
>> + dest and the referent of src are not the same entry,
>> + then it's ok, since while we'll lose one of those hard links,
>> + src will still point to a remaining link.
>> +
>> + Given this,
>> + $ touch f && ln f l && ln -s f s
>> + $ ls -og f l s
>> + -rw-------. 2 0 Jan 4 22:46 f
>> + -rw-------. 2 0 Jan 4 22:46 l
>> + lrwxrwxrwx. 1 1 Jan 4 22:46 s -> f
>> + this must fail: mv s f
>> + this must succeed: mv s l */
>> + if (x->move_mode
>> + && S_ISLNK (src_sb->st_mode)
>> + && ! S_ISLNK (dst_sb->st_mode)
>> + && 1 < dst_sb_link->st_nlink)
>> + {
>> + char *abs_src = canonicalize_file_name (src_name);
>> + if (abs_src)
>> + {
>> + bool result = ! same_name (abs_src, dst_name);
>> + free (abs_src);
>> + return result;
>> + }
>> + }
>
> Well the logic follows the description at least.
> I was going to say the nlink test was redundant,
> but it's a bit clearer with that left, and also
> it's a performance improvement in the nlink=1 case.
That's a good point.
I've added it:
/* At this point, it is normally an error (data loss) to move a symlink
onto its referent, but in at least one narrow case, it is not:
In move mode, when
1) src is a symlink,
2) dest is not a symlink,
3) dest has a link count of 2 or more and
4) dest and the referent of src are not the same entry,
then it's ok, since while we'll lose one of those hard links,
src will still point to a remaining link.
Note that technically, condition #4 obviates condition #2, but we
retain the 1 < st_nlink condition because that means fewer invocations
of the more expensive #4.
...
- bug#6960: mv refuses to move a symlink over a hard link to the same file, (continued)
- bug#6960: mv refuses to move a symlink over a hard link to the same file, Jim Meyering, 2012/01/04
- bug#6960: mv refuses to move a symlink over a hard link to the same file, Paul Eggert, 2012/01/04
- bug#6960: mv refuses to move a symlink over a hard link to the same file, Jim Meyering, 2012/01/29
- bug#6960: mv refuses to move a symlink over a hard link to the same file, Pádraig Brady, 2012/01/29
- bug#6960: mv refuses to move a symlink over a hard link to the same file, Jim Meyering, 2012/01/30
- bug#6960: mv refuses to move a symlink over a hard link to the same file,
Jim Meyering <=
- bug#6960: mv refuses to move a symlink over a hard link to the same file, Paul Eggert, 2012/01/30
- bug#6960: mv refuses to move a symlink over a hard link to the same file, Jim Meyering, 2012/01/30
- bug#6960: mv refuses to move a symlink over a hard link to the same file, Jim Meyering, 2012/01/31