#! /bin/bash # SPDX-License-Identifier: GPL-2.0 # Copyright (c) 2018 Red Hat, Inc. All Rights Reserved. # # FS QA Test 443 # # Regression test for the XFS rmapbt based extent swap algorithm. The extent # swap algorithm for rmapbt=1 filesystems unmaps/remaps individual extents to # rectify the rmapbt for each extent swapped between inodes. If one of the # inodes happens to straddle the extent <-> btree format boundary (which can # vary depending on inode size), the unmap/remap sequence can bounce the inodes # back and forth between formats many times during the swap. Since extent -> # btree format conversion requires a block allocation, this can consume more # blocks than expected, lead to block reservation overrun and free space # accounting inconsistency. # seq=`basename $0` seqres=$RESULT_DIR/$seq echo "QA output created by $seq" here=`pwd` tmp=/tmp/$$ status=1 # failure is the default! trap "_cleanup; exit \$status" 0 1 2 3 15 _cleanup() { cd / rm -f $tmp.* } # get standard environment, filters and checks . ./common/rc . ./common/filter . ./common/punch # remove previous $seqres.full before test rm -f $seqres.full # real QA test starts here # Modify as appropriate. _supported_fs generic _supported_os Linux _require_scratch _require_test_program "punch-alternating" _require_xfs_io_command "falloc" _require_xfs_io_command "fpunch" _require_xfs_io_command "swapext" _scratch_mkfs | _filter_mkfs >> $seqres.full 2> $tmp.mkfs _scratch_mount # get fs block size . $tmp.mkfs file1=$SCRATCH_MNT/file1 file2=$SCRATCH_MNT/file2 # The goal is run an extent swap where one of the associated files has the # minimum number of extents to remain in btree format. First, create a couple # files with large enough extent counts (200 or so should be plenty) to ensure # btree format on the largest possible inode size filesystems. $XFS_IO_PROG -fc "falloc 0 $((400 * dbsize))" $file1 $here/src/punch-alternating $file1 $XFS_IO_PROG -fc "falloc 0 $((400 * dbsize))" $file2 $here/src/punch-alternating $file2 # Now run an extent swap at every possible extent count down to 0. Depending on # inode size, one of these swaps will cover the boundary case between extent and # btree format. for i in $(seq 1 2 399); do # punch one extent from the tmpfile and swap $XFS_IO_PROG -c "fpunch $((i * dbsize)) $dbsize" $file2 $XFS_IO_PROG -c "swapext $file2" $file1 # punch the same extent from the old fork (now in file2) to resync the # extent counts and repeat $XFS_IO_PROG -c "fpunch $((i * dbsize)) $dbsize" $file2 done # sanity check that no extents are left over $XFS_IO_PROG -c "fiemap" $file1 | _filter_fiemap $XFS_IO_PROG -c "fiemap" $file2 | _filter_fiemap # failure results in fs corruption and possible assert failure echo Silence is golden # success, all done status=0 exit