--- /dev/null
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2013 Red Hat, Inc., Tomas Racek <tracek@redhat.com>
+#
+# FS QA Test No. 746
+#
+# Test that filesystem sends discard requests only on free blocks
+#
+. ./common/preamble
+_begin_fstest auto trim fiemap
+
+_supported_fs ext4 xfs btrfs
+_require_test
+_require_loop
+_require_fstrim
+_require_xfs_io_command "fiemap"
+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=$(_small_fs_size_mb 300) # 200m phys/virt size
+fi
+
+[ "$FSTYP" = "ext4" ] && _require_dumpe2fs
+[ "$FSTYP" = "btrfs" ] && _require_btrfs_command inspect-internal dump-super
+[ "$FSTYP" = "btrfs" ] && _require_btrfs_command inspect-internal dump-tree
+
+# Override the default cleanup function.
+_cleanup()
+{
+ $UMOUNT_PROG $loop_dev &> /dev/null
+ _destroy_loop_device $loop_dev
+ if [ $status -eq 0 ]; then
+ rm -rf $tmp
+ rm $img_file
+ fi
+}
+
+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
+
+ # FIEMAP only works on regular files, so call it on the backing file
+ # and not the loop device like everything else
+ $XFS_IO_PROG -F -c fiemap $img_file | 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 $loop_dev 2>&1 | grep " Free blocks" | cut -d ":" -f2- | \
+ tr ',' '\n' | $SED_PROG 's/^ //' | \
+ $AWK_PROG -v spb=$sectors_per_block 'BEGIN{FS="-"};
+ NF {
+ if($2 != "") # range of blocks
+ print spb * $1, spb * ($2 + 1) - 1;
+ else # just single block
+ print spb * $1, spb * ($1 + 1) - 1;
+ }'
+ ;;
+ xfs)
+ agsize=`$XFS_INFO_PROG $loop_mnt | $SED_PROG -n 's/.*agsize=\(.*\) blks.*/\1/p'`
+ # Convert free space (agno, block, length) to (start sector, end sector)
+ $UMOUNT_PROG $loop_mnt
+ $XFS_DB_PROG -r -c "freesp -d" $loop_dev | $SED_PROG '/^.*from/,$d'| \
+ $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 $loop_dev \
+ | sed -n 's/nodesize\s*\(.*\)/\1/p')
+
+ # Get holes within block groups
+ $BTRFS_UTIL_PROG inspect-internal dump-tree -t extent $loop_dev \
+ | $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 $loop_dev \
+ | $AWK_PROG -v sectorsize=512 -v devsize=$device_size -f $here/src/parse-dev-tree.awk
+
+ ;;
+ esac
+}
+
+merge_ranges()
+{
+ # Merges consecutive ranges from two input files
+ file1=$1
+ file2=$2
+
+ tmp_file=$tmp/sectors.tmp
+
+ cat $file1 $file2 | sort -n > $tmp_file
+
+ read line < $tmp_file
+ start=${line% *}
+ end=${line#* }
+
+ # Continue from second line
+ sed -i "1d" $tmp_file
+ while read line; do
+ curr_start=${line% *}
+ curr_end=${line#* }
+
+ if [ `expr $end + 1` -ge $curr_start ]; then
+ if [ $curr_end -gt $end ]; then
+ end=$curr_end
+ fi
+ else
+ echo $start $end
+ start=$curr_start
+ end=$curr_end
+ fi
+ done < $tmp_file
+
+ # Print last line
+ echo $start $end
+
+ rm $tmp_file
+}
+
+tmp=`mktemp -d`
+
+img_file=$TEST_DIR/$$.fs
+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
+
+fiemap_ref="$tmp/reference"
+fiemap_after="$tmp/after"
+free_sectors="$tmp/free_sectors"
+merged_sectors="$tmp/merged_free_sectors"
+
+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
+
+echo -n "Generating garbage on loop..."
+# Goal is to fill it up, ignore any errors.
+for i in `seq 1 10`; do
+ mkdir $loop_mnt/$i &> /dev/null
+ cp -r $here/* $loop_mnt/$i &> /dev/null || break
+done
+
+# Get reference fiemap, this can contain i.e. uninitialized inode table
+sync
+get_holes > $fiemap_ref
+
+# Delete some files
+find $loop_mnt -type f -print | $AWK_PROG \
+ 'BEGIN {srand()}; {if(rand() > 0.7) printf("%s\0", $0);}' | xargs -0 rm
+echo "done."
+
+echo -n "Running fstrim..."
+$FSTRIM_PROG $loop_mnt &> /dev/null
+echo "done."
+
+echo -n "Detecting interesting holes in image..."
+# Get after-trim fiemap
+sync
+get_holes > $fiemap_after
+echo "done."
+
+echo -n "Comparing holes to the reported space from FS..."
+# Get block size
+block_size=$(_get_block_size $loop_mnt/)
+sectors_per_block=`expr $block_size / 512`
+
+# Obtain free space from filesystem
+get_free_sectors > $free_sectors
+# Merge original holes with free sectors
+merge_ranges $fiemap_ref $free_sectors > $merged_sectors
+
+# Check that all holes after fstrim call were already present before or
+# that they match free space reported from FS
+while read line; do
+ from=${line% *}
+ to=${line#* }
+ if ! $AWK_PROG -v s=$from -v e=$to \
+ '{ if ($1 <= s && e <= $2) found = 1};
+ 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
+echo "done."
+
+status=0
+exit
--- /dev/null
+QA output created by 746
+Generating garbage on loop...done.
+Running fstrim...done.
+Detecting interesting holes in image...done.
+Comparing holes to the reported space from FS...done.
+++ /dev/null
-#! /bin/bash
-# SPDX-License-Identifier: GPL-2.0
-# Copyright (c) 2013 Red Hat, Inc., Tomas Racek <tracek@redhat.com>
-#
-# FS QA Test No. 298
-#
-# Test that filesystem sends discard requests only on free blocks
-#
-. ./common/preamble
-_begin_fstest auto trim fiemap
-
-_supported_fs ext4 xfs btrfs
-_require_test
-_require_loop
-_require_fstrim
-_require_xfs_io_command "fiemap"
-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=$(_small_fs_size_mb 300) # 200m phys/virt size
-fi
-
-[ "$FSTYP" = "ext4" ] && _require_dumpe2fs
-[ "$FSTYP" = "btrfs" ] && _require_btrfs_command inspect-internal dump-super
-[ "$FSTYP" = "btrfs" ] && _require_btrfs_command inspect-internal dump-tree
-
-# Override the default cleanup function.
-_cleanup()
-{
- $UMOUNT_PROG $loop_dev &> /dev/null
- _destroy_loop_device $loop_dev
- if [ $status -eq 0 ]; then
- rm -rf $tmp
- rm $img_file
- fi
-}
-
-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
-
- # FIEMAP only works on regular files, so call it on the backing file
- # and not the loop device like everything else
- $XFS_IO_PROG -F -c fiemap $img_file | 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 $loop_dev 2>&1 | grep " Free blocks" | cut -d ":" -f2- | \
- tr ',' '\n' | $SED_PROG 's/^ //' | \
- $AWK_PROG -v spb=$sectors_per_block 'BEGIN{FS="-"};
- NF {
- if($2 != "") # range of blocks
- print spb * $1, spb * ($2 + 1) - 1;
- else # just single block
- print spb * $1, spb * ($1 + 1) - 1;
- }'
- ;;
- xfs)
- agsize=`$XFS_INFO_PROG $loop_mnt | $SED_PROG -n 's/.*agsize=\(.*\) blks.*/\1/p'`
- # Convert free space (agno, block, length) to (start sector, end sector)
- $UMOUNT_PROG $loop_mnt
- $XFS_DB_PROG -r -c "freesp -d" $loop_dev | $SED_PROG '/^.*from/,$d'| \
- $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 $loop_dev \
- | sed -n 's/nodesize\s*\(.*\)/\1/p')
-
- # Get holes within block groups
- $BTRFS_UTIL_PROG inspect-internal dump-tree -t extent $loop_dev \
- | $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 $loop_dev \
- | $AWK_PROG -v sectorsize=512 -v devsize=$device_size -f $here/src/parse-dev-tree.awk
-
- ;;
- esac
-}
-
-merge_ranges()
-{
- # Merges consecutive ranges from two input files
- file1=$1
- file2=$2
-
- tmp_file=$tmp/sectors.tmp
-
- cat $file1 $file2 | sort -n > $tmp_file
-
- read line < $tmp_file
- start=${line% *}
- end=${line#* }
-
- # Continue from second line
- sed -i "1d" $tmp_file
- while read line; do
- curr_start=${line% *}
- curr_end=${line#* }
-
- if [ `expr $end + 1` -ge $curr_start ]; then
- if [ $curr_end -gt $end ]; then
- end=$curr_end
- fi
- else
- echo $start $end
- start=$curr_start
- end=$curr_end
- fi
- done < $tmp_file
-
- # Print last line
- echo $start $end
-
- rm $tmp_file
-}
-
-tmp=`mktemp -d`
-
-img_file=$TEST_DIR/$$.fs
-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
-
-fiemap_ref="$tmp/reference"
-fiemap_after="$tmp/after"
-free_sectors="$tmp/free_sectors"
-merged_sectors="$tmp/merged_free_sectors"
-
-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
-
-echo -n "Generating garbage on loop..."
-# Goal is to fill it up, ignore any errors.
-for i in `seq 1 10`; do
- mkdir $loop_mnt/$i &> /dev/null
- cp -r $here/* $loop_mnt/$i &> /dev/null || break
-done
-
-# Get reference fiemap, this can contain i.e. uninitialized inode table
-sync
-get_holes > $fiemap_ref
-
-# Delete some files
-find $loop_mnt -type f -print | $AWK_PROG \
- 'BEGIN {srand()}; {if(rand() > 0.7) printf("%s\0", $0);}' | xargs -0 rm
-echo "done."
-
-echo -n "Running fstrim..."
-$FSTRIM_PROG $loop_mnt &> /dev/null
-echo "done."
-
-echo -n "Detecting interesting holes in image..."
-# Get after-trim fiemap
-sync
-get_holes > $fiemap_after
-echo "done."
-
-echo -n "Comparing holes to the reported space from FS..."
-# Get block size
-block_size=$(_get_block_size $loop_mnt/)
-sectors_per_block=`expr $block_size / 512`
-
-# Obtain free space from filesystem
-get_free_sectors > $free_sectors
-# Merge original holes with free sectors
-merge_ranges $fiemap_ref $free_sectors > $merged_sectors
-
-# Check that all holes after fstrim call were already present before or
-# that they match free space reported from FS
-while read line; do
- from=${line% *}
- to=${line#* }
- if ! $AWK_PROG -v s=$from -v e=$to \
- '{ if ($1 <= s && e <= $2) found = 1};
- 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
-echo "done."
-
-status=0
-exit
+++ /dev/null
-QA output created by 298
-Generating garbage on loop...done.
-Running fstrim...done.
-Detecting interesting holes in image...done.
-Comparing holes to the reported space from FS...done.