Try to be more intelligent in linking to old instances of the same file.
Especially recover from various errors (e.g. link count exvceeded) by creating a new file. Note: This code is extremely slow and should not be used. A reorganisation of the database layout is in progress.
This commit is contained in:
parent
87ab219c31
commit
066869e9c2
|
@ -455,19 +455,27 @@ sub get_last_session_id {
|
||||||
|
|
||||||
=head2 finddup
|
=head2 finddup
|
||||||
|
|
||||||
Find a duplicate of the current file in the database. This is useful if you
|
Try to find a duplicate of the current file in the database and replace the
|
||||||
|
current file with a hardlink to it. This is useful if you
|
||||||
have multiple copies of a file stored in different locations.
|
have multiple copies of a file stored in different locations.
|
||||||
|
The search starts from the newest session and continues into the past until
|
||||||
|
either linking successful or we run out of duplicates.
|
||||||
|
This is done because creating a hard link may not always be possible (duplicate is
|
||||||
|
on a different file system or has already reached the maximum link count)
|
||||||
|
and it is more likely that we can link to new copies than to old ones.
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
sub finddup {
|
sub linkdup {
|
||||||
my ($self, $f) = @_;
|
my ($self, $f, $backup_filename) = @_;
|
||||||
my $sth = $self->{dbh}->prepare("select * from versions, files, sessions
|
my $sth = $self->{dbh}->prepare("select * from versions, files, sessions
|
||||||
where file_type=? and file_size=? and file_mtime=?
|
where file_type=? and file_size=? and file_mtime=?
|
||||||
and file_owner=? and file_group=? and file_acl=?
|
and file_owner=? and file_group=? and file_acl=?
|
||||||
and file_unix_bits=?
|
and file_unix_bits=?
|
||||||
and checksum=? and online=1
|
and checksum=? and online=1
|
||||||
and versions.file=files.id and versions.session=sessions.id");
|
and versions.file=files.id and versions.session=sessions.id
|
||||||
|
order by sessions.id desc
|
||||||
|
");
|
||||||
$sth->execute(
|
$sth->execute(
|
||||||
$f->{t}, $f->{s}, $f->{m},
|
$f->{t}, $f->{s}, $f->{m},
|
||||||
$f->{o}, $f->{g}, $f->{acl},
|
$f->{o}, $f->{g}, $f->{acl},
|
||||||
|
@ -483,8 +491,16 @@ sub finddup {
|
||||||
$st->gid == $self->name2gid($f->{g}) &&
|
$st->gid == $self->name2gid($f->{g}) &&
|
||||||
($st->mode & 07777) == $self->acl2mode($f)
|
($st->mode & 07777) == $self->acl2mode($f)
|
||||||
) {
|
) {
|
||||||
|
rename($backup_filename, "$backup_filename.$$.simba_backup") or die "cannot save $backup_filename to $backup_filename.$$.simba_backup: $!";
|
||||||
|
if (link($oldfile, $backup_filename)) {
|
||||||
|
$self->log(10, "linked (dup)");
|
||||||
|
unlink("$backup_filename.$$.simba_backup") or die "cannot unlink $backup_filename.$$.simba_backup: $!";
|
||||||
$sth->finish();
|
$sth->finish();
|
||||||
return $oldfile;
|
return $oldfile;
|
||||||
|
} else {
|
||||||
|
$self->log(5, "cannot link $oldfile to $backup_filename");
|
||||||
|
rename("$backup_filename.$$.simba_backup", $backup_filename) or die "cannot restore $backup_filename from $backup_filename.$$.simba_backup: $!";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -505,9 +521,13 @@ sub store_file {
|
||||||
my ($self, $f) = @_;
|
my ($self, $f) = @_;
|
||||||
|
|
||||||
if($self->present($f)) {
|
if($self->present($f)) {
|
||||||
link("$self->{last_backup}/$f->{name}", "$self->{this_backup}/$f->{name}") or die; # XXX
|
if (link("$self->{last_backup}/$f->{name}", "$self->{this_backup}/$f->{name}")) {
|
||||||
$self->log(10, "linked");
|
$self->log(10, "linked");
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
$self->log(5, "cannot link $self->{last_backup}/$f->{name} to $self->{this_backup}/$f->{name}: $!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# else request from da
|
# else request from da
|
||||||
unless ($self->{file_pid}) {
|
unless ($self->{file_pid}) {
|
||||||
|
@ -557,19 +577,13 @@ sub store_file {
|
||||||
} else {
|
} else {
|
||||||
$self->log(5, "unexpected trailer $trailer\n");
|
$self->log(5, "unexpected trailer $trailer\n");
|
||||||
}
|
}
|
||||||
my $oldfile = $self->finddup($f);
|
unless ($self->linkdup($f, $backup_filename)) {
|
||||||
if ($oldfile) {
|
|
||||||
unlink($backup_filename) or die "cannot unlink $backup_filename: $!";
|
|
||||||
link($oldfile, $backup_filename) or die "cannot link $oldfile to $backup_filename: $!";
|
|
||||||
$self->log(10, "linked (dup)");
|
|
||||||
} else {
|
|
||||||
$self->setmeta($f);
|
$self->setmeta($f);
|
||||||
$self->log(10, "stored");
|
$self->log(10, "stored");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$self->log(5, "unexpected header $header\n");
|
$self->log(5, "unexpected header $header\n");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub DESTROY {
|
sub DESTROY {
|
||||||
|
|
Loading…
Reference in New Issue