mirror of https://github.com/digint/btrbk
btrbk: replace url_cache by spec_cache
parent
0ea0430c43
commit
e9374b3b1d
106
btrbk
106
btrbk
|
@ -254,9 +254,9 @@ my %raw_info_sort = (
|
|||
# kdf_* (generated by kdf_backend)
|
||||
);
|
||||
|
||||
my %url_cache; # map URL to btr_tree node
|
||||
my %raw_url_cache; # map URL to (fake) btr_tree node
|
||||
my %mountpoint_cache;# map HOST to btrfs mount points
|
||||
my %spec_cache; # map HOST:fs_spec (aka device) to btr_tree node
|
||||
my %uuid_cache; # map UUID to btr_tree node
|
||||
my %realpath_cache; # map URL to realpath (symlink target)
|
||||
|
||||
|
@ -370,9 +370,6 @@ sub SUBVOL_LIST {
|
|||
my $vol = shift; my $t = shift // "SUBVOL_LIST"; my $svl = vinfo_subvol_list($vol);
|
||||
print STDERR "$t:\n " . join("\n ", map { "$vol->{PRINT}/./$_->{SUBVOL_PATH}\t$_->{node}{id}" } @$svl) . "\n";
|
||||
}
|
||||
sub URL_CACHE {
|
||||
print STDERR "URL_CACHE:\n" . join("\n", (sort keys %url_cache)) . "\n";
|
||||
}
|
||||
|
||||
|
||||
sub ABORTED($;$)
|
||||
|
@ -2061,17 +2058,22 @@ sub btr_tree($$$$)
|
|||
my $spec = shift || die; # aka device
|
||||
my $mountpoints = shift || die; # all known mountpoints for this filesystem: arrayref of { file, subvolid }
|
||||
die unless($vol_root_id >= 5);
|
||||
# NOTE: we need an ID (provided by btrfs_subvolume_show()) in order
|
||||
# to determine the anchor to our root path (since the subvolume path
|
||||
# output of "btrfs subvolume list" is ambigous, and the uuid of the
|
||||
# btrfs root node cannot be resolved).
|
||||
|
||||
# man btrfs-subvolume:
|
||||
# Also every btrfs filesystem has a default subvolume as its initially
|
||||
# top-level subvolume, whose subvolume id is 5(FS_TREE).
|
||||
my %tree = ( id => 5,
|
||||
# return parsed tree from %spec_cache if present
|
||||
my $vol_host_spec = ($vol->{HOST} // "localhost") . ':' . $spec;
|
||||
my $cached_tree = $spec_cache{$vol_host_spec};
|
||||
TRACE "spec_cache " . ($cached_tree ? "HIT" : "MISS") . ": $vol_host_spec";
|
||||
if($cached_tree) {
|
||||
TRACE "btr_tree: returning cached tree at id=$vol_root_id";
|
||||
my $node = $cached_tree->{ID_HASH}{$vol_root_id};
|
||||
ERROR "Unknown subvolid=$vol_root_id in btrfs tree of $vol_host_spec" unless($node);
|
||||
return $node;
|
||||
}
|
||||
|
||||
# assemble subvolume tree
|
||||
my %tree = ( id => 5, # top-level subvolume id is always 5 (by btrfs spec)
|
||||
is_root => 1,
|
||||
spec => $spec,
|
||||
host_spec => $vol_host_spec, # unique identifier, e.g. "localhost:/dev/sda1"
|
||||
MOUNTPOINTS => $mountpoints, # { file, spec, node }
|
||||
SUBTREE => []
|
||||
);
|
||||
|
@ -2156,6 +2158,7 @@ sub btr_tree($$$$)
|
|||
TRACE "btr_tree: returning tree at id=$vol_root->{id}";
|
||||
VINFO($vol_root, "node") if($loglevel >=4);
|
||||
|
||||
$spec_cache{$vol_host_spec} = \%tree;
|
||||
return $vol_root;
|
||||
}
|
||||
|
||||
|
@ -2227,26 +2230,6 @@ sub _is_child_of
|
|||
}
|
||||
|
||||
|
||||
sub _fill_url_cache
|
||||
{
|
||||
my $node = shift;
|
||||
my $abs_path = shift;
|
||||
my $node_subdir = shift;
|
||||
TRACE "_fill_url_cache: $abs_path" . ($node_subdir ? " (subdir=$node_subdir)" : "");
|
||||
|
||||
# traverse tree from given node and update tree cache
|
||||
$url_cache{$abs_path} = $node unless(defined($node_subdir));
|
||||
foreach(@{$node->{SUBTREE}}) {
|
||||
my $rel_path = $_->{REL_PATH};
|
||||
if(defined($node_subdir)) {
|
||||
next unless($rel_path =~ s/^\Q$node_subdir\E\///);
|
||||
}
|
||||
_fill_url_cache($_, $abs_path . '/' . $rel_path, undef);
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
sub _get_longest_match
|
||||
{
|
||||
my $node = shift;
|
||||
|
@ -2264,20 +2247,6 @@ sub _get_longest_match
|
|||
}
|
||||
|
||||
|
||||
# reverse path lookup
|
||||
sub get_cached_url_by_uuid($)
|
||||
{
|
||||
my $uuid = shift;
|
||||
my @result;
|
||||
while(my ($url, $node) = each(%url_cache)) {
|
||||
next if($node->{is_root});
|
||||
next unless($node->{uuid} eq $uuid);
|
||||
push @result, $url;
|
||||
}
|
||||
return @result;
|
||||
}
|
||||
|
||||
|
||||
sub vinfo($;$)
|
||||
{
|
||||
my $url = shift // die;
|
||||
|
@ -2455,34 +2424,20 @@ sub vinfo_init_root($;@)
|
|||
{
|
||||
my $vol = shift || die;
|
||||
my %opts = @_;
|
||||
my $tree_root;
|
||||
|
||||
# use cached info if present
|
||||
$tree_root = $url_cache{$vol->{URL}};
|
||||
TRACE "url_cache " . ($tree_root ? "HIT" : "MISS") . ": URL=$vol->{URL}";
|
||||
unless($tree_root) {
|
||||
if(my $real_path = $realpath_cache{$vol->{URL}}) {
|
||||
my $real_url = $vol->{URL_PREFIX} . $real_path;
|
||||
$tree_root = $url_cache{$real_url};
|
||||
TRACE "url_cache " . ($tree_root ? "HIT" : "MISS") . ": REAL_URL=$real_url";
|
||||
}
|
||||
}
|
||||
|
||||
unless($tree_root) {
|
||||
# btrfs tree is not yet cached, read it from mount point
|
||||
# resolve btrfs tree from mount point
|
||||
my ($mnt_path, $real_path, $subvolid, $spec, $spec_mounts) = btrfs_mountpoint($vol);
|
||||
return undef unless($mnt_path && $real_path && $subvolid);
|
||||
my $mnt_tree_root = $url_cache{$vol->{URL_PREFIX} . $mnt_path};
|
||||
unless($mnt_tree_root) {
|
||||
|
||||
# read btrfs tree for the mount point
|
||||
my $mnt_vol = vinfo($vol->{URL_PREFIX} . $mnt_path, $vol->{CONFIG});
|
||||
$mnt_tree_root = btr_tree($mnt_vol, $subvolid, $spec, $spec_mounts);
|
||||
_fill_url_cache($mnt_tree_root, $mnt_vol->{URL});
|
||||
}
|
||||
my $mnt_tree_root = btr_tree($mnt_vol, $subvolid, $spec, $spec_mounts);
|
||||
return undef unless($mnt_tree_root);
|
||||
|
||||
# find longest match in tree
|
||||
# find longest match in btrfs tree
|
||||
my $ret = _get_longest_match($mnt_tree_root, $mnt_path, $real_path) // die;
|
||||
$tree_root = $ret->{node};
|
||||
my $tree_root = $ret->{node};
|
||||
return undef unless($tree_root);
|
||||
|
||||
# set NODE_SUBDIR if $vol->{PATH} points to a regular (non-subvolume) directory.
|
||||
# in other words, "PATH=<path_to_subvolume>/NODE_SUBDIR"
|
||||
|
@ -2490,16 +2445,11 @@ sub vinfo_init_root($;@)
|
|||
die unless($node_subdir =~ s/^\Q$ret->{path}\E//); # NOTE: $ret->{path} has trailing slash!
|
||||
$node_subdir =~ s/\/+$//;
|
||||
$vol->{NODE_SUBDIR} = $node_subdir if($node_subdir ne '');
|
||||
$vol->{node} = $tree_root;
|
||||
|
||||
$vol->{MOUNTPOINT} = $mnt_path;
|
||||
$vol->{MOUNTPOINT_NODE} = $mnt_tree_root;
|
||||
|
||||
_fill_url_cache($tree_root, $vol->{URL}, $vol->{NODE_SUBDIR});
|
||||
}
|
||||
return undef unless($tree_root);
|
||||
|
||||
$vol->{node} = $tree_root;
|
||||
|
||||
return $tree_root;
|
||||
}
|
||||
|
||||
|
@ -2523,6 +2473,7 @@ sub vinfo_init_raw_root($;@)
|
|||
# create fake btr_tree
|
||||
$tree_root = { id => 5,
|
||||
is_root => 1,
|
||||
host_spec => 'raw_tree@' . $droot->{URL}, # for completeness (this is never used)
|
||||
GEN_MAX => 1,
|
||||
SUBTREE => [],
|
||||
UUID_HASH => {},
|
||||
|
@ -2749,7 +2700,6 @@ sub vinfo_inject_child($$$;$)
|
|||
return undef unless(add_btrbk_filename_info($node, $raw_info));
|
||||
|
||||
$vinfo_child->{node} = $node;
|
||||
$url_cache{$vinfo_child->{URL}} = $node;
|
||||
TRACE "vinfo_inject_child: injected child id=$node->{id} to $vinfo->{PRINT}";
|
||||
return $vinfo_child;
|
||||
}
|
||||
|
@ -4280,13 +4230,9 @@ sub _origin_tree
|
|||
# cache a bit, this might be large
|
||||
$nodelist //= [ (sort { $a->{REL_PATH} cmp $b->{REL_PATH} } values %uuid_cache) ];
|
||||
|
||||
my @url = get_cached_url_by_uuid($uuid);
|
||||
my $out_path;
|
||||
if(scalar @url) {
|
||||
$out_path = join(" === ", sort map { vinfo($_)->{PRINT} } @url);
|
||||
} else {
|
||||
$out_path = _fs_path($node);
|
||||
}
|
||||
|
||||
my $prefix_spaces = ' ' x (($depth * 4) - ($prefix ? 4 : 0));
|
||||
push(@$lines, { tree => "${prefix_spaces}${prefix}$out_path",
|
||||
uuid => $node->{uuid},
|
||||
|
|
Loading…
Reference in New Issue