- various fixes to configure.pl and lib/BackupPC/Lib.pm
[BackupPC.git] / lib / BackupPC / PoolWrite.pm
index f7624ca..23eb788 100644 (file)
@@ -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;