@@ -480,3 +480,90 @@ _btrfs_no_v1_cache_opt()
fi
echo -n "-onospace_cache"
}
+
+# Test if a property is available
+_require_btrfs_property_get()
+{
+ local propname
+
+ [ $# -eq 1 ] || _fail "_require_btrfs_get_property: expected property name as param"
+
+ propname="$1"
+ $BTRFS_UTIL_PROG property get $SCRATCH_DEV "$propname" |
+ grep -q "ERROR: unknown property" &&
+ _notrun "Need btrfs property '$propname' support"
+}
+
+__dump_bg_data_info() {
+ local dir=$1
+ $BTRFS_UTIL_PROG fi us -b $dir | awk '
+ /^$/ { flag=0 }
+ { if(flag) print $0 }
+ /^Data/ { flag=1 }
+ '
+}
+
+__dump_bg_metadata_info() {
+ local dir=$1
+ $BTRFS_UTIL_PROG fi us -b $dir | awk '
+ /^$/ { flag=0 }
+ { if(flag) print $0 }
+ /^Metadata/ { flag=1 }
+ '
+}
+
+# check if a disk not contains data bg
+btrfs_check_data_bg_in_disk() {
+ local mnt=$1
+ shift
+ local res="$(__dump_bg_data_info $mnt)"
+ while [ -n "$1" ]; do
+ if ! echo $res | egrep -q $1 ; then
+ [ -n "$DEBUG" ] && $BTRFS_UTIL_PROG fil us $SCRATCH_MNT
+ _fail "Disk '$1' should contain a DATA BG"
+ fi
+ shift
+ done
+}
+
+# check if a disk not contains data bg
+btrfs_check_data_bg_not_in_disk() {
+ local mnt=$1
+ shift
+ local res="$(__dump_bg_data_info $mnt)"
+ while [ -n "$1" ]; do
+ if echo $res | egrep -q $1 ; then
+ [ -n "$DEBUG" ] && $BTRFS_UTIL_PROG fil us $SCRATCH_MNT
+ _fail "Disk '$1' should not contain a DATA BG"
+ fi
+ shift
+ done
+}
+
+# check if a disk contains metadata bg
+btrfs_check_metadata_bg_in_disk() {
+ local mnt=$1
+ shift
+ local res="$(__dump_bg_metadata_info $mnt)"
+ while [ -n "$1" ]; do
+ if ! echo $res | egrep -q $1 ; then
+ [ -n "$DEBUG" ] && $BTRFS_UTIL_PROG fil us $SCRATCH_MNT
+ _fail "Disk '$1' should contain a METADATA BG"
+ fi
+ shift
+ done
+}
+
+# check if a disk not contains metadata bg
+btrfs_check_metadata_bg_not_in_disk() {
+ local mnt=$1
+ shift
+ local res="$(__dump_bg_metadata_info $mnt)"
+ while [ -n "$1" ]; do
+ if echo $res | egrep -q $1 ; then
+ [ -n "$DEBUG" ] && $BTRFS_UTIL_PROG fil us $SCRATCH_MNT
+ _fail "Disk '$1' should not contain a METADATA BG"
+ fi
+ shift
+ done
+}
@@ -132,4 +132,5 @@ whiteout overlayfs whiteout functionality
xino overlayfs xino feature
zero fallocate FALLOC_FL_ZERO_RANGE
zone zoned (SMR) device support
+allocation_hint allocation_hint property (BTRFS only)
======================= =======================================================
new file mode 100755
@@ -0,0 +1,120 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# FS QA Test No. 255
+#
+# Test the allocation_hint property of a btrfs filesystem
+#
+
+
+# size of the disk used; default 1GB
+MAXSIZE=$((1*1024*1024*1024))
+NDEVS=2
+DEBUG=
+
+. ./common/preamble
+_begin_fstest auto quick allocation_hint
+
+seq=`basename $0`
+seqres="${RESULT_DIR}/${seq}"
+
+disks=""
+nodes=""
+
+# Override the default cleanup function.
+_cleanup()
+{
+ umount $SCRATCH_MNT &>/dev/null || true
+ for disk in $disks; do
+ _dmsetup_remove $disk
+ done
+}
+
+# Import common functions.
+. ./common/filter
+. ./common/filter.btrfs
+
+# real QA test starts here
+_supported_fs btrfs
+_require_block_device $SCRATCH_DEV
+_require_dm_target linear
+_require_scratch_nocheck
+_require_command "$WIPEFS_PROG" wipefs
+_try_wipe_scratch_devs
+
+_require_btrfs_property_get "allocation_hint"
+
+# dont' use _require_scratch_size because it pretend that the filesystem is
+# scratch_dev is consistent
+devsize=`_get_device_size $SCRATCH_DEV`
+[ $devsize -lt $((($MAXSIZE * $NDEVS + 100*1024*1024) / 1024)) ] &&
+ _notrun "scratch dev too small"
+
+setup_dmdev()
+{
+ # create some small size disks
+
+ size_in_sector=$(($MAXSIZE / 512))
+
+ off=0
+ for i in $(seq $NDEVS); do
+ node=dev${seq}test${i}
+ disk="/dev/mapper/$node"
+ disks="$disks $disk"
+ nodes="$nodes $node"
+ table="0 $size_in_sector linear $SCRATCH_DEV $off"
+ _dmsetup_create $node --table "$table" || \
+ _fail "setup dm device failed"
+ off=$(($off + $size_in_sector))
+ $WIPEFS_PROG -a $disk &>/dev/null
+ done
+}
+
+create_file() {
+ local fn=$SCRATCH_MNT/giant-file-$1
+ local size
+ if [ -n "$2" ]; then
+ size=count=$(($2 / 16 / 1024 / 1024 ))
+ else
+ size=
+ fi
+ dd if=/dev/zero of=$fn bs=16M oflag=direct $size &>/dev/null
+ ls -l $fn | awk '{ print $5 }'
+}
+
+#
+# create a file and check that the Data BG is in the correct disk
+#
+test_single_preferred_data() {
+
+ local blkdev0 blkdev1
+ blkdev0=$(echo $disks | awk '{ print $1 }')
+ blkdev1=$(echo $disks | awk '{ print $2 }')
+ $BTRFS_UTIL_PROG dev scan -u
+ _mkfs_dev -dsingle -msingle $blkdev0 $blkdev1
+ _mount $blkdev0 $SCRATCH_MNT
+
+ [ $(ls /sys/fs/btrfs/*/devinfo/*/allocation_hint | wc -l) -gt 0 ] ||
+ _notrun "Kernel with allocation_hint support required"
+
+ # use realpath because a link may confuse "btrfs prop get/set"
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev0) allocation_hint METADATA_PREFERRED
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev1) allocation_hint DATA_PREFERRED
+
+ $BTRFS_UTIL_PROG balance start --full-balance $SCRATCH_MNT
+
+ size=$(create_file x $(($MAXSIZE / 2)) )
+
+ btrfs_check_data_bg_in_disk $SCRATCH_MNT $blkdev1
+ btrfs_check_data_bg_not_in_disk $SCRATCH_MNT $blkdev0
+
+ umount $SCRATCH_MNT
+}
+
+setup_dmdev
+test_single_preferred_data
+
+echo "Silence is golden"
+# success, all done
+status=0
+exit
new file mode 100644
@@ -0,0 +1,3 @@
+QA output created by 255
+Done, had to relocate 3 out of 3 chunks
+Silence is golden
new file mode 100755
@@ -0,0 +1,123 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# FS QA Test No. 256
+#
+# Test the allocation_hint property of a btrfs filesystem
+#
+
+
+# size of the disk used; default 1GB
+MAXSIZE=$((1*1024*1024*1024))
+UUID=292afefb-6e8c-4fb3-9d12-8c4ecb1f238c
+NDEVS=4
+DEBUG=
+
+. ./common/preamble
+_begin_fstest auto quick allocation_hint
+
+seq=`basename $0`
+seqres="${RESULT_DIR}/${seq}"
+
+disks=""
+nodes=""
+
+# Override the default cleanup function.
+_cleanup()
+{
+ umount $SCRATCH_MNT &>/dev/null || true
+ for disk in $disks; do
+ _dmsetup_remove $disk
+ done
+}
+
+# Import common functions.
+. ./common/filter
+. ./common/filter.btrfs
+
+# real QA test starts here
+_supported_fs btrfs
+_require_block_device $SCRATCH_DEV
+_require_dm_target linear
+_require_scratch_nocheck
+_require_command "$WIPEFS_PROG" wipefs
+_try_wipe_scratch_devs
+
+_require_btrfs_property_get "allocation_hint"
+
+# dont' use _require_scratch_size because it pretend that the filesystem is
+# scratch_dev is consistent
+devsize=`_get_device_size $SCRATCH_DEV`
+[ $devsize -lt $((($MAXSIZE * $NDEVS + 100*1024*1024) / 1024)) ] &&
+ _notrun "scratch dev too small"
+
+setup_dmdev()
+{
+ # create some small size disks
+
+ size_in_sector=$(($MAXSIZE / 512))
+
+ off=0
+ for i in $(seq $NDEVS); do
+ node=dev${seq}test${i}
+ disk="/dev/mapper/$node"
+ disks="$disks $disk"
+ nodes="$nodes $node"
+ table="0 $size_in_sector linear $SCRATCH_DEV $off"
+ _dmsetup_create $node --table "$table" || \
+ _fail "setup dm device failed"
+ off=$(($off + $size_in_sector))
+ $WIPEFS_PROG -a $disk &>/dev/null
+ done
+}
+
+create_file() {
+ local fn=$SCRATCH_MNT/giant-file-$1
+ local size
+ if [ -n "$2" ]; then
+ size=count=$(($2 / 16 / 1024 / 1024 ))
+ else
+ size=
+ fi
+ dd if=/dev/zero of=$fn bs=16M oflag=direct $size &>/dev/null
+ ls -l $fn | awk '{ print $5 }'
+}
+
+#
+# mark some disks as DATA_PREFERRED and check that these are the only one used
+#
+test_raid1_preferred_data() {
+ local blkdev0 blkdev1 blkdev2 blkdev3
+ blkdev0=$(echo $disks | awk '{ print $1 }')
+ blkdev1=$(echo $disks | awk '{ print $2 }')
+ blkdev2=$(echo $disks | awk '{ print $3 }')
+ blkdev3=$(echo $disks | awk '{ print $4 }')
+ $BTRFS_UTIL_PROG dev scan -u
+ _mkfs_dev -U $UUID -draid1 -mraid1 $blkdev0 $blkdev1 $blkdev2 $blkdev3
+ _mount $blkdev0 $SCRATCH_MNT
+
+ [ $(ls /sys/fs/btrfs/*/devinfo/*/allocation_hint | wc -l) -gt 0 ] ||
+ _notrun "Kernel with allocation_hint support required"
+
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev0) allocation_hint METADATA_PREFERRED
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev1) allocation_hint METADATA_PREFERRED
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev2) allocation_hint DATA_PREFERRED
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev3) allocation_hint DATA_PREFERRED
+
+ $BTRFS_UTIL_PROG balance start --full-balance $SCRATCH_MNT
+
+ size=$(create_file x $(($MAXSIZE / 2)) )
+
+ btrfs_check_data_bg_in_disk $SCRATCH_MNT $blkdev2 $blkdev3
+ btrfs_check_data_bg_not_in_disk $SCRATCH_MNT $blkdev0 $blkdev1
+
+ umount $SCRATCH_MNT
+}
+
+setup_dmdev
+test_raid1_preferred_data
+
+echo "Silence is golden"
+# success, all done
+status=0
+exit
new file mode 100644
@@ -0,0 +1,3 @@
+QA output created by 256
+Done, had to relocate 3 out of 3 chunks
+Silence is golden
new file mode 100755
@@ -0,0 +1,123 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# FS QA Test No. 257
+#
+# Test the allocation_hint property of a btrfs filesystem
+#
+
+
+# size of the disk used; default 1GB
+MAXSIZE=$((1*1024*1024*1024))
+NDEVS=2
+DEBUG=
+
+. ./common/preamble
+_begin_fstest auto quick allocation_hint
+
+seq=`basename $0`
+seqres="${RESULT_DIR}/${seq}"
+
+disks=""
+nodes=""
+
+# Override the default cleanup function.
+_cleanup()
+{
+ umount $SCRATCH_MNT &>/dev/null || true
+ for disk in $disks; do
+ _dmsetup_remove $disk
+ done
+}
+
+# Import common functions.
+. ./common/filter
+. ./common/filter.btrfs
+
+# real QA test starts here
+_supported_fs btrfs
+_require_block_device $SCRATCH_DEV
+_require_dm_target linear
+_require_scratch_nocheck
+_require_command "$WIPEFS_PROG" wipefs
+_try_wipe_scratch_devs
+
+_require_btrfs_property_get "allocation_hint"
+
+# dont' use _require_scratch_size because it pretend that the filesystem is
+# scratch_dev is consistent
+devsize=`_get_device_size $SCRATCH_DEV`
+[ $devsize -lt $((($MAXSIZE * $NDEVS + 100*1024*1024) / 1024)) ] &&
+ _notrun "scratch dev too small"
+
+setup_dmdev()
+{
+ # create some small size disks
+
+ size_in_sector=$(($MAXSIZE / 512))
+
+ off=0
+ for i in $(seq $NDEVS); do
+ node=dev${seq}test${i}
+ disk="/dev/mapper/$node"
+ disks="$disks $disk"
+ nodes="$nodes $node"
+ table="0 $size_in_sector linear $SCRATCH_DEV $off"
+ _dmsetup_create $node --table "$table" || \
+ _fail "setup dm device failed"
+ off=$(($off + $size_in_sector))
+ $WIPEFS_PROG -a $disk &>/dev/null
+ done
+}
+
+create_file() {
+ local fn=$SCRATCH_MNT/giant-file-$1
+ local size
+ if [ -n "$2" ]; then
+ size=count=$(($2 / 16 / 1024 / 1024 ))
+ else
+ size=
+ fi
+ dd if=/dev/zero of=$fn bs=16M oflag=direct $size &>/dev/null
+ ls -l $fn | awk '{ print $5 }'
+}
+
+#
+# create a file and check that the Data BG is in the correct disk
+#
+test_single_data_only() {
+
+ local blkdev0 blkdev1
+ blkdev0=$(echo $disks | awk '{ print $1 }')
+ blkdev1=$(echo $disks | awk '{ print $2 }')
+ $BTRFS_UTIL_PROG dev scan -u
+ _mkfs_dev -dsingle -msingle $blkdev0 $blkdev1
+ _mount $blkdev0 $SCRATCH_MNT
+
+ [ $(ls /sys/fs/btrfs/*/devinfo/*/allocation_hint | wc -l) -gt 0 ] ||
+ _notrun "Kernel with allocation_hint support required"
+
+ # use realpath because a link may confuse "btrfs prop get/set"
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev0) allocation_hint METADATA_ONLY
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev1) allocation_hint DATA_ONLY
+
+ $BTRFS_UTIL_PROG balance start --full-balance $SCRATCH_MNT
+
+ size=$(create_file)
+
+ [ $size -gt $(($MAXSIZE * 2 * 2 / 3 )) ] && _fail "File too big: check mnt/"
+ [ $size -lt $(($MAXSIZE * 2 / 3 )) ] && _fail "File too small: check mnt/"
+
+ btrfs_check_data_bg_in_disk $SCRATCH_MNT $blkdev1
+ btrfs_check_data_bg_not_in_disk $SCRATCH_MNT $blkdev0
+
+ umount $SCRATCH_MNT
+}
+
+setup_dmdev
+test_single_data_only
+
+echo "Silence is golden"
+# success, all done
+status=0
+exit
new file mode 100644
@@ -0,0 +1,3 @@
+QA output created by 257
+Done, had to relocate 3 out of 3 chunks
+Silence is golden
new file mode 100755
@@ -0,0 +1,126 @@
+##! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# FS QA Test No. 258
+#
+# Test the allocation_hint property of a btrfs filesystem
+#
+
+
+# size of the disk used; default 1GB
+MAXSIZE=$((1*1024*1024*1024))
+NDEVS=4
+DEBUG=
+
+. ./common/preamble
+_begin_fstest auto quick allocation_hint
+
+seq=`basename $0`
+seqres="${RESULT_DIR}/${seq}"
+
+disks=""
+nodes=""
+
+# Override the default cleanup function.
+_cleanup()
+{
+ umount $SCRATCH_MNT &>/dev/null || true
+ for disk in $disks; do
+ _dmsetup_remove $disk
+ done
+}
+
+# Import common functions.
+. ./common/filter
+. ./common/filter.btrfs
+
+# real QA test starts here
+_supported_fs btrfs
+_require_block_device $SCRATCH_DEV
+_require_dm_target linear
+_require_scratch_nocheck
+_require_command "$WIPEFS_PROG" wipefs
+_try_wipe_scratch_devs
+
+_require_btrfs_property_get "allocation_hint"
+
+# dont' use _require_scratch_size because it pretend that the filesystem is
+# scratch_dev is consistent
+devsize=`_get_device_size $SCRATCH_DEV`
+[ $devsize -lt $((($MAXSIZE * $NDEVS + 100*1024*1024) / 1024)) ] &&
+ _notrun "scratch dev too small"
+
+setup_dmdev()
+{
+ # create some small size disks
+
+ size_in_sector=$(($MAXSIZE / 512))
+
+ off=0
+ for i in $(seq $NDEVS); do
+ node=dev${seq}test${i}
+ disk="/dev/mapper/$node"
+ disks="$disks $disk"
+ nodes="$nodes $node"
+ table="0 $size_in_sector linear $SCRATCH_DEV $off"
+ _dmsetup_create $node --table "$table" || \
+ _fail "setup dm device failed"
+ off=$(($off + $size_in_sector))
+ $WIPEFS_PROG -a $disk &>/dev/null
+ done
+}
+
+create_file() {
+ local fn=$SCRATCH_MNT/giant-file-$1
+ local size
+ if [ -n "$2" ]; then
+ size=count=$(($2 / 16 / 1024 / 1024 ))
+ else
+ size=
+ fi
+ dd if=/dev/zero of=$fn bs=16M oflag=direct $size &>/dev/null
+ ls -l $fn | awk '{ print $5 }'
+}
+
+#
+# fill a filesystem with disks tagged METADATA/DATA ONLY and check that only the
+# latter are used
+#
+test_raid1_data_only() {
+ local blkdev0 blkdev1 blkdev2 blkdev3
+ blkdev0=$(echo $disks | awk '{ print $1 }')
+ blkdev1=$(echo $disks | awk '{ print $2 }')
+ blkdev2=$(echo $disks | awk '{ print $3 }')
+ blkdev3=$(echo $disks | awk '{ print $4 }')
+ $BTRFS_UTIL_PROG dev scan -u
+ _mkfs_dev -draid1 -mraid1 $blkdev0 $blkdev1 $blkdev2 $blkdev3
+ _mount $blkdev0 $SCRATCH_MNT
+
+ [ $(ls /sys/fs/btrfs/*/devinfo/*/allocation_hint | wc -l) -gt 0 ] ||
+ _notrun "Kernel with allocation_hint support required"
+
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev0) allocation_hint METADATA_ONLY
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev1) allocation_hint METADATA_ONLY
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev2) allocation_hint DATA_ONLY
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev3) allocation_hint DATA_ONLY
+
+ $BTRFS_UTIL_PROG balance start --full-balance $SCRATCH_MNT
+
+ size=$(create_file x )
+
+ [ $size -gt $(($MAXSIZE * 2 * 2 / 3 )) ] && _fail "File too big: check mnt/"
+ [ $size -lt $(($MAXSIZE * 2 / 3 )) ] && _fail "File too small: check mnt/"
+
+ btrfs_check_data_bg_in_disk $SCRATCH_MNT $blkdev2 $blkdev3
+ btrfs_check_data_bg_not_in_disk $SCRATCH_MNT $blkdev0 $blkdev1
+
+ umount $SCRATCH_MNT
+}
+
+setup_dmdev
+test_raid1_data_only
+
+echo "Silence is golden"
+# success, all done
+status=0
+exit
new file mode 100644
@@ -0,0 +1,3 @@
+QA output created by 258
+Done, had to relocate 3 out of 3 chunks
+Silence is golden
new file mode 100755
@@ -0,0 +1,139 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# FS QA Test No. 259
+#
+# Test the allocation_hint property of a btrfs filesystem
+#
+
+
+# size of the disk used; default 1GB
+MAXSIZE=$((1*1024*1024*1024))
+NDEVS=2
+DEBUG=
+
+. ./common/preamble
+_begin_fstest auto quick allocation_hint
+
+seq=`basename $0`
+seqres="${RESULT_DIR}/${seq}"
+
+disks=""
+nodes=""
+
+# Override the default cleanup function.
+_cleanup()
+{
+ umount $SCRATCH_MNT &>/dev/null || true
+ for disk in $disks; do
+ _dmsetup_remove $disk
+ done
+}
+
+# Import common functions.
+. ./common/filter
+. ./common/filter.btrfs
+
+# real QA test starts here
+_supported_fs btrfs
+_require_block_device $SCRATCH_DEV
+_require_dm_target linear
+_require_scratch_nocheck
+_require_command "$WIPEFS_PROG" wipefs
+_try_wipe_scratch_devs
+
+_require_btrfs_property_get "allocation_hint"
+
+# dont' use _require_scratch_size because it pretend that the filesystem is
+# scratch_dev is consistent
+devsize=`_get_device_size $SCRATCH_DEV`
+[ $devsize -lt $((($MAXSIZE * $NDEVS + 100*1024*1024) / 1024)) ] &&
+ _notrun "scratch dev too small"
+
+setup_dmdev()
+{
+ # create some small size disks
+
+ size_in_sector=$(($MAXSIZE / 512))
+
+ off=2048
+ $WIPEFS_PROG -a $SCRATCH_DEV
+ for i in $(seq $NDEVS); do
+ node=dev${seq}test${i}
+ disk="/dev/mapper/$node"
+ disks="$disks $disk"
+ nodes="$nodes $node"
+ table="0 $size_in_sector linear $SCRATCH_DEV $off"
+ _dmsetup_create $node --table "$table" || \
+ _fail "setup dm device failed"
+ off=$(($off + $size_in_sector))
+ $WIPEFS_PROG -a $disk &>/dev/null
+ done
+}
+
+create_file() {
+ local fn=$SCRATCH_MNT/giant-file-$1
+ local size
+ if [ -n "$2" ]; then
+ size=count=$(($2 / 16 / 1024 / 1024 ))
+ else
+ size=
+ fi
+ dd if=/dev/zero of=$fn bs=16M oflag=direct $size &>/dev/null
+ ls -l $fn | awk '{ print $5 }'
+}
+
+#
+# create a file , switch the METADATA_ONLY <-> DATA_ONLY disk and check
+# that the data-bg are stored in the data disk
+#
+test_single_data_bouncing() {
+
+ local blkdev0 blkdev1
+ blkdev0=$(echo $disks | awk '{ print $1 }')
+ blkdev1=$(echo $disks | awk '{ print $2 }')
+ $BTRFS_UTIL_PROG dev scan -u
+ _mkfs_dev -dsingle -msingle $blkdev0 $blkdev1
+ _mount $blkdev0 $SCRATCH_MNT
+
+ [ $(ls /sys/fs/btrfs/*/devinfo/*/allocation_hint | wc -l) -gt 0 ] ||
+ _notrun "Kernel with allocation_hint support required"
+
+ # use realpath because a link may confuse "btrfs prop get/set"
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev0) allocation_hint METADATA_ONLY
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev1) allocation_hint DATA_ONLY
+
+ $BTRFS_UTIL_PROG balance start --full-balance $SCRATCH_MNT
+
+ size=$(create_file x $(($MAXSIZE * 2 / 4 )))
+
+ [ $size -gt $(($MAXSIZE * 2 / 3 )) ] && _fail "File too big: check mnt/"
+ [ $size -lt $(($MAXSIZE * 1 / 3 )) ] && _fail "File too small: check mnt/"
+
+ btrfs_check_data_bg_in_disk $SCRATCH_MNT $blkdev1
+ btrfs_check_data_bg_not_in_disk $SCRATCH_MNT $blkdev0
+
+ $BTRFS_UTIL_PROG balance start --full-balance $SCRATCH_MNT
+
+ btrfs_check_data_bg_in_disk $SCRATCH_MNT $blkdev1
+ btrfs_check_data_bg_not_in_disk $SCRATCH_MNT $blkdev0
+
+ # use realpath because a link may confuse "btrfs prop get/set"
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev1) allocation_hint METADATA_ONLY
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev0) allocation_hint DATA_ONLY
+
+ $BTRFS_UTIL_PROG balance start --full-balance $SCRATCH_MNT
+
+ btrfs_check_data_bg_in_disk $SCRATCH_MNT $blkdev0
+ btrfs_check_data_bg_not_in_disk $SCRATCH_MNT $blkdev1
+
+ umount $SCRATCH_MNT
+}
+
+setup_dmdev
+test_single_data_bouncing
+
+echo "Silence is golden"
+# success, all done
+status=0
+exit
new file mode 100644
@@ -0,0 +1,5 @@
+QA output created by 259
+Done, had to relocate 3 out of 3 chunks
+Done, had to relocate 5 out of 5 chunks
+Done, had to relocate 5 out of 5 chunks
+Silence is golden
new file mode 100755
@@ -0,0 +1,158 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# FS QA Test No. 260
+#
+# Test the allocation_hint property of a btrfs filesystem
+#
+
+
+# size of the disk used; default 1GB
+MAXSIZE=$((1*1024*1024*1024))
+NDEVS=4
+DEBUG=
+
+. ./common/preamble
+_begin_fstest auto quick allocation_hint
+
+seq=`basename $0`
+seqres="${RESULT_DIR}/${seq}"
+
+disks=""
+nodes=""
+
+# Override the default cleanup function.
+_cleanup()
+{
+ umount $SCRATCH_MNT &>/dev/null || true
+ for disk in $disks; do
+ _dmsetup_remove $disk
+ done
+}
+
+# Import common functions.
+. ./common/filter
+. ./common/filter.btrfs
+
+# real QA test starts here
+_supported_fs btrfs
+_require_block_device $SCRATCH_DEV
+_require_dm_target linear
+_require_scratch_nocheck
+_require_command "$WIPEFS_PROG" wipefs
+_try_wipe_scratch_devs
+
+_require_btrfs_property_get "allocation_hint"
+
+# dont' use _require_scratch_size because it pretend that the filesystem is
+# scratch_dev is consistent
+devsize=`_get_device_size $SCRATCH_DEV`
+[ $devsize -lt $((($MAXSIZE * $NDEVS + 100*1024*1024) / 1024)) ] &&
+ _notrun "scratch dev too small"
+
+setup_dmdev()
+{
+ # create some small size disks
+
+ size_in_sector=$(($MAXSIZE / 512))
+
+ off=2048
+ $WIPEFS_PROG -a $SCRATCH_DEV
+ for i in $(seq $NDEVS); do
+ node=dev${seq}test${i}
+ disk="/dev/mapper/$node"
+ disks="$disks $disk"
+ nodes="$nodes $node"
+ table="0 $size_in_sector linear $SCRATCH_DEV $off"
+ _dmsetup_create $node --table "$table" || \
+ _fail "setup dm device failed"
+ off=$(($off + $size_in_sector))
+ $WIPEFS_PROG -a $disk &>/dev/null
+ done
+}
+
+create_file() {
+ local fn=$SCRATCH_MNT/giant-file-$1
+ local size
+ if [ -n "$2" ]; then
+ size=count=$(($2 / 16 / 1024 / 1024 ))
+ else
+ size=
+ fi
+ dd if=/dev/zero of=$fn bs=16M oflag=direct $size &>/dev/null
+ ls -l $fn | awk '{ print $5 }'
+}
+
+#
+# create files that consume the space avaiable on the disks, and check
+# that the order of allocation is maintained
+#
+test_single_progressive_fill_data() {
+
+ local blkdev0 blkdev1 blkdev2 blkdev3
+ blkdev0=$(echo $disks | awk '{ print $1 }')
+ blkdev1=$(echo $disks | awk '{ print $2 }')
+ blkdev2=$(echo $disks | awk '{ print $3 }')
+ blkdev3=$(echo $disks | awk '{ print $4 }')
+ $BTRFS_UTIL_PROG dev scan -u
+ _mkfs_dev -dsingle -msingle $blkdev0 $blkdev1 $blkdev2 $blkdev3
+ _mount $blkdev0 $SCRATCH_MNT
+
+ [ $(ls /sys/fs/btrfs/*/devinfo/*/allocation_hint | wc -l) -gt 0 ] ||
+ _notrun "Kernel with allocation_hint support required"
+
+ # use realpath because a link may confuse "btrfs prop get/set"
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev0) allocation_hint METADATA_ONLY
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev1) allocation_hint METADATA_PREFERRED
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev2) allocation_hint DATA_PREFERRED
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev3) allocation_hint DATA_ONLY
+
+ $BTRFS_UTIL_PROG balance start --full-balance $SCRATCH_MNT
+
+ size=$(create_file x $(( $MAXSIZE / 3 )))
+
+ for i in 1 2 3; do
+ btrfs_check_data_bg_in_disk $SCRATCH_MNT $blkdev3
+ btrfs_check_data_bg_not_in_disk $SCRATCH_MNT $blkdev1 $blkdev2 $blkdev0
+ $BTRFS_UTIL_PROG balance start --full-balance $SCRATCH_MNT &>/dev/null
+ done
+
+ # fill $blkdev3 then $blkdev2
+
+ size=$(create_file y $(( $MAXSIZE )))
+
+ for i in 1 2 3; do
+ btrfs_check_data_bg_in_disk $SCRATCH_MNT $blkdev3 $blkdev2
+ btrfs_check_data_bg_not_in_disk $SCRATCH_MNT $blkdev1 $blkdev0
+ $BTRFS_UTIL_PROG balance start --full-balance $SCRATCH_MNT &>/dev/null
+ done
+
+ # fill $blkdev3 then $blkdev2, then $blkdev1
+
+ size=$(create_file z $(( $MAXSIZE )))
+
+ for i in 1 2 3; do
+ btrfs_check_data_bg_in_disk $SCRATCH_MNT $blkdev3 $blkdev2 $blkdev1
+ btrfs_check_data_bg_not_in_disk $SCRATCH_MNT $blkdev0
+ $BTRFS_UTIL_PROG balance start --full-balance $SCRATCH_MNT &>/dev/null
+ done
+
+ # fill the disk
+
+ size=$(create_file w )
+
+ # when the disk is filled not balance is possible
+ btrfs_check_data_bg_in_disk $SCRATCH_MNT $blkdev3 $blkdev2 $blkdev1
+ btrfs_check_data_bg_not_in_disk $SCRATCH_MNT $blkdev0
+
+
+ umount $SCRATCH_MNT
+}
+
+setup_dmdev
+test_single_progressive_fill_data
+
+echo "Silence is golden"
+# success, all done
+status=0
+exit
new file mode 100644
@@ -0,0 +1,3 @@
+QA output created by 260
+Done, had to relocate 3 out of 3 chunks
+Silence is golden
new file mode 100755
@@ -0,0 +1,144 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# FS QA Test No. 261
+#
+# Test the allocation_hint property of a btrfs filesystem
+#
+
+
+# size of the disk used; default 1GB
+MAXSIZE=$((1*1024*1024*1024))
+NDEVS=5
+DEBUG=
+
+. ./common/preamble
+_begin_fstest auto quick allocation_hint
+
+seq=`basename $0`
+seqres="${RESULT_DIR}/${seq}"
+
+disks=""
+nodes=""
+
+# Override the default cleanup function.
+_cleanup()
+{
+ umount $SCRATCH_MNT &>/dev/null || true
+ for disk in $disks; do
+ _dmsetup_remove $disk
+ done
+}
+
+# Import common functions.
+. ./common/filter
+. ./common/filter.btrfs
+
+# real QA test starts here
+_supported_fs btrfs
+_require_block_device $SCRATCH_DEV
+_require_dm_target linear
+_require_scratch_nocheck
+_require_command "$WIPEFS_PROG" wipefs
+_try_wipe_scratch_devs
+
+_require_btrfs_property_get "allocation_hint"
+
+# dont' use _require_scratch_size because it pretend that the filesystem is
+# scratch_dev is consistent
+devsize=`_get_device_size $SCRATCH_DEV`
+[ $devsize -lt $((($MAXSIZE * $NDEVS + 100*1024*1024) / 1024)) ] &&
+ _notrun "scratch dev too small"
+
+setup_dmdev()
+{
+ # create some small size disks
+
+ size_in_sector=$(($MAXSIZE / 512))
+
+ off=2048
+ $WIPEFS_PROG -a $SCRATCH_DEV
+ for i in $(seq $NDEVS); do
+ node=dev${seq}test${i}
+ disk="/dev/mapper/$node"
+ disks="$disks $disk"
+ nodes="$nodes $node"
+ table="0 $size_in_sector linear $SCRATCH_DEV $off"
+ _dmsetup_create $node --table "$table" || \
+ _fail "setup dm device failed"
+ off=$(($off + $size_in_sector))
+ $WIPEFS_PROG -a $disk &>/dev/null
+ done
+}
+
+create_file() {
+ local fn=$SCRATCH_MNT/giant-file-$1
+ local size
+ if [ -n "$2" ]; then
+ size=count=$(($2 / 16 / 1024 / 1024 ))
+ else
+ size=
+ fi
+ dd if=/dev/zero of=$fn bs=16M oflag=direct $size &>/dev/null
+ ls -l $fn | awk '{ print $5 }'
+}
+
+#
+# create files that consume the space avaiable on the disks, and check
+# that the order of allocation is maintained
+#
+test_raid1_progressive_fill_data() {
+
+ local blkdev0 blkdev1 blkdev2 blkdev3
+ blkdev0=$(echo $disks | awk '{ print $1 }')
+ blkdev1=$(echo $disks | awk '{ print $2 }')
+ blkdev2=$(echo $disks | awk '{ print $3 }')
+ blkdev3=$(echo $disks | awk '{ print $4 }')
+ blkdev4=$(echo $disks | awk '{ print $5 }')
+ $BTRFS_UTIL_PROG dev scan -u
+ _mkfs_dev -dRAID1 -msingle $blkdev0 $blkdev1 $blkdev2 $blkdev3 $blkdev4
+ _mount $blkdev0 $SCRATCH_MNT
+
+ [ $(ls /sys/fs/btrfs/*/devinfo/*/allocation_hint | wc -l) -gt 0 ] ||
+ _notrun "Kernel with allocation_hint support required"
+
+ # use realpath because a link may confuse "btrfs prop get/set"
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev0) allocation_hint METADATA_ONLY
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev1) allocation_hint METADATA_PREFERRED
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev2) allocation_hint DATA_PREFERRED
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev3) allocation_hint DATA_ONLY
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev4) allocation_hint DATA_ONLY
+
+ $BTRFS_UTIL_PROG balance start --full-balance $SCRATCH_MNT
+
+ size=$(create_file x $(( $MAXSIZE / 5 )))
+
+ # fill $blkdev3 $blkdev4
+ for i in 1 2 3; do
+ btrfs_check_data_bg_in_disk $SCRATCH_MNT $blkdev3 $blkdev4
+ btrfs_check_data_bg_not_in_disk $SCRATCH_MNT $blkdev1 $blkdev2 $blkdev0
+
+ $BTRFS_UTIL_PROG balance start --full-balance $SCRATCH_MNT &>/dev/null
+ done
+
+ # fill $blkdev3 $blkdev4, then $blkdev1 and $blkdev2
+ size=$(create_file y $(( $MAXSIZE )))
+
+ for i in 1 2 3; do
+ btrfs_check_data_bg_in_disk $SCRATCH_MNT $blkdev3 $blkdev2 $blkdev4 $blkdev1
+ btrfs_check_data_bg_not_in_disk $SCRATCH_MNT $blkdev0
+
+ $BTRFS_UTIL_PROG balance start --full-balance $SCRATCH_MNT &>/dev/null
+ done
+
+
+ umount $SCRATCH_MNT
+}
+
+setup_dmdev
+test_raid1_progressive_fill_data
+
+echo "Silence is golden"
+# success, all done
+status=0
+exit
new file mode 100755
@@ -0,0 +1,3 @@
+QA output created by 261
+Done, had to relocate 3 out of 3 chunks
+Silence is golden
new file mode 100755
@@ -0,0 +1,121 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# FS QA Test No. 262
+#
+# Test the allocation_hint property of a btrfs filesystem
+#
+
+
+# size of the disk used; default 1GB
+MAXSIZE=$((512*1024*1024))
+NDEVS=2
+DEBUG=
+
+. ./common/preamble
+_begin_fstest auto allocation_hint
+
+seq=`basename $0`
+seqres="${RESULT_DIR}/${seq}"
+
+disks=""
+nodes=""
+
+# Override the default cleanup function.
+_cleanup()
+{
+ umount $SCRATCH_MNT &>/dev/null || true
+ for disk in $disks; do
+ _dmsetup_remove $disk
+ done
+}
+
+# Import common functions.
+. ./common/filter
+. ./common/filter.btrfs
+
+# real QA test starts here
+_supported_fs btrfs
+_require_block_device $SCRATCH_DEV
+_require_dm_target linear
+_require_scratch_nocheck
+_require_command "$WIPEFS_PROG" wipefs
+_try_wipe_scratch_devs
+
+_require_btrfs_property_get "allocation_hint"
+
+# dont' use _require_scratch_size because it pretend that the filesystem is
+# scratch_dev is consistent
+devsize=`_get_device_size $SCRATCH_DEV`
+[ $devsize -lt $((($MAXSIZE * $NDEVS + 100*1024*1024) / 1024)) ] &&
+ _notrun "scratch dev too small"
+
+setup_dmdev()
+{
+ # create some small size disks
+
+ size_in_sector=$(($MAXSIZE / 512))
+
+ off=0
+ for i in $(seq $NDEVS); do
+ node=dev${seq}test${i}
+ disk="/dev/mapper/$node"
+ disks="$disks $disk"
+ nodes="$nodes $node"
+ table="0 $size_in_sector linear $SCRATCH_DEV $off"
+ _dmsetup_create $node --table "$table" || \
+ _fail "setup dm device failed"
+ off=$(($off + $size_in_sector))
+ $WIPEFS_PROG -a $disk &>/dev/null
+ done
+}
+
+create_small_file() {
+ local fn=$SCRATCH_MNT/small-file-$1
+ local size=$2
+ dd if=/dev/zero of=$fn bs=$size oflag=direct count=1 &>/dev/null
+ ls -l $fn | awk '{ print $5 }'
+}
+
+#
+# near fill all the metadata dedicated disk, and check that the data dedicated
+# is unused
+#
+test_single_preferred_metadata_slow() {
+
+ local blkdev0 blkdev1
+ blkdev0=$(echo $disks | awk '{ print $1 }')
+ blkdev1=$(echo $disks | awk '{ print $2 }')
+ $BTRFS_UTIL_PROG dev scan -u
+ _mkfs_dev -dsingle -msingle $blkdev0 $blkdev1
+ _mount $blkdev0 $SCRATCH_MNT
+
+ [ $(ls /sys/fs/btrfs/*/devinfo/*/allocation_hint | wc -l) -gt 0 ] ||
+ _notrun "Kernel with allocation_hint support required"
+
+ # use realpath because a link may confuse "btrfs prop get/set"
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev0) allocation_hint METADATA_PREFERRED
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev1) allocation_hint DATA_PREFERRED
+
+ $BTRFS_UTIL_PROG balance start --full-balance $SCRATCH_MNT
+
+ # create files that fit in the metadata node (i.e. size <= 2048 bytes)
+ # fill up to 7/10 of a disk
+ fnsize=2048
+ for i in $(seq $(( $MAXSIZE / $fnsize * 700 / 1000))); do
+ create_small_file $i $fnsize &>/dev/null
+ done
+
+ btrfs_check_metadata_bg_in_disk $SCRATCH_MNT $blkdev0
+ btrfs_check_metadata_bg_not_in_disk $SCRATCH_MNT $blkdev1
+
+ umount $SCRATCH_MNT
+}
+
+setup_dmdev
+test_single_preferred_metadata_slow
+
+echo "Silence is golden"
+# success, all done
+status=0
+exit
new file mode 100644
@@ -0,0 +1,3 @@
+QA output created by 262
+Done, had to relocate 3 out of 3 chunks
+Silence is golden
new file mode 100755
@@ -0,0 +1,123 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# FS QA Test No. 263
+#
+# Test the allocation_hint property of a btrfs filesystem
+#
+
+
+# size of the disk used; default 1GB
+MAXSIZE=$((512*1024*1024))
+NDEVS=4
+DEBUG=
+
+. ./common/preamble
+_begin_fstest auto allocation_hint
+
+seq=`basename $0`
+seqres="${RESULT_DIR}/${seq}"
+
+disks=""
+nodes=""
+
+# Override the default cleanup function.
+_cleanup()
+{
+ umount $SCRATCH_MNT &>/dev/null || true
+ for disk in $disks; do
+ _dmsetup_remove $disk
+ done
+}
+
+# Import common functions.
+. ./common/filter
+. ./common/filter.btrfs
+
+# real QA test starts here
+_supported_fs btrfs
+_require_block_device $SCRATCH_DEV
+_require_dm_target linear
+_require_scratch_nocheck
+_require_command "$WIPEFS_PROG" wipefs
+_try_wipe_scratch_devs
+
+_require_btrfs_property_get "allocation_hint"
+
+# dont' use _require_scratch_size because it pretend that the filesystem is
+# scratch_dev is consistent
+devsize=`_get_device_size $SCRATCH_DEV`
+[ $devsize -lt $((($MAXSIZE * $NDEVS + 100*1024*1024) / 1024)) ] &&
+ _notrun "scratch dev too small"
+
+setup_dmdev()
+{
+ # create some small size disks
+
+ size_in_sector=$(($MAXSIZE / 512))
+
+ off=0
+ for i in $(seq $NDEVS); do
+ node=dev${seq}test${i}
+ disk="/dev/mapper/$node"
+ disks="$disks $disk"
+ nodes="$nodes $node"
+ table="0 $size_in_sector linear $SCRATCH_DEV $off"
+ _dmsetup_create $node --table "$table" || \
+ _fail "setup dm device failed"
+ off=$(($off + $size_in_sector))
+ $WIPEFS_PROG -a $disk &>/dev/null
+ done
+}
+
+create_small_file() {
+ local fn=$SCRATCH_MNT/small-file-$1
+ local size=$2
+ dd if=/dev/zero of=$fn bs=$size oflag=direct count=1 &>/dev/null
+ ls -l $fn | awk '{ print $5 }'
+}
+
+#
+# near fill all the metadata dedicated disks, and check that the data dedicated
+# are unused
+#
+test_raid1_preferred_metadata_slow() {
+ local blkdev0 blkdev1 blkdev2 blkdev3
+ blkdev0=$(echo $disks | awk '{ print $1 }')
+ blkdev1=$(echo $disks | awk '{ print $2 }')
+ blkdev2=$(echo $disks | awk '{ print $3 }')
+ blkdev3=$(echo $disks | awk '{ print $4 }')
+ $BTRFS_UTIL_PROG dev scan -u
+ _mkfs_dev -draid1 -mraid1 $blkdev0 $blkdev1 $blkdev2 $blkdev3
+ _mount $blkdev0 $SCRATCH_MNT
+
+ [ $(ls /sys/fs/btrfs/*/devinfo/*/allocation_hint | wc -l) -gt 0 ] ||
+ _notrun "Kernel with allocation_hint support required"
+
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev0) allocation_hint METADATA_PREFERRED
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev1) allocation_hint METADATA_PREFERRED
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev2) allocation_hint DATA_PREFERRED
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev3) allocation_hint DATA_PREFERRED
+
+ $BTRFS_UTIL_PROG balance start --full-balance $SCRATCH_MNT
+
+ # create files that fit in the metadata node (i.e. size <= 2048 bytes)
+ # fill up to 6/10 of a disk
+ fnsize=2048
+ for i in $(seq $(( $MAXSIZE / $fnsize * 600 / 1000))); do
+ create_small_file $i $fnsize &>/dev/null
+ done
+
+ btrfs_check_metadata_bg_in_disk $SCRATCH_MNT $blkdev0 $blkdev1
+ btrfs_check_metadata_bg_not_in_disk $SCRATCH_MNT $blkdev2 $blkdev3
+
+ umount $SCRATCH_MNT
+}
+
+setup_dmdev
+test_raid1_preferred_metadata_slow
+
+echo "Silence is golden"
+# success, all done
+status=0
+exit
new file mode 100644
@@ -0,0 +1,3 @@
+QA output created by 263
+Done, had to relocate 3 out of 3 chunks
+Silence is golden
new file mode 100755
@@ -0,0 +1,121 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# FS QA Test No. 264
+#
+# Test the allocation_hint property of a btrfs filesystem
+#
+
+
+# size of the disk used; default 1GB
+MAXSIZE=$((1*1024*1024*1024))
+NDEVS=2
+DEBUG=
+
+. ./common/preamble
+_begin_fstest auto quick allocation_hint
+
+seq=`basename $0`
+seqres="${RESULT_DIR}/${seq}"
+
+# Override the default cleanup function.
+disks=""
+nodes=""
+
+_cleanup()
+{
+ umount $SCRATCH_MNT &>/dev/null || true
+ for disk in $disks; do
+ _dmsetup_remove $disk
+ done
+}
+
+# Import common functions.
+. ./common/filter
+. ./common/filter.btrfs
+
+# real QA test starts here
+_supported_fs btrfs
+_require_block_device $SCRATCH_DEV
+_require_dm_target linear
+_require_scratch_nocheck
+_require_command "$WIPEFS_PROG" wipefs
+_try_wipe_scratch_devs
+
+_require_btrfs_property_get "allocation_hint"
+
+# dont' use _require_scratch_size because it pretend that the filesystem is
+# scratch_dev is consistent
+devsize=`_get_device_size $SCRATCH_DEV`
+[ $devsize -lt $((($MAXSIZE * $NDEVS + 100*1024*1024) / 1024)) ] &&
+ _notrun "scratch dev too small"
+
+setup_dmdev()
+{
+ # create some small size disks
+
+ size_in_sector=$(($MAXSIZE / 512))
+
+ off=0
+ for i in $(seq $NDEVS); do
+ node=dev${seq}test${i}
+ disk="/dev/mapper/$node"
+ disks="$disks $disk"
+ nodes="$nodes $node"
+ table="0 $size_in_sector linear $SCRATCH_DEV $off"
+ _dmsetup_create $node --table "$table" || \
+ _fail "setup dm device failed"
+ off=$(($off + $size_in_sector))
+ $WIPEFS_PROG -a $disk &>/dev/null
+ done
+}
+
+create_file() {
+ local fn=$SCRATCH_MNT/giant-file-$1
+ local size
+ if [ -n "$2" ]; then
+ size=count=$(($2 / 16 / 1024 / 1024 ))
+ else
+ size=
+ fi
+ dd if=/dev/zero of=$fn bs=16M oflag=direct $size &>/dev/null
+ ls -l $fn | awk '{ print $5 }'
+}
+
+#
+# create a file and check that the Data BG is in the correct disk
+# force the compression flag
+#
+test_single_preferred_data_compression() {
+
+ local blkdev0 blkdev1
+ blkdev0=$(echo $disks | awk '{ print $1 }')
+ blkdev1=$(echo $disks | awk '{ print $2 }')
+ $BTRFS_UTIL_PROG dev scan -u
+ _mkfs_dev -dsingle -msingle $blkdev0 $blkdev1
+ _mount -o compress $blkdev0 $SCRATCH_MNT
+
+ [ $(ls /sys/fs/btrfs/*/devinfo/*/allocation_hint | wc -l) -gt 0 ] ||
+ _notrun "Kernel with allocation_hint support required"
+
+ # use realpath because a link may confuse "btrfs prop get/set"
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev0) allocation_hint METADATA_PREFERRED
+ $BTRFS_UTIL_PROG prop set $(realpath $blkdev1) allocation_hint DATA_PREFERRED
+
+ $BTRFS_UTIL_PROG balance start --full-balance $SCRATCH_MNT
+
+ size=$(create_file x $(($MAXSIZE / 2)) )
+
+ btrfs_check_data_bg_in_disk $SCRATCH_MNT $blkdev1
+ btrfs_check_data_bg_not_in_disk $SCRATCH_MNT $blkdev0
+
+ umount $SCRATCH_MNT
+}
+
+setup_dmdev
+test_single_preferred_data_compression
+
+echo "Silence is golden"
+# success, all done
+status=0
+exit
new file mode 100644
@@ -0,0 +1,3 @@
+QA output created by 264
+Done, had to relocate 3 out of 3 chunks
+Silence is golden