fallocate: dig holes only in data extents
Based on patch from Vaclav Dolezal <vdolezal@redhat.com>, this
implementation is less invasive.
The patch adds a new while() for pread() call (so diff is mostly code
indention). The pread() is called for a real data only (addressed by
'off' and 'end') and we use SEEK_{DATA,HOLE} before the pread() to
skip already existing holes. The variables 'file_off' and 'file_end'
addresses area in the file as specified on fallocate command line.
Test:
$ truncate -s 10G testfile
$ dd if=/dev/zero of=testfile count=10 bs=1M conv=notrunc
old version:
$ time /usr/bin/fallocate --dig-holes --verbose testfile
testfile: 10 GiB (
10737418240 bytes) converted to sparse holes.
real 0m3.013s
user 0m0.700s
sys 0m2.304s
new version:
$ time ./fallocate --dig-holes --verbose testfile
testfile: 10 MiB (
10485760 bytes) converted to sparse holes.
real 0m0.026s
user 0m0.002s
sys 0m0.004s
The old version scans all file.
The change has minimal overhead for files without holes.
Addresses: https://github.com/karelzak/util-linux/issues/421
Co-Author: Vaclav Dolezal <vdolezal@redhat.com>
Signed-off-by: Karel Zak <kzak@redhat.com>