Annoyingly, btrfs filesystem show
returns an approximate value if the size isn't a multiple of 1MB. It also requires a loop device, btrfs filesystem show img.btrfs
doesn't work (as of Debian jessie). I can't find another btrfs
subcommand that would help.
But file img.btrfs
helpfully returns the desired size.
$ truncate -s 16684k /tmp/img.btrfs
$ /sbin/mkfs.btrfs /tmp/img.btrfs
SMALL VOLUME: forcing mixed metadata/data groups
Btrfs v3.17
See http://btrfs.wiki.kernel.org for more information.
Turning ON incompat feature 'mixed-bg': mixed data and metadata block groups
Turning ON incompat feature 'extref': increased hardlink limit per file to 65536
Created a data/metadata chunk of size 1703936
failed to open /dev/btrfs-control skipping device registration: Permission denied
fs created label (null) on /tmp/img.btrfs
nodesize 4096 leafsize 4096 sectorsize 4096 size 16.29MiB
$ truncate -s 32m /tmp/img.btrfs
$ file /tmp/img.btrfs
/tmp/img.btrfs: BTRFS Filesystem sectorsize 4096, nodesize 4096, leafsize 4096, UUID=61297945-d399-4fdc-ba9f-750ef9f9dfdb, 28672/17084416 bytes used, 1 devices
It directly reads the 8-byte little-endian value at offset 0x10070. If you don't want to parse the output of file
, you can extract it. The following POSIX snippet does the job¹:
size_hex=$(cat /tmp/img.btrfs | dd ibs=8 skip=8206 count=1 2>/dev/null | od -tx8 -An | tr abcdef ABCDEF | tr -dc 0-9ABCDEF)
[ ${#size_hex} -eq 16 ] &&
{ echo "ibase=16; $size_hex"; } | bc
or in Perl:
</tmp/btrfs.img perl -e 'seek(STDIN, 0x10070, 0) or sysread(STDIN, $_, 0x10070) == 0x10070 or die "seek"; sysread(STDIN, $_, 8) == 8 or die "read"; print unpack("Q<", $_), "\n"'
file
works for some other filesystem types, but that doesn't help much for scripts because the output isn't standardized. I can't think of a generic utility with a standard interface for all common filesystems, maybe some virtualization or forensics tool.
¹ Exercise: why is this a useful use of cat
?
mkfs.btrfs /dev/loop
using up all available space). Then I calledbtrfs fi resize -3G /vol/btrfs
.