. ./common/rc
-_supported_fs ext4 xfs
-_supported_os Linux
+# remove previous $seqres.full before test
+rm -f $seqres.full
+
+_supported_fs ext4 xfs btrfs
_require_test
_require_loop
_require_fstrim
_require_xfs_io_command "fiemap"
-_require_fs_space $TEST_DIR 307200
+if [ "$FSTYP" = "btrfs" ]; then
+ # 3g for btrfs to have distinct bgs
+ _require_fs_space $TEST_DIR 3145728
+ fssize=3000
+else
+ _require_fs_space $TEST_DIR 307200
+ fssize=300
+fi
+
[ "$FSTYP" = "ext4" ] && _require_dumpe2fs
+[ "$FSTYP" = "btrfs" ] && _require_btrfs_command inspect-internal dump-super
+[ "$FSTYP" = "btrfs" ] && _require_btrfs_command inspect-internal dump-tree
_cleanup()
{
get_holes()
{
+ # It's not a good idea to be running tools against the image file
+ # backing a live filesystem because the filesystem could be maintaining
+ # in-core state that will perturb the free space map on umount. Stick
+ # to established convention which requires the filesystem to be
+ # unmounted while we probe the underlying file.
+ $UMOUNT_PROG $loop_mnt
$XFS_IO_PROG -F -c fiemap $1 | grep hole | $SED_PROG 's/.*\[\(.*\)\.\.\(.*\)\].*/\1 \2/'
+ _mount $loop_dev $loop_mnt
}
get_free_sectors()
{
case $FSTYP in
ext4)
+ $UMOUNT_PROG $loop_mnt
$DUMPE2FS_PROG $img_file 2>&1 | grep " Free blocks" | cut -d ":" -f2- | \
tr ',' '\n' | $SED_PROG 's/^ //' | \
$AWK_PROG -v spb=$sectors_per_block 'BEGIN{FS="-"};
$AWK_PROG -v spb=$sectors_per_block -v agsize=$agsize \
'{ print spb * ($1 * agsize + $2), spb * ($1 * agsize + $2 + $3) - 1 }'
;;
+ btrfs)
+ local device_size=$($BTRFS_UTIL_PROG filesystem show --raw $loop_mnt 2>&1 \
+ | sed -n "s/^.*size \([0-9]*\).*$/\1/p")
+
+ local nodesize=$($BTRFS_UTIL_PROG inspect-internal dump-super $img_file \
+ | sed -n 's/nodesize\s*\(.*\)/\1/p')
+
+ # Get holes within block groups
+ $BTRFS_UTIL_PROG inspect-internal dump-tree -t extent $img_file \
+ | $AWK_PROG -v sectorsize=512 -v nodesize=$nodesize -f $here/src/parse-extent-tree.awk
+
+ # Get holes within unallocated space on disk
+ $BTRFS_UTIL_PROG inspect-internal dump-tree -t dev $img_file \
+ | $AWK_PROG -v sectorsize=512 -v devsize=$device_size -f $here/src/parse-dev-tree.awk
+
+ ;;
esac
}
tmp=`mktemp -d`
img_file=$TEST_DIR/$$.fs
-dd if=/dev/zero of=$img_file bs=1M count=300 &> /dev/null
+dd if=/dev/zero of=$img_file bs=1M count=$fssize &> /dev/null
loop_dev=$(_create_loop_device $img_file)
loop_mnt=$tmp/loop_mnt
mkdir $loop_mnt
[ "$FSTYP" = "xfs" ] && MKFS_OPTIONS="-f $MKFS_OPTIONS"
+[ "$FSTYP" = "btrfs" ] && MKFS_OPTIONS="$MKFS_OPTIONS -f -dsingle -msingle"
_mkfs_dev $loop_dev
_mount $loop_dev $loop_mnt
END { if(found) exit 0; else exit 1}' $merged_sectors
then
echo "Sectors $from-$to are not marked as free!"
+
+ # Dump the state to make it easier to debug this...
+ echo free_sectors >> $seqres.full
+ sort -g < $free_sectors >> $seqres.full
+ echo fiemap_ref >> $seqres.full
+ sort -g < $fiemap_ref >> $seqres.full
+ echo merged_sectors >> $seqres.full
+ sort -g < $merged_sectors >> $seqres.full
+ echo fiemap_after >> $seqres.full
+ sort -g < $fiemap_after >> $seqres.full
exit
fi
done < $fiemap_after