mirror of https://github.com/digint/btrbk
btrbk: cleanup aio extentmap
parent
dc1b7f1b5c
commit
0719fc415d
47
btrbk
47
btrbk
|
@ -2358,9 +2358,10 @@ sub filefrag_extentmap($)
|
||||||
sub aio_extentmap($)
|
sub aio_extentmap($)
|
||||||
{
|
{
|
||||||
my $vol = shift || die;
|
my $vol = shift || die;
|
||||||
|
my $starttime = time;
|
||||||
|
|
||||||
INFO("Fetching extent information (IO::AIO) for: $vol->{PRINT}");
|
INFO("Fetching extent information (IO::AIO) for: $vol->{PRINT}");
|
||||||
my $starttime = time;
|
|
||||||
# NOTE: this returns exitstatus=0 if file is not found, or no files found
|
# NOTE: this returns exitstatus=0 if file is not found, or no files found
|
||||||
my $ret = run_cmd( cmd => [ 'find', { unsafe => $vol->{PATH} }, '-xdev', '-type', 'f' ],
|
my $ret = run_cmd( cmd => [ 'find', { unsafe => $vol->{PATH} }, '-xdev', '-type', 'f' ],
|
||||||
large_output => 1 );
|
large_output => 1 );
|
||||||
|
@ -2369,44 +2370,42 @@ sub aio_extentmap($)
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG("Reading ioctl FIEMAP on all files");
|
DEBUG("Reading ioctl FIEMAP of " . scalar(@$ret) . " files");
|
||||||
|
|
||||||
IO::AIO::max_outstanding(512); # < 1024 (max file descriptors)
|
IO::AIO::max_outstanding(128); # < 1024 (max file descriptors)
|
||||||
|
IO::AIO::max_poll_reqs(32);
|
||||||
|
|
||||||
# not sure how IO::AIO does its threading, it says we should not care about it (?).
|
|
||||||
# anyway, it works without "my @range :shared" (from threads::shared).
|
|
||||||
# Note: aio_fiemap returns byte range (not blocks)
|
# Note: aio_fiemap returns byte range (not blocks)
|
||||||
my @range;
|
my @range;
|
||||||
my $relax = 0;
|
|
||||||
my $count = 0;
|
my $count = 0;
|
||||||
|
my $inline = 0;
|
||||||
foreach my $file (@$ret) {
|
foreach my $file (@$ret) {
|
||||||
IO::AIO::aio_open($file, IO::AIO::O_RDONLY(), 0, sub {
|
IO::AIO::aio_open($file, IO::AIO::O_RDONLY(), 0, sub {
|
||||||
my $fh = shift or die "failed to open $file: $!";
|
return unless($_[0]); # graceful abort on file open errors (check $count below)
|
||||||
#aioreq_pri 4;
|
IO::AIO::aio_fiemap($_[0], 0, undef, 0, undef, sub {
|
||||||
# aio_fiemap $fh, $start, $length, $flags, $count, $cb->(\@extents)
|
|
||||||
IO::AIO::aio_fiemap($fh, 0, undef, 0, undef, sub {
|
|
||||||
my $aref = shift; # [$logical, $physical, $length, $flags]
|
|
||||||
# ignore inline data: for some reason, filefrag reports different size (x 4096 ?)
|
|
||||||
push @range, map { ($_->[3] & IO::AIO::FIEMAP_EXTENT_DATA_INLINE()) ? () :
|
|
||||||
[ $_->[1], $_->[1] + $_->[2] - 1 ] } @$aref;
|
|
||||||
$count++;
|
$count++;
|
||||||
close $fh;
|
foreach(@{$_[0]}) { # [$logical, $physical, $length, $flags]
|
||||||
|
if($_->[3] & IO::AIO::FIEMAP_EXTENT_DATA_INLINE() ) {
|
||||||
|
# ignore inline data: for some reason, filefrag reports different size (x 4096 ?)
|
||||||
|
$inline++;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
push @range, [ $_->[1], $_->[1] + $_->[2] - 1 ];
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
# the above eats up all our filedescriptors, relax every now and then
|
# poll, or the above eats up all our filedescriptors
|
||||||
$relax++;
|
IO::AIO::poll_cb(); # takes "max_outstanding" and "max_poll_reqs" settings
|
||||||
if($relax > 256) {
|
#TRACE "aio_fiemap: processed $ret : $count files (inline=$inline), " . scalar(@range) . " regions" if($loglevel >= 4);
|
||||||
# poll_cb is slow, no need to call it every time
|
|
||||||
IO::AIO::poll_cb(); # max_outstanding is only unsed if poll_cb is called
|
|
||||||
TRACE "aio_fiemap: processed $count files, " . scalar(@range) . " regions" if($loglevel >= 4);
|
|
||||||
$relax = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IO::AIO::flush();
|
IO::AIO::flush();
|
||||||
|
|
||||||
DEBUG("parsed FIEMAP of $count files: " . scalar(@range) . " regions in " . (time - $starttime) . "s for: $vol->{PRINT}");
|
WARN "Failed to open $count / " . scalar(@$ret) . " files" if($count != scalar(@$ret));
|
||||||
|
|
||||||
|
DEBUG("Parsed " . scalar(@range) . " regions for $count files in " . (time - $starttime) . "s for: $vol->{PRINT}");
|
||||||
|
DEBUG("Ignored $inline \"inline\" extents for: $vol->{PRINT}") if($inline);
|
||||||
return extentmap_merge(\@range);
|
return extentmap_merge(\@range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue