X-Git-Url: http://git.rot13.org/?p=BackupPC.git;a=blobdiff_plain;f=lib%2FBackupPC%2FPoolWrite.pm;h=23eb78853a13fb94aec3d6760453e81f9547dca8;hp=f7624ca7eb8e65f7cdc17389bb12e05a290870da;hb=27f513f89d885d24bf1a01242fba676c7a840fd5;hpb=ce708288691ba7dd95a8dac7a468bc0e4c1d6588 diff --git a/lib/BackupPC/PoolWrite.pm b/lib/BackupPC/PoolWrite.pm index f7624ca..23eb788 100644 --- a/lib/BackupPC/PoolWrite.pm +++ b/lib/BackupPC/PoolWrite.pm @@ -56,7 +56,7 @@ # #======================================================================== # -# Version 2.1.0beta0, released 20 Mar 2004. +# Version 3.0.0alpha, released 23 Jan 2006. # # See http://backuppc.sourceforge.net. # @@ -98,8 +98,8 @@ sub new return $self; } -my $BufSize = 1048576; # 1MB or 2^20 -my $MaxFiles = 20; +my $BufSize = 1048576; # 1MB or 2^20 +my $MaxFiles = 20; # max number of compare files open at one time sub write { @@ -119,6 +119,8 @@ sub write # if ( !defined($dataRef) && !defined($a->{digest}) && $a->{fileSize} != length($a->{data}) ) { + #my $newSize = length($a->{data}); + #print("Fixing file size from $a->{fileSize} to $newSize\n"); $a->{fileSize} = length($a->{data}); } @@ -310,6 +312,7 @@ sub write push(@{$a->{errors}}, "Can't rename $a->{fileName} -> $fileName" . " or open during size fixup\n"); } + #print("Using temporary name $fileName\n"); } elsif ( defined($a->{files}) && defined($a->{files}[0]) ) { # # We haven't written anything yet, so just use the @@ -317,6 +320,7 @@ sub write # $fh = $a->{files}[0]->{fh}; $fh->rewind; + #print("Using compare file $a->{files}[0]->{name}\n"); } if ( defined($fh) ) { my $poolWrite = BackupPC::PoolWrite->new($a->{bpc}, $a->{fileName}, @@ -490,4 +494,53 @@ sub filePartialCompare return 1; } +# +# LinkOrCopy() does a hardlink from oldFile to newFile. +# +# If that fails (because there are too many links on oldFile) +# then oldFile is copied to newFile, and the pool stats are +# returned to be added to the new file list. That allows +# BackupPC_link to try again, and to create a new pool file +# if necessary. +# +sub LinkOrCopy +{ + my($bpc, $oldFile, $oldFileComp, $newFile, $newFileComp) = @_; + my($nRead, $data); + + unlink($newFile) if ( -f $newFile ); + # + # Try to link if hardlink limit is ok, and compression types + # are the same + # + return (1, undef) if ( (stat($oldFile))[3] < $bpc->{Conf}{HardLinkMax} + && !$oldFileComp == !$newFileComp + && link($oldFile, $newFile) ); + # + # There are too many links on oldFile, or compression + # type if different, so now we have to copy it. + # + # We need to compute the file size, which is expensive + # since we need to read the file twice. That's probably + # ok since the hardlink limit is rarely hit. + # + my $readFd = BackupPC::FileZIO->open($oldFile, 0, $oldFileComp); + if ( !defined($readFd) ) { + return (0, undef, undef, undef, ["LinkOrCopy: can't open $oldFile"]); + } + while ( $readFd->read(\$data, $BufSize) > 0 ) { + $nRead += length($data); + } + $readFd->rewind(); + + my $poolWrite = BackupPC::PoolWrite->new($bpc, $newFile, + $nRead, $newFileComp); + while ( $readFd->read(\$data, $BufSize) > 0 ) { + $poolWrite->write(\$data); + } + my($exists, $digest, $outSize, $errs) = $poolWrite->close; + + return ($exists, $digest, $nRead, $outSize, $errs); +} + 1;