| Store | Cart

RE: NTFS hard file links

From: Jan Dubois <j...@activestate.com>
Tue, 22 Feb 2011 13:44:32 -0800
On Tue, 22 Feb 2011, Brian H. Oak wrote:
> > Your builtin link() is a godsend!  If only I'd known years ago....  I> could have saved a lot of heartache trying to kludge> Win32::API::Prototype into working in my programs.

Looks like I added support for it in 1999:

    http://perl5.git.perl.org/perl.git/commitdiff/6b980173

> I did a lot of testing of link() over this last weekend, and got mixed> results.  Here's my test environment:> > \FolderA\LinkTest.txt          Original file> \FolderA\FolderB\LnkdFil1.txt  First hardlink> \FolderA\LnkdFil2.txt          Second hardlink> > I create a straight copy of an original text file in FolderA, naming> it "LinkTest.txt".  I create a hardlink to "LinkTest.txt" in FolderB,> naming it "LnkdFil1.txt".  I test that it is an actual hardlink by> opening and editing both files; changes to either file show up in the> other when opened.  So far, so good.> > But then I create another hardlink to "LinkTest.txt" in FolderA (same> folder as "LinkTest.txt" this time), naming it "LnkdFil2.txt".  Now I> should have a total of three filesystem hardlinks pointing to the> single original file on disk, right?

Yes
 
> I unlink the original "LinkTest.txt", and that should leave me with> two remaining links to the same file on disk (since NTFS uses link> counting, in much the same way as Perl employs reference counting).> But testing demonstrates that I now have two separate files on disk --> each with a single link to it -- rather than two links to the same file.

I cannot reproduce this.  How did you check for it?

Here is a crude script that works for me:

#!perl
use strict;
use warnings;

my $tmp = "C:\\tmp";

system("rd/s/q $tmp\\lntest");
system("del $tmp\\lntest.txt $tmp\\link.txt");

system("echo foo > $tmp\\lntest.txt");

mkdir("$tmp\\lntest") or die;
link("$tmp\\lntest.txt", "$tmp\\lntest\\link.txt") or die;
link("$tmp\\lntest\\link.txt", "$tmp\\link.txt") or die;

system("echo bar >> $tmp\\lntest.txt");
system("type $tmp\\link.txt");

unlink("$tmp\\lntest.txt") or die;
system("echo baz >> $tmp\\lntest\\link.txt");
system("type $tmp\\link.txt");
__END__

c:\tmp>perl lntest.pl 
foo 
bar 
foo 
bar 
baz

So *after* I deleted C:\tmp\lntest.txt I appened to C:\tmp\lntest\link.txt
and the appended text shows up in the C:\tmp\link.txt link, proving that
the remaining link has not been broken by the first unlink().

I suspect that you are doing some operation that is not updating a file,
but deleting and re-creating it.  This will always break hard links.

> Do I have a bad understanding of the concepts, of how hardlinks are> supposed to work?  Am I doing something wrong, or in the wrong order?> Or is there some deficiency in the implementation of Windows hardlinks> through link()?

link() will just invoke CreateHardLinkW() under the covers, so you should
see exactly the same effect with your Win32::API based implementation.

> One final question: since symlinks were enabled in NTFS.sys v6.0> (Windows Vista) and above, is there any possibility that the builtin> symlink() function can be made to silently Do the Right Thing on> recent versions of Windows?

Yes, there is, but I'm not sure it can still be done in time for
Perl 5.14.  There is just one more 5.13.11 dev release planned for
March, and then 5.14 should come out in April/May, and new features
may no longer be allowed into the tree (besides I don't think I have
time to do this right away anyways).

Cheers,
-Jan


_______________________________________________
Perl-Win32-Users mailing list
Perl...@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Recent Messages in this Thread
Brian H. Oak Feb 18, 2011 05:05 am
Jan Dubois Feb 18, 2011 07:50 am
Angelos Karageorgiou Feb 18, 2011 09:06 am
Brian H. Oak Feb 22, 2011 08:53 pm
Jan Dubois Feb 22, 2011 09:44 pm
Brian H. Oak Feb 23, 2011 05:55 am
Messages in this thread