#!/usr/bin/perl -T

use strict;
use warnings;

my $fd;

$ENV{PATH} = "/usr/sbin";
$ENV{LC_ALL} = "C";

my $XFSDB  = "xfs_db";

sub help { print "Usage: freecount.pl device\n"; }

sub read_param {
  my $param = shift or die;

  my ($key, $val) = split(/ = /, <$fd>);

  my $regex = quotemeta($param);

  die "desired $param not received" unless $key =~ /$regex/;

  return $val;
}

unless (@ARGV == 1) { help && exit }

my $dev = pop @ARGV;

# untaint
if ($dev =~ m!^(\/dev\/\w+\d+)$!) { $dev = $1 } else { help && exit }

open($fd, "$XFSDB -r -c 'sb' -c 'p agcount' -c 'p blocksize' $dev |")
  or die "Can't open xfs_db: $!\n";

my ($agcount, $blksize) = map { read_param $_ } qw/agcount blocksize/;

close($fd);

my $free = 0;

for (my $i = 0; $i < $agcount; $i++) {

  open($fd, "$XFSDB -r -c 'agf $i' -c 'p freeblks' -c 'p btreeblks' $dev |")
    or die "Can't open xfs_db: $!\n";

  # discount the space used in btreeblks from the free space
  $free += read_param("freeblks") - read_param("btreeblks");

  close($fd);
}

$free *= $blksize / (1024 ** 2);

print "$free M";
