2 # compute the blocks used by a file
4 # computeblocklists [options] <files...>
6 # --padstart NUM, --padend NUM, --verbose
9 # <file base name> <size> <blocksize> <block numbers...>
11 # a block is either a number or a range (start-end)
13 # TODO: instead of printing zeroes for each block in a hole use
14 # something like 0*num
18 my ($opt_padstart, $opt_padend, $opt_verbose);
21 if ($ARGV[0] eq '--padstart') {
23 $opt_padstart = shift @ARGV;
26 if ($ARGV[0] eq '--padend') {
28 $opt_padend = shift @ARGV;
31 if ($ARGV[0] eq '--verbose' || $ARGV[0] eq '-v') {
40 print "\n"x$opt_padstart;
43 for my $file (@ARGV) {
45 print STDERR "$file\n" if $opt_verbose;
49 if(!open(F, '<', $file)) {
50 print STDERR "$file: $!";
55 ioctl(F, 2, $bsize) || ioctl(F, 536870914, $bsize) || die("FIGETBSZ: $!\n");
56 $bsize = unpack("L", $bsize);
59 my ($st_size, $st_blocks) = ($stat[7], $stat[11], $stat[12]);
61 my $blocks = int(($st_size+$bsize-1)/$bsize);
63 print "$n $st_size $bsize ";
65 my ($firstblock, $lastblock);
66 for ($b = 0; $b < $blocks; ++$b) {
67 my $block = pack('I', $b);
68 if(not defined ioctl(F, 1, $block)) {
69 if(not defined ioctl(F, 536870913, $block)) {
73 $block = unpack('I', $block);
78 # blocks are non-contiguous
79 if($lastblock+1 != $block) {
80 # check if we skipped some that form a range
81 if($firstblock != $lastblock) {
87 # last block, check if contiguous
88 if($b+1==$blocks && $lastblock+1 == $block) {
99 print "\n"x$opt_padend;