xfs/{422,517}: kill background jobs on test termination master v2022.06.26
authorAmir Goldstein <amir73il@gmail.com>
Tue, 21 Jun 2022 17:37:29 +0000 (20:37 +0300)
committerZorro Lang <zlang@kernel.org>
Fri, 24 Jun 2022 16:27:11 +0000 (00:27 +0800)
Those tests failed to cleanup background jobs properly after test
is interrupted and even sometimes when it completed succefully.

xfs/517 would sometime fails randomally with this false positive error:
     QA output created by 517
     Format and populate
     Concurrent fsmap and freeze
    +Terminated
     Test done

The tests have several background sub-shells that spawn short lived
programs in a loop.  By killing the spawned programs using killall,
killall could find no process to kill and the sub-shell loop could still
spawn another process that is not going to be killed and in the worst
case, the freeze_loop() could spawn the xfs_io "freeze" command after
test has thawn the fs before exit, which leaves the fs frozen after the
test.

The "Terminated" output is emitted by the sub-shell when killing the
programs that it has spawned when the loop did not finish before test
timeout.  By killing the sub-shell and not the spawned programs, we
avoid the false positive "Terminated" error.

Use a helper to perform this cleanup dance:
First kill and wait the freeze_loop so it won't try to freeze fs again
Then make sure fs is not frozen.
Then kill and wait for the rest of the sub-shells, because
if fs is frozen a killed writer process will never exit.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Zorro Lang <zlang@kernel.org>
87 files changed:
README
check
common/btrfs
common/config
common/filter
common/overlay
common/rc
common/repair
common/report
common/xfs
src/attr_replace_test.c
src/splice-test.c
tests/btrfs/140
tests/btrfs/141
tests/btrfs/142
tests/btrfs/143
tests/btrfs/157
tests/btrfs/177
tests/btrfs/215
tests/btrfs/220
tests/btrfs/258
tests/btrfs/259
tests/btrfs/265 [new file with mode: 0755]
tests/btrfs/265.out [new file with mode: 0644]
tests/btrfs/266 [new file with mode: 0755]
tests/btrfs/266.out [new file with mode: 0644]
tests/btrfs/267 [new file with mode: 0755]
tests/btrfs/267.out [new file with mode: 0644]
tests/ceph/001
tests/ceph/002.out
tests/ext4/053
tests/generic/020
tests/generic/038
tests/generic/068
tests/generic/085
tests/generic/139
tests/generic/280
tests/generic/342
tests/generic/390
tests/generic/459
tests/generic/486
tests/generic/491
tests/generic/502
tests/generic/506
tests/generic/526
tests/generic/527
tests/generic/591
tests/generic/591.out
tests/generic/623
tests/generic/631
tests/generic/646
tests/generic/649
tests/xfs/011
tests/xfs/018 [new file with mode: 0755]
tests/xfs/018.out [new file with mode: 0644]
tests/xfs/081 [new file with mode: 0755]
tests/xfs/081.out [new file with mode: 0644]
tests/xfs/119
tests/xfs/122
tests/xfs/145
tests/xfs/154
tests/xfs/154.out
tests/xfs/158
tests/xfs/158.out
tests/xfs/167
tests/xfs/177
tests/xfs/189
tests/xfs/270
tests/xfs/270.out
tests/xfs/297
tests/xfs/318
tests/xfs/325
tests/xfs/422
tests/xfs/423
tests/xfs/438
tests/xfs/513
tests/xfs/517
tests/xfs/538
tests/xfs/538.out
tests/xfs/539
tests/xfs/542
tests/xfs/545
tests/xfs/547 [new file with mode: 0755]
tests/xfs/547.out [new file with mode: 0644]
tests/xfs/548 [new file with mode: 0755]
tests/xfs/548.out [new file with mode: 0644]
tools/mkgroupfile

diff --git a/README b/README
index 7da66cb66a109fd8ebd1d0ea5edb633240e03438..80d148be82b4a8ed2b4868532bb139c639b6ca2f 100644 (file)
--- a/README
+++ b/README
@@ -368,19 +368,41 @@ Test script environment:
 
      6. Test group membership: Each test can be associated with any number
        of groups for convenient selection of subsets of tests.  Group names
-       can be any sequence of non-whitespace characters.  Test authors
-       associate a test with groups by passing the names of those groups as
-       arguments to the _begin_fstest function.  For example, the code:
+       must  be human readable using only characters in the set [:alnum:_-].
 
-       _begin_fstest auto quick subvol snapshot
+       Test authors associate a test with groups by passing the names of those
+       groups as arguments to the _begin_fstest function. While _begin_fstests
+       is a shell function that must be called at the start of a test to
+       initialise the test environment correctly, the the build infrastructure
+       also scans the test files for _begin_fstests invocations. It does this
+       to compile the group lists that are used to determine which tests to run
+       when `check` is executed. In other words, test files files must call
+       _begin_fstest with their intended groups or they will not be run.
+
+       However, because the build infrastructure also uses _begin_fstests as
+       a defined keyword, addition restrictions are placed on how it must be
+       formatted:
+
+       (a) It must be a single line with no multi-line continuations.
+
+       (b) group names should be separated by spaces and not other whitespace
+
+       (c) A '#' placed anywhere in the list, even in the middle of a group
+           name, will cause everything from the # to the end of the line to be
+           ignored.
+
+       For example, the code:
+
+       _begin_fstest auto quick subvol snapshot # metadata
 
        associates the current test with the "auto", "quick", "subvol", and
-       "snapshot" groups.  It is not necessary to specify the "all" group
-       in the list because that group is computed at run time.
+       "snapshot" groups. Because "metadata" is after the "#" comment
+       delimiter, it is ignored by the build infrastructure and so it will not
+       be associated with that group.
+
+       It is not necessary to specify the "all" group in the list because that
+       group is always computed at run time from the group lists.
 
-       The build process scans test files for _begin_fstest invocations and
-       compiles the group list from that information.  In other words, test
-       files must call _begin_fstest or they will not be run.
 
 Verified output:
 
diff --git a/check b/check
index de11b37e1346806d80158521b28a1752aeb63092..2ea2920f76329b1ba79045242d5fc5862147b78c 100755 (executable)
--- a/check
+++ b/check
@@ -8,13 +8,10 @@ tmp=/tmp/$$
 status=0
 needwrap=true
 needsum=true
-n_try=0
-try=""
-n_bad=0
+try=()
 sum_bad=0
-bad=""
-n_notrun=0
-notrun=""
+bad=()
+notrun=()
 interrupt=true
 diff="diff -u"
 showme=false
@@ -277,15 +274,13 @@ while [ $# -gt 0 ]; do
        case "$1" in
        -\? | -h | --help) usage ;;
 
-       -nfs)           FSTYP=nfs ;;
-       -glusterfs)     FSTYP=glusterfs ;;
-       -cifs)          FSTYP=cifs ;;
-       -9p)            FSTYP=9p ;;
-       -virtiofs)      FSTYP=virtiofs ;;
-       -overlay)       FSTYP=overlay; export OVERLAY=true ;;
-       -pvfs2)         FSTYP=pvfs2 ;;
-       -tmpfs)         FSTYP=tmpfs ;;
-       -ubifs)         FSTYP=ubifs ;;
+       -nfs|-glusterfs|-cifs|-9p|-virtiofs|-pvfs2|-tmpfs|-ubifs)
+               FSTYP="${1:1}"
+               ;;
+       -overlay)
+               FSTYP=overlay
+               export OVERLAY=true
+               ;;
 
        -g)     group=$2 ; shift ;
                GROUP_LIST="$GROUP_LIST ${group//,/ }"
@@ -414,10 +409,9 @@ fi
 
 _wipe_counters()
 {
-       n_try="0"
-       n_bad="0"
-       n_notrun="0"
-       unset try notrun bad
+       try=()
+       notrun=()
+       bad=()
 }
 
 _global_log() {
@@ -432,13 +426,12 @@ _wrapup()
        seq="check"
        check="$RESULT_BASE/check"
 
-       if $showme; then
-               if $needwrap; then
-                       if $do_report; then
-                               _make_section_report
-                       fi
-                       needwrap=false
+       if $showme && $needwrap; then
+               if $do_report; then
+                       # $showme = all selected tests are notrun (no tries)
+                       _make_section_report "${#notrun[*]}" "0" "${#notrun[*]}"
                fi
+               needwrap=false
        elif $needwrap; then
                if [ -f $check.time -a -f $tmp.time ]; then
                        cat $check.time $tmp.time  \
@@ -461,12 +454,12 @@ _wrapup()
 
                echo "SECTION       -- $section" >>$tmp.summary
                echo "=========================" >>$tmp.summary
-               if [ ! -z "$n_try" -a $n_try != 0 ]; then
+               if ((${#try[*]} > 0)); then
                        if [ $brief_test_summary == "false" ]; then
-                               echo "Ran:$try"
-                               echo "Ran:$try" >>$tmp.summary
+                               echo "Ran: ${try[*]}"
+                               echo "Ran: ${try[*]}" >>$tmp.summary
                        fi
-                       _global_log "Ran:$try"
+                       _global_log "Ran: ${try[*]}"
                fi
 
                $interrupt && echo "Interrupted!" | tee -a $check.log
@@ -475,34 +468,34 @@ _wrapup()
                                ${REPORT_DIR}/check.log
                fi
 
-               if [ ! -z "$notrun" ]; then
+               if ((${#notrun[*]} > 0)); then
                        if [ $brief_test_summary == "false" ]; then
-                               echo "Not run:$notrun"
-                               echo "Not run:$notrun" >>$tmp.summary
+                               echo "Not run: ${notrun[*]}"
+                               echo "Not run: ${notrun[*]}" >>$tmp.summary
                        fi
-                       _global_log "Not run:$notrun"
+                       _global_log "Not run: ${notrun[*]}"
                fi
 
-               if [ ! -z "$n_bad" -a $n_bad != 0 ]; then
-                       echo "Failures:$bad"
-                       echo "Failed $n_bad of $n_try tests"
-                       _global_log "Failures:$bad"
-                       _global_log "Failed $n_bad of $n_try tests"
-                       echo "Failures:$bad" >>$tmp.summary
-                       echo "Failed $n_bad of $n_try tests" >>$tmp.summary
+               if ((${#bad[*]} > 0)); then
+                       echo "Failures: ${bad[*]}"
+                       echo "Failed ${#bad[*]} of ${#try[*]} tests"
+                       _global_log "Failures: ${bad[*]}"
+                       _global_log "Failed ${#bad[*]} of ${#try[*]} tests"
+                       echo "Failures: ${bad[*]}" >>$tmp.summary
+                       echo "Failed ${#bad[*]} of ${#try[*]} tests" >>$tmp.summary
                else
-                       echo "Passed all $n_try tests"
-                       _global_log "Passed all $n_try tests"
-                       echo "Passed all $n_try tests" >>$tmp.summary
+                       echo "Passed all ${#try[*]} tests"
+                       _global_log "Passed all ${#try[*]} tests"
+                       echo "Passed all ${#try[*]} tests" >>$tmp.summary
                fi
                echo "" >>$tmp.summary
                if $do_report; then
-                       _make_section_report
+                       _make_section_report "${#try[*]}" "${#bad[*]}" "${#notrun[*]}"
                fi
                needwrap=false
        fi
 
-       sum_bad=`expr $sum_bad + $n_bad`
+       sum_bad=`expr $sum_bad + ${#bad[*]}`
        _wipe_counters
        rm -f /tmp/*.rawout /tmp/*.out /tmp/*.err /tmp/*.time
        if ! $OPTIONS_HAVE_SECTIONS; then
@@ -732,24 +725,17 @@ function run_section()
        seqres="$check"
        _check_test_fs
 
-       err=false
-       first_test=true
+       local tc_status="init"
        prev_seq=""
        for seq in $list ; do
                # Run report for previous test!
-               if $err ; then
-                       bad="$bad $seqnum"
-                       n_bad=`expr $n_bad + 1`
-                       tc_status="fail"
+               if [ "$tc_status" == "fail" ]; then
+                       bad+=("$seqnum")
                fi
-               if $do_report && ! $first_test ; then
-                       if [ $tc_status != "expunge" ] ; then
-                               _make_testcase_report "$prev_seq" "$tc_status"
-                       fi
+               if $do_report && [[ ! $tc_status =~ ^(init|expunge)$ ]]; then
+                       _make_testcase_report "$prev_seq" "$tc_status"
                fi
-               first_test=false
 
-               err=false
                prev_seq="$seq"
                if [ ! -f $seq ]; then
                        # Try to get full name in case the user supplied only
@@ -797,7 +783,7 @@ function run_section()
                        start=0
                        stop=0
                        tc_status="list"
-                       n_notrun=`expr $n_notrun + 1`
+                       notrun+=("$seqnum")
                        continue
                fi
 
@@ -818,16 +804,11 @@ function run_section()
                fi
 
                # record that we really tried to run this test.
-               try="$try $seqnum"
-               n_try=`expr $n_try + 1`
+               try+=("$seqnum")
 
-               # slashes now in names, sed barfs on them so use grep
-               lasttime=`grep -w ^$seqnum $check.time | awk '// {print $2}'`
-               if [ "X$lasttime" != X ]; then
-                       echo -n " ${lasttime}s ... "
-               else
-                       echo -n "       " # prettier output with timestamps.
-               fi
+               awk 'BEGIN {lasttime="       "} \
+                    $1 == "'$seqnum'" {lasttime=" " $2 "s ... "; exit} \
+                    END {printf "%s", lasttime}' "$check.time"
                rm -f core $seqres.notrun
 
                start=`_wallclock`
@@ -858,7 +839,7 @@ function run_section()
                if [ -f core ]; then
                        _dump_err_cont "[dumped core]"
                        mv core $RESULT_BASE/$seqnum.core
-                       err=true
+                       tc_status="fail"
                fi
 
                if [ -f $seqres.notrun ]; then
@@ -868,8 +849,7 @@ function run_section()
                        $timestamp && echo " [not run]" && \
                                      echo -n " $seqnum -- "
                        cat $seqres.notrun
-                       notrun="$notrun $seqnum"
-                       n_notrun=`expr $n_notrun + 1`
+                       notrun+=("$seqnum")
                        tc_status="notrun"
 
                        # Unmount the scratch fs so that we can wipe the scratch
@@ -884,15 +864,15 @@ function run_section()
                        _scratch_unmount 2> /dev/null
                        rm -f ${RESULT_DIR}/require_test*
                        rm -f ${RESULT_DIR}/require_scratch*
-                       err=true
+                       tc_status="fail"
                else
                        # The test apparently passed, so check for corruption
                        # and log messages that shouldn't be there.  Run the
                        # checking tools from a subshell with adjusted OOM
                        # score so that the OOM killer will target them instead
                        # of the check script itself.
-                       (_adjust_oom_score 250; _check_filesystems) || err=true
-                       _check_dmesg || err=true
+                       (_adjust_oom_score 250; _check_filesystems) || tc_status="fail"
+                       _check_dmesg || tc_status="fail"
                fi
 
                # Reload the module after each test to check for leaks or
@@ -906,7 +886,7 @@ function run_section()
 
                # Scan for memory leaks after every test so that associating
                # a leak to a particular test will be as accurate as possible.
-               _check_kmemleak || err=true
+               _check_kmemleak || tc_status="fail"
 
                # test ends after all checks are done.
                $timestamp && _timestamp
@@ -914,7 +894,7 @@ function run_section()
 
                if [ ! -f $seq.out ]; then
                        _dump_err "no qualified output"
-                       err=true
+                       tc_status="fail"
                        continue;
                fi
 
@@ -923,7 +903,7 @@ function run_section()
                # version.
                sed -i "s/\`/\'/g" $tmp.out
                if diff $seq.out $tmp.out >/dev/null 2>&1 ; then
-                       if ! $err ; then
+                       if [ "$tc_status" != "fail" ]; then
                                echo "$seqnum `expr $stop - $start`" >>$tmp.time
                                echo -n " `expr $stop - $start`s"
                        fi
@@ -940,10 +920,10 @@ function run_section()
                                echo "(Run '$diff $here/$seq.out $seqres.out.bad'" \
                                        " to see the entire diff)"
                        fi; } | sed -e 's/^\(.\)/    \1/'
-                       err=true
+                       tc_status="fail"
                fi
                if [ -f $seqres.hints ]; then
-                       if $err; then
+                       if [ "$tc_status" == "fail" ]; then
                                echo
                                cat $seqres.hints
                        else
@@ -953,15 +933,11 @@ function run_section()
        done
 
        # make sure we record the status of the last test we ran.
-       if $err ; then
-               bad="$bad $seqnum"
-               n_bad=`expr $n_bad + 1`
-               tc_status="fail"
+       if [ "$tc_status" == "fail" ]; then
+               bad+=("$seqnum")
        fi
-       if $do_report && ! $first_test ; then
-               if [ $tc_status != "expunge" ] ; then
-                       _make_testcase_report "$prev_seq" "$tc_status"
-               fi
+       if $do_report && [[ ! $tc_status =~ ^(init|expunge)$ ]]; then
+               _make_testcase_report "$prev_seq" "$tc_status"
        fi
 
        sect_stop=`_wallclock`
index ac597ca465a1c3d39240b7e330284c42b7471c47..c7058918cecd81845727eda0359d2cfd3f927545 100644 (file)
@@ -505,3 +505,78 @@ _btrfs_metadump()
        $BTRFS_IMAGE_PROG "$device" "$dumpfile"
        [ -n "$DUMP_COMPRESSOR" ] && $DUMP_COMPRESSOR -f "$dumpfile" &> /dev/null
 }
+
+# Return the btrfs logical address for the first block in a file
+_btrfs_get_first_logical()
+{
+       local file=$1
+       _require_command "$FILEFRAG_PROG" filefrag
+
+       ${FILEFRAG_PROG} -v $file >> $seqres.full
+       ${FILEFRAG_PROG} -v $file | _filter_filefrag | cut -d '#' -f 1
+}
+
+# Find the device path for a btrfs logical offset
+_btrfs_get_device_path()
+{
+       local logical=$1
+       local stripe=$2
+
+       _require_command "$BTRFS_MAP_LOGICAL_PROG" btrfs-map-logical
+
+       $BTRFS_MAP_LOGICAL_PROG -l $logical $SCRATCH_DEV | \
+               $AWK_PROG "(\$1 ~ /mirror/ && \$2 ~ /$stripe/) { print \$8 }"
+}
+
+
+# Find the device physical sector for a btrfs logical offset
+_btrfs_get_physical()
+{
+       local logical=$1
+       local stripe=$2
+
+       _require_command "$BTRFS_MAP_LOGICAL_PROG" btrfs-map-logical
+
+       $BTRFS_MAP_LOGICAL_PROG -b -l $logical $SCRATCH_DEV >> $seqres.full 2>&1
+       $BTRFS_MAP_LOGICAL_PROG -l $logical $SCRATCH_DEV | \
+               $AWK_PROG "(\$1 ~ /mirror/ && \$2 ~ /$stripe/) { print \$6 }"
+}
+
+# Read from a specific stripe to test read recovery that corrupted a specific
+# stripe.  Btrfs uses the PID to select the mirror, so keep reading until the
+# xfs_io process that performed the read was executed with a PID that ends up
+# on the intended mirror.
+_btrfs_direct_read_on_mirror()
+{
+       local mirror=$1
+       local nr_mirrors=$2
+       local file=$3
+       local offset=$4
+       local size=$5
+
+       while [[ -z $( (( BASHPID % nr_mirrors == mirror )) &&
+               exec $XFS_IO_PROG -d \
+                       -c "pread -b $size $offset $size" $file) ]]; do
+               :
+       done
+}
+
+# Read from a specific stripe to test read recovery that corrupted a specific
+# stripe.  Btrfs uses the PID to select the mirror, so keep reading until the
+# xfs_io process that performed the read was executed with a PID that ends up
+# on the intended mirror.
+_btrfs_buffered_read_on_mirror()
+{
+       local mirror=$1
+       local nr_mirrors=$2
+       local file=$3
+       local offset=$4
+       local size=$5
+
+       echo 3 > /proc/sys/vm/drop_caches
+       while [[ -z $( (( BASHPID % nr_mirrors == mirror )) &&
+               exec $XFS_IO_PROG \
+                       -c "pread -b $size $offset $size" $file) ]]; do
+               :
+       done
+}
index c6428f90c7c7253aa1a2046c2f458190b3bbdd0d..de3aba15b146ffa3ef34ec7ddb5f032f60f41870 100644 (file)
@@ -228,6 +228,7 @@ export E2IMAGE_PROG="$(type -P e2image)"
 export BLKZONE_PROG="$(type -P blkzone)"
 export GZIP_PROG="$(type -P gzip)"
 export BTRFS_IMAGE_PROG="$(type -P btrfs-image)"
+export BTRFS_MAP_LOGICAL_PROG=$(type -P btrfs-map-logical)
 
 # use 'udevadm settle' or 'udevsettle' to wait for lv to be settled.
 # newer systems have udevadm command but older systems like RHEL5 don't.
@@ -481,6 +482,65 @@ _fsck_opts()
        esac
 }
 
+# check necessary running dependences then source sepcific fs helpers
+_source_specific_fs()
+{
+       local fs=$1
+
+       if [ -z "$fs" ];then
+               fs=$FSTYP
+       fi
+
+       case "$fs" in
+       xfs)
+               [ "$XFS_LOGPRINT_PROG" = "" ] && _fatal "xfs_logprint not found"
+               [ "$XFS_REPAIR_PROG" = "" ] && _fatal "xfs_repair not found"
+               [ "$XFS_DB_PROG" = "" ] && _fatal "xfs_db not found"
+               [ "$MKFS_XFS_PROG" = "" ] && _fatal "mkfs_xfs not found"
+               [ "$XFS_INFO_PROG" = "" ] && _fatal "xfs_info not found"
+
+               . ./common/xfs
+               ;;
+       udf)
+               [ "$MKFS_UDF_PROG" = "" ] && _fatal "mkfs_udf/mkudffs not found"
+               ;;
+       btrfs)
+               [ "$MKFS_BTRFS_PROG" = "" ] && _fatal "mkfs.btrfs not found"
+
+               . ./common/btrfs
+               ;;
+       ext4)
+               [ "$MKFS_EXT4_PROG" = "" ] && _fatal "mkfs.ext4 not found"
+               ;;
+       f2fs)
+               [ "$MKFS_F2FS_PROG" = "" ] && _fatal "mkfs.f2fs not found"
+               ;;
+       nfs)
+               . ./common/nfs
+               ;;
+       cifs)
+               ;;
+       9p)
+               ;;
+       ceph)
+               . ./common/ceph
+               ;;
+       glusterfs)
+               ;;
+       overlay)
+               . ./common/overlay
+               ;;
+       reiser4)
+               [ "$MKFS_REISER4_PROG" = "" ] && _fatal "mkfs.reiser4 not found"
+               ;;
+       pvfs2)
+               ;;
+       ubifs)
+               [ "$UBIUPDATEVOL_PROG" = "" ] && _fatal "ubiupdatevol not found"
+               ;;
+       esac
+}
+
 known_hosts()
 {
        [ "$HOST_CONFIG_DIR" ] || HOST_CONFIG_DIR=`pwd`/configs
index a6a42b7a6ad25873fd374d59ea9ce1512ec9c6d3..14f6a02782326d831de610eaef5f59d376164a09 100644 (file)
@@ -380,6 +380,8 @@ _filter_ending_dot()
 # ancient:        mount: cannot remount block device <device> read-write, is write-protected
 # prior to v2.30:  mount: cannot remount <device> read-write, is write-protected
 # v2.30 and later: mount: <mountpoint>: cannot remount <device> read-write, is write-protected.
+# v2.38 and later:
+# dmesg(1) may have more information after failed mount mount system call
 #
 # Now use _filter_ro_mount to unify all these differences across old & new
 # util-linux versions. So the filtered format would be:
@@ -412,7 +414,8 @@ _filter_ro_mount() {
                print "mount: cannot remount device read-write, is write-protected\n";
        } else {
                print "$_";
-       }' | _filter_ending_dot
+       }' | grep -v "dmesg(1) may have more information after failed mount" | \
+       _filter_ending_dot
 }
 
 # Filter a failed mount output due to EUCLEAN and USTALE, util-linux changed
@@ -424,6 +427,8 @@ _filter_ro_mount() {
 # mount: mount <device> on <mountpoint> failed: Structure needs cleaning
 # v2.30 and later:
 # mount: <mountpoint>: mount(2) system call failed: Structure needs cleaning.
+# v2.38 and later:
+# dmesg(1) may have more information after failed mount mount system call
 #
 # This is also true for ESTALE error. So let's remove all the changing parts
 # and keep the 'prior to v2.21' format:
@@ -431,7 +436,8 @@ _filter_ro_mount() {
 # mount: Stale file handle
 _filter_error_mount()
 {
-       sed -e "s/mount:\(.*failed:\)/mount:/" | _filter_ending_dot
+       grep -v "dmesg(1) may have more information after failed mount" | \
+               sed -e "s/mount:\(.*failed:\)/mount:/" | _filter_ending_dot
 }
 
 # Similar to _filter_error_mount, filter a busy mount output.
@@ -440,8 +446,11 @@ _filter_error_mount()
 # old: mount: <device> is already mounted or <mountpoint> busy
 # new: mount: <mountpoint>: <device> already mounted or mount point busy.
 # filtered: mount: device already mounted or mount point busy
+# v2.38 and later, filter out:
+# dmesg(1) may have more information after failed mount mount system call
 _filter_busy_mount()
 {
+       grep -v "dmesg(1) may have more information after failed mount" | \
        sed -e "s/.*: .* already mounted or .* busy/mount: device already mounted or mount point busy/" | \
                _filter_ending_dot
 }
index c4e7ee5896b569e7f46ae197b39c4e88ee0141e1..e35419d0e0452a18e93a88dc5b255345a687e4ea 100644 (file)
@@ -12,6 +12,10 @@ export OVL_XATTR_NLINK="trusted.overlay.nlink"
 export OVL_XATTR_UPPER="trusted.overlay.upper"
 export OVL_XATTR_METACOPY="trusted.overlay.metacopy"
 
+if [ -n "$OVL_BASE_FSTYP" ];then
+       _source_specific_fs $OVL_BASE_FSTYP
+fi
+
 # helper function to do the actual overlayfs mount operation
 _overlay_mount_dirs()
 {
index 70a15f9ca156706a01de25a6aea2fddf9d1cd209..3c072c16f0cabd285622436f1e21d86b0a47f4a2 100644 (file)
--- a/common/rc
+++ b/common/rc
@@ -96,54 +96,7 @@ _log_err()
 umask 022
 
 # check for correct setup and source the $FSTYP specific functions now
-case "$FSTYP" in
-    xfs)
-        [ "$XFS_LOGPRINT_PROG" = "" ] && _fatal "xfs_logprint not found"
-        [ "$XFS_REPAIR_PROG" = "" ] && _fatal "xfs_repair not found"
-        [ "$XFS_DB_PROG" = "" ] && _fatal "xfs_db not found"
-        [ "$MKFS_XFS_PROG" = "" ] && _fatal "mkfs_xfs not found"
-        [ "$XFS_INFO_PROG" = "" ] && _fatal "xfs_info not found"
-
-        . ./common/xfs
-        ;;
-    udf)
-        [ "$MKFS_UDF_PROG" = "" ] && _fatal "mkfs_udf/mkudffs not found"
-        ;;
-    btrfs)
-        [ "$MKFS_BTRFS_PROG" = "" ] && _fatal "mkfs.btrfs not found"
-
-        . ./common/btrfs
-        ;;
-    ext4)
-        [ "$MKFS_EXT4_PROG" = "" ] && _fatal "mkfs.ext4 not found"
-        ;;
-    f2fs)
-        [ "$MKFS_F2FS_PROG" = "" ] && _fatal "mkfs.f2fs not found"
-        ;;
-    nfs)
-        . ./common/nfs
-        ;;
-    cifs)
-        ;;
-    9p)
-        ;;
-    ceph)
-        . ./common/ceph
-        ;;
-    glusterfs)
-        ;;
-    overlay)
-        . ./common/overlay
-        ;;
-    reiser4)
-        [ "$MKFS_REISER4_PROG" = "" ] && _fatal "mkfs.reiser4 not found"
-        ;;
-    pvfs2)
-       ;;
-    ubifs)
-       [ "$UBIUPDATEVOL_PROG" = "" ] && _fatal "ubiupdatevol not found"
-       ;;
-esac
+_source_specific_fs $FSTYP
 
 if [ ! -z "$REPORT_LIST" ]; then
        . ./common/report
@@ -2163,21 +2116,33 @@ _require_sane_bdev_flush()
 # Decide if the scratch filesystem is likely to be mounted in fsdax mode.
 # It goes 3 ways based on mount options::
 #      1. "dax" or "dax=always" means always test using DAX
-#      2. "dax=never" means we'll never use DAX
+#      2. "dax=never" means we'll never use DAX.
 #      3. "dax=inode" or nothing means "use scratch dev capability" to
 #          determine whether DAX is going to be used.
 #
-# Returns 0 if DAX will be used, 1 if DAX is not going to be used.
+# Case 2 and 3 basically mean the same thing for the purpose of
+# _require_dm_target(). If the fs is not forcing the use of DAX, then DAX
+# can only be enabled if the underlying block device supports it.
+#
+# Returns 0 if the filesytem will use DAX, 1 if it won't.
 __scratch_uses_fsdax()
 {
        local ops=$(_normalize_mount_options "$MOUNT_OPTIONS")
 
        echo $ops | egrep -qw "dax(=always| |$)" && return 0
-       echo $ops | grep -qw "dax=never" && return 1
+       return 1
+}
 
+# Determine if the scratch device is DAX capable. Even if the fs is not
+# using DAX, we still can't use certain device mapper targets if the block
+# device is DAX capable. Hence the check needs to be separat from the FS
+# capability.
+__scratch_dev_has_dax()
+{
        local sysfs="/sys/block/$(_short_dev $SCRATCH_DEV)"
        test -e "${sysfs}/dax" && return 0
        test "$(cat "${sysfs}/queue/dax" 2>/dev/null)" = "1" && return 0
+
        return 1
 }
 
@@ -2194,15 +2159,18 @@ _require_dm_target()
        _require_sane_bdev_flush $SCRATCH_DEV
        _require_command "$DMSETUP_PROG" dmsetup
 
-       if __scratch_uses_fsdax; then
-               case $target in
-               stripe|linear|log-writes)
-                       ;;
-               *)
-                       _notrun "Cannot run tests with DAX on $target devices."
-                       ;;
-               esac
-       fi
+       case $target in
+       stripe|linear|log-writes)
+               ;;
+       *)
+               if __scratch_uses_fsdax; then
+                       _notrun "Cannot run tests with fsdax on $target devices."
+               fi
+               if __scratch_dev_has_dax; then
+                       _notrun "Cannot use $target devices on DAX capable block devices."
+               fi
+               ;;
+       esac
 
        modprobe dm-$target >/dev/null 2>&1
 
@@ -2768,9 +2736,13 @@ _require_xfs_io_command()
        fi
 }
 
-# check that kernel and filesystem support direct I/O
+# check that kernel and filesystem support direct I/O, and check if "$1" size
+# aligned (optional) is supported
 _require_odirect()
 {
+       local blocksize=$1
+       local align_args=${1:+"-b $1"}
+
        if [ $FSTYP = "ext4" ] || [ $FSTYP = "f2fs" ] ; then
                if echo "$MOUNT_OPTIONS" | grep -q "test_dummy_encryption"; then
                        _notrun "$FSTYP encryption doesn't support O_DIRECT"
@@ -2782,9 +2754,13 @@ _require_odirect()
                fi
        fi
        local testfile=$TEST_DIR/$$.direct
-       $XFS_IO_PROG -F -f -d -c "pwrite 0 20k" $testfile > /dev/null 2>&1
+       $XFS_IO_PROG -F -f -d -c "pwrite ${align_args} 0 20k" $testfile > /dev/null 2>&1
        if [ $? -ne 0 ]; then
-               _notrun "O_DIRECT is not supported"
+               if [ -n "$blocksize" ]; then
+                       _notrun "O_DIRECT aligned to $blocksize bytes is not supported"
+               else
+                       _notrun "O_DIRECT is not supported"
+               fi
        fi
        rm -f $testfile 2>&1 > /dev/null
 }
@@ -4008,7 +3984,7 @@ _require_batched_discard()
        fi
        _require_fstrim
 
-       grep -q "not supported" <($FSTRIM_PROG $1 2>&1)
+       grep -q -E "not supported|not implemented" <($FSTRIM_PROG $1 2>&1)
        if [ "$?" = "0" ]
        then
                _notrun "FITRIM not supported on $1"
index 5a957f4ec81c51e0e62bf9c23c2922769731ad0e..463ef9db6e5bdf627c0f608cbdc3235329ec7f35 100644 (file)
@@ -90,6 +90,7 @@ s/(superblock) (\d+)/\1 AGNO/;
 s/(AG \#)(\d+)/\1AGNO/;
 s/(reset bad sb for ag) (\d+)/\1 AGNO/;
 s/(unknown block state, ag )(\d+)(, blocks? )(\d+)/\1AGNO\3AGBNO/;
+s/^Superblock has (bad magic number) 0x.*/\1/;
 /^Note - quota info will be regenerated on next quota mount.$/ && next;
        print;'
 }
index 6cac71fc865b7e48bf125e741d21dbeea656bd21..84d9e0a7386976657d0b277522442256583cbbcb 100644 (file)
@@ -49,9 +49,11 @@ _xunit_add_property()
 _xunit_make_section_report()
 {
        # xfstest:section ==> xunit:testsuite
+       local tests_count="$1"
+       local bad_count="$2"
+       local notrun_count="$3"
        local sect_name=$section
        local sect_time=`expr $sect_stop - $sect_start`
-       local n_total=`expr $n_try + $n_notrun`
 
        if [ $sect_name == '-no-sections-' ]; then
                sect_name='global'
@@ -62,9 +64,8 @@ _xunit_make_section_report()
        if [ -z "$date_time" ]; then
                date_time=$(date +"%F %T")
        fi
-       local dtime=`echo $date_time| tr  " " 'T'`
-       local stats="failures=\"$n_bad\" skipped=\"$n_notrun\" tests=\"$n_total\" time=\"$sect_time\""
-       local hw_info="hostname=\"$HOST\" timestamp=\"$dtime\" "
+       local stats="failures=\"$bad_count\" skipped=\"$notrun_count\" tests=\"$tests_count\" time=\"$sect_time\""
+       local hw_info="hostname=\"$HOST\" timestamp=\"${date_time/ /T}\" "
        echo "<testsuite name=\"xfstests\" $stats  $hw_info >" >> $REPORT_DIR/result.xml
 
        # Properties
@@ -149,10 +150,13 @@ _xunit_make_testcase_report()
 #  Common report generator entry points
 _make_section_report()
 {
+       local tests_count="$1"
+       local bad_count="$2"
+       local notrun_count="$3"
        for report in $REPORT_LIST; do
                case "$report" in
                "xunit")
-                       _xunit_make_section_report "$test_status"
+                       _xunit_make_section_report "$tests_count" "$bad_count" "$notrun_count"
                        ;;
                *)
                        _dump_err "format '$report' is not supported"
index 2123a4ab428195a34caba1a2d45574b5c5276bf0..9f84dffb8d2acf188ee05f68fdcce3741be6b889 100644 (file)
@@ -444,6 +444,18 @@ _require_xfs_sparse_inodes()
        _scratch_unmount
 }
 
+# this test requires the xfs large extent counter feature
+#
+_require_xfs_nrext64()
+{
+       _scratch_mkfs_xfs_supported -m crc=1 -i nrext64 > /dev/null 2>&1 \
+               || _notrun "mkfs.xfs does not support nrext64"
+       _scratch_mkfs_xfs -m crc=1 -i nrext64 > /dev/null 2>&1
+       _try_scratch_mount >/dev/null 2>&1 \
+               || _notrun "kernel does not support nrext64"
+       _scratch_unmount
+}
+
 # check that xfs_db supports a specific command
 _require_xfs_db_command()
 {
index cca8dcf8ff6014fd2c2fc300d7496807117f2fdd..1218e7264c8f91132364d21762867a19abc2089b 100644 (file)
@@ -20,19 +20,41 @@ exit(1); } while (0)
 fprintf(stderr, __VA_ARGS__); exit (1); \
 } while (0)
 
+void usage(char *progname)
+{
+       fail("usage: %s [-m max_attr_size] <file>\n", progname);
+}
+
 int main(int argc, char *argv[])
 {
        int ret;
        int fd;
+       int c;
        char *path;
        char *name = "user.world";
        char *value;
        struct stat sbuf;
        size_t size = sizeof(value);
+       size_t maxsize = XATTR_SIZE_MAX;
+
+       while ((c = getopt(argc, argv, "m:")) != -1) {
+               char *endp;
+
+               switch (c) {
+               case 'm':
+                       maxsize = strtoul(optarg, &endp, 0);
+                       if (*endp || (maxsize > XATTR_SIZE_MAX))
+                               fail("Invalid 'max_attr_size' value\n");
+                       break;
+               default:
+                       usage(argv[0]);
+               }
+       }
 
-       if (argc != 2)
-               fail("Usage: %s <file>\n", argv[0]);
-       path = argv[1];
+       if (optind == argc - 1)
+               path = argv[optind];
+       else
+               usage(argv[0]);
 
        fd = open(path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
        if (fd < 0) die();
@@ -46,7 +68,7 @@ int main(int argc, char *argv[])
        size = sbuf.st_blksize * 3 / 4;
        if (!size)
                fail("Invalid st_blksize(%ld)\n", sbuf.st_blksize);
-       size = MIN(size, XATTR_SIZE_MAX);
+       size = MIN(size, maxsize);
        value = malloc(size);
        if (!value)
                fail("Failed to allocate memory\n");
index 2f1ba2baaff0713cca65537b6278110612c0ca4a..eb86367380643b118a5d2ab253bba0cc8ca38c16 100644 (file)
 #include <errno.h>
 #include <malloc.h>
 
-#define SECTOR_SIZE 512
-#define BUFFER_SIZE (150 * SECTOR_SIZE)
+unsigned int sector_size;
+unsigned int buffer_size;
 
 void read_from_pipe(int fd, const char *filename, size_t size)
 {
-       char buffer[SECTOR_SIZE];
+       char *buffer;
        size_t sz;
        ssize_t ret;
+       buffer = malloc(buffer_size);
 
        while (size) {
                sz = size;
-               if (sz > sizeof buffer)
-                       sz = sizeof buffer;
+               if (sz > buffer_size)
+                       sz = buffer_size;
                ret = read(fd, buffer, sz);
                if (ret < 0)
                        err(1, "read: %s", filename);
@@ -41,6 +42,7 @@ void read_from_pipe(int fd, const char *filename, size_t size)
                }
                size -= sz;
        }
+       free(buffer);
 }
 
 void do_splice1(int fd, const char *filename, size_t size)
@@ -108,7 +110,7 @@ void do_splice2(int fd, const char *filename, size_t size)
 
 void usage(const char *argv0)
 {
-       fprintf(stderr, "USAGE: %s [-rd] {filename}\n", basename(argv0));
+       fprintf(stderr, "USAGE: %s [-rd] [-s sectorsize] {filename}\n", basename(argv0));
        exit(2);
 }
 
@@ -120,11 +122,22 @@ int main(int argc, char *argv[])
        int opt, open_flags, fd;
        ssize_t ret;
 
+       /*
+        * init default sector_size and buffer_size, might be changed if the -s
+        * option is specified
+        */
+       sector_size = 512;
+       buffer_size = 150 * sector_size;
+
        do_splice = do_splice1;
        open_flags = O_CREAT | O_TRUNC | O_RDWR | O_DIRECT;
 
-       while ((opt = getopt(argc, argv, "rd")) != -1) {
+       while ((opt = getopt(argc, argv, "rds:")) != -1) {
                switch(opt) {
+               case 's':
+                       sector_size = strtol(optarg, NULL, 0);
+                       buffer_size = 150 * sector_size;
+                       break;
                case 'r':
                        do_splice = do_splice2;
                        break;
@@ -140,11 +153,13 @@ int main(int argc, char *argv[])
                usage(argv[0]);
        filename = argv[optind];
 
+       /* force below printf line buffered */
+       setlinebuf(stdout);
        printf("%s reader %s O_DIRECT\n",
                   do_splice == do_splice1 ? "sequential" : "concurrent",
                   (open_flags & O_DIRECT) ? "with" : "without");
 
-       buffer = memalign(SECTOR_SIZE, BUFFER_SIZE);
+       buffer = memalign(sector_size, buffer_size);
        if (buffer == NULL)
                err(1, "memalign");
 
@@ -152,11 +167,11 @@ int main(int argc, char *argv[])
        if (fd == -1)
                err(1, "open: %s", filename);
 
-       memset(buffer, 'x', BUFFER_SIZE);
-       ret = write(fd, buffer, BUFFER_SIZE);
+       memset(buffer, 'x', buffer_size);
+       ret = write(fd, buffer, buffer_size);
        if (ret < 0)
                err(1, "write: %s", filename);
-       if (ret != BUFFER_SIZE) {
+       if (ret != buffer_size) {
                fprintf(stderr, "%s: short write\n", filename);
                exit(1);
        }
@@ -165,7 +180,7 @@ int main(int argc, char *argv[])
        if (ret != 0)
                err(1, "lseek: %s", filename);
 
-       do_splice(fd, filename, BUFFER_SIZE);
+       do_splice(fd, filename, buffer_size);
 
        if (unlink(filename) == -1)
                err(1, "unlink: %s", filename);
index c680fe0aef4153323eec36c7389d3603b4e4f537..fdff6eb2cfd93d5f34a383a849552a8fb52c681e 100755 (executable)
@@ -24,7 +24,6 @@ _supported_fs btrfs
 _require_scratch_dev_pool 2
 
 _require_btrfs_command inspect-internal dump-tree
-_require_command "$FILEFRAG_PROG" filefrag
 _require_odirect
 # Overwriting data is forbidden on a zoned block device
 _require_non_zoned_device "${SCRATCH_DEV}"
@@ -71,7 +70,7 @@ $XFS_IO_PROG -f -d -c "pwrite -S 0xaa -b 128K 0 128K" "$SCRATCH_MNT/foobar" |\
 echo "step 2......corrupt file extent" >>$seqres.full
 
 ${FILEFRAG_PROG} -v $SCRATCH_MNT/foobar >> $seqres.full
-logical_in_btrfs=`${FILEFRAG_PROG} -v $SCRATCH_MNT/foobar | _filter_filefrag | cut -d '#' -f 1`
+logical_in_btrfs=$(_btrfs_get_first_logical $SCRATCH_MNT/foobar)
 physical=$(get_physical ${logical_in_btrfs} 1)
 devid=$(get_devid ${logical_in_btrfs} 1)
 devpath=$(get_device_path ${devid})
@@ -87,15 +86,7 @@ _scratch_mount
 # step 3, 128k dio read (this read can repair bad copy)
 echo "step 3......repair the bad copy" >>$seqres.full
 
-# since raid1 consists of two copies, and the bad copy was put on stripe #1
-# while the good copy lies on stripe #0, the bad copy only gets access when the
-# reader's pid % 2 == 1 is true
-while true; do
-       $XFS_IO_PROG -d -c "pread -b 128K 0 128K" "$SCRATCH_MNT/foobar" > /dev/null &
-       pid=$!
-       wait
-       [ $((pid % 2)) == 1 ] && break
-done
+_btrfs_direct_read_on_mirror 1 2 "$SCRATCH_MNT/foobar" 0 128K
 
 _scratch_unmount
 
index 9fdcb2aba6837f79858319bd942f8c9cc30ae43a..90a90d00d7bf14d503bacf11f05ad350a6ef180c 100755 (executable)
@@ -25,7 +25,6 @@ _supported_fs btrfs
 _require_scratch_dev_pool 2
 
 _require_btrfs_command inspect-internal dump-tree
-_require_command "$FILEFRAG_PROG" filefrag
 
 get_physical()
 {
@@ -69,8 +68,7 @@ $XFS_IO_PROG -f -d -c "pwrite -S 0xaa -b 128K 0 128K" "$SCRATCH_MNT/foobar" |\
 # one in $SCRATCH_DEV_POOL
 echo "step 2......corrupt file extent" >>$seqres.full
 
-${FILEFRAG_PROG} -v $SCRATCH_MNT/foobar >> $seqres.full
-logical_in_btrfs=`${FILEFRAG_PROG} -v $SCRATCH_MNT/foobar | _filter_filefrag | cut -d '#' -f 1`
+logical_in_btrfs=$(_btrfs_get_first_logical $SCRATCH_MNT/foobar)
 physical=$(get_physical ${logical_in_btrfs} 1)
 devid=$(get_devid ${logical_in_btrfs} 1)
 devpath=$(get_device_path ${devid})
@@ -85,16 +83,7 @@ _scratch_mount
 # step 3, 128k buffered read (this read can repair bad copy)
 echo "step 3......repair the bad copy" >>$seqres.full
 
-# since raid1 consists of two copies, and the bad copy was put on stripe #1
-# while the good copy lies on stripe #0, the bad copy only gets access when the
-# reader's pid % 2 == 1 is true
-while true; do
-       echo 3 > /proc/sys/vm/drop_caches
-       $XFS_IO_PROG -c "pread -b 128K 0 128K" "$SCRATCH_MNT/foobar" > /dev/null &
-       pid=$!
-       wait
-       [ $((pid % 2)) == 1 ] && break
-done
+_btrfs_buffered_read_on_mirror 1 2 "$SCRATCH_MNT/foobar" 0 128K
 
 _scratch_unmount
 
index 58d01addc4410b22a9accbc5a724664be7f15a44..7a63fb83fb10a2fd1112e066ee795f0597c6c349 100755 (executable)
@@ -27,7 +27,6 @@ _require_scratch_dev_pool 2
 _require_dm_target dust
 
 _require_btrfs_command inspect-internal dump-tree
-_require_command "$FILEFRAG_PROG" filefrag
 
 _scratch_dev_pool_get 2
 # step 1, create a raid1 btrfs which contains one 128k file.
@@ -46,8 +45,7 @@ $XFS_IO_PROG -f -d -c "pwrite -S 0xaa -b 128K 0 128K" "$SCRATCH_MNT/foobar" |\
 # step 2, corrupt the first 64k of stripe #1
 echo "step 2......corrupt file extent" >>$seqres.full
 
-${FILEFRAG_PROG} -v $SCRATCH_MNT/foobar >> $seqres.full
-logical_in_btrfs=`${FILEFRAG_PROG} -v $SCRATCH_MNT/foobar | _filter_filefrag | cut -d '#' -f 1`
+logical_in_btrfs=$(_btrfs_get_first_logical $SCRATCH_MNT/foobar)
 echo "Logical offset is $logical_in_btrfs" >>$seqres.full
 _scratch_unmount
 
@@ -67,10 +65,8 @@ echo "step 3......repair the bad copy" >>$seqres.full
 
 $DMSETUP_PROG message dust-test 0 addbadblock $((physical / 512))
 $DMSETUP_PROG message dust-test 0 enable
-while [[ -z $( (( BASHPID % 2 == stripe )) &&
-              exec $XFS_IO_PROG -d -c "pread -b 128K 0 128K" "$SCRATCH_MNT/foobar") ]]; do
-       :
-done
+
+_btrfs_direct_read_on_mirror $stripe 2 "$SCRATCH_MNT/foobar" 0 128K
 
 _cleanup_dust
 
index 71db861d05718320a0d41a1a6ebcbf5e8204a077..b6ff2a424af6266c883f0aa5e9d33e119f0243b7 100755 (executable)
@@ -34,7 +34,6 @@ _require_scratch_dev_pool 2
 _require_dm_target dust
 
 _require_btrfs_command inspect-internal dump-tree
-_require_command "$FILEFRAG_PROG" filefrag
 
 _scratch_dev_pool_get 2
 # step 1, create a raid1 btrfs which contains one 128k file.
@@ -53,8 +52,7 @@ $XFS_IO_PROG -f -d -c "pwrite -S 0xaa -b 128K 0 128K" "$SCRATCH_MNT/foobar" |\
 # step 2, corrupt the first 64k of stripe #1
 echo "step 2......corrupt file extent" >>$seqres.full
 
-${FILEFRAG_PROG} -v $SCRATCH_MNT/foobar >> $seqres.full
-logical_in_btrfs=`${FILEFRAG_PROG} -v $SCRATCH_MNT/foobar | _filter_filefrag | cut -d '#' -f 1`
+logical_in_btrfs=$(_btrfs_get_first_logical $SCRATCH_MNT/foobar)
 echo "Logical offset is $logical_in_btrfs" >>$seqres.full
 _scratch_unmount
 
@@ -74,10 +72,8 @@ echo "step 3......repair the bad copy" >>$seqres.full
 
 $DMSETUP_PROG message dust-test 0 addbadblock $((physical / 512))
 $DMSETUP_PROG message dust-test 0 enable
-while [[ -z $( (( BASHPID % 2 == stripe )) &&
-              exec $XFS_IO_PROG -c "pread -b 128K 0 128K" "$SCRATCH_MNT/foobar") ]]; do
-       :
-done
+
+_btrfs_buffered_read_on_mirror $stripe 2 "$SCRATCH_MNT/foobar" 0 128K
 
 _cleanup_dust
 
index 343178b7c06b1b1a49afbbf2514914b154c174fc..022db51166dbc7d1619592a94ab2dabf5a557844 100755 (executable)
@@ -71,7 +71,7 @@ _scratch_mount $(_btrfs_no_v1_cache_opt)
 $XFS_IO_PROG -f -d -c "pwrite -S 0xaa 0 128K" -c "fsync" \
        "$SCRATCH_MNT/foobar" | _filter_xfs_io
 
-logical=`${FILEFRAG_PROG} -v $SCRATCH_MNT/foobar | _filter_filefrag | cut -d '#' -f 1`
+logical=$(_btrfs_get_first_logical $SCRATCH_MNT/foobar)
 _scratch_unmount
 
 phy0=$(get_physical 0)
index 2fd11e89ca350364287d7ce6a7d7352e5e410d10..7b004b83c15fd9dee9e3c2c3565b1bdd813b86c2 100755 (executable)
@@ -10,7 +10,6 @@
 _begin_fstest auto quick swap balance
 
 . ./common/filter
-. ./common/btrfs
 
 # Modify as appropriate.
 _supported_fs btrfs
index 0dcbce2a888ecdb8792f4dee288dd4cfb429ee15..928f365c35c035d3ff7df0e73b79bd501f63e698 100755 (executable)
@@ -56,7 +56,7 @@ fi
 #create an 8 block file
 $XFS_IO_PROG -d -f -c "pwrite -S 0xbb -b $filesize 0 $filesize" "$SCRATCH_MNT/foobar" > /dev/null
 
-logical_extent=$($FILEFRAG_PROG -v "$SCRATCH_MNT/foobar" | _filter_filefrag | cut -d '#' -f 1)
+logical_extent=$(_btrfs_get_first_logical $SCRATCH_MNT/foobar)
 physical_extent=$(get_physical $logical_extent)
 
 echo "logical = $logical_extent physical=$physical_extent" >> $seqres.full
index fa91a38493af7c50a6397de57b06c6eff9b64368..4d94ccd6eee2a554037d151961297cf5cbce220c 100755 (executable)
@@ -265,14 +265,16 @@ test_revertible_options()
        test_roundtrip_mount "compress=zlib:20" "compress=zlib:9" "compress=zstd:16" "compress=zstd:15"
        test_roundtrip_mount "compress-force=lzo" "compress-force=lzo" "compress-force=zlib:4" "compress-force=zlib:4"
 
-       # on remount, if we only pass datacow after nodatacow was used it will remain with nodatasum
-       test_roundtrip_mount "nodatacow" "nodatasum,nodatacow" "datacow,datasum" "$DEFAULT_OPTS"
-       # nodatacow disabled compression
-       test_roundtrip_mount "compress-force" "compress-force=zlib:3" "nodatacow" "nodatasum,nodatacow"
-
-       # nodatacow disabled both datacow and datasum, and datasum enabled datacow and datasum
-       test_roundtrip_mount "nodatacow" "nodatasum,nodatacow" "datasum" "$DEFAULT_OPTS"
-       test_roundtrip_mount "nodatasum" "nodatasum" "datasum" "$DEFAULT_OPTS"
+       if ! _scratch_btrfs_is_zoned; then
+               # on remount, if we only pass datacow after nodatacow was used it will remain with nodatasum
+               test_roundtrip_mount "nodatacow" "nodatasum,nodatacow" "datacow,datasum" "$DEFAULT_OPTS"
+               # nodatacow disabled compression
+               test_roundtrip_mount "compress-force" "compress-force=zlib:3" "nodatacow" "nodatasum,nodatacow"
+
+               # nodatacow disabled both datacow and datasum, and datasum enabled datacow and datasum
+               test_roundtrip_mount "nodatacow" "nodatasum,nodatacow" "datasum" "$DEFAULT_OPTS"
+               test_roundtrip_mount "nodatasum" "nodatasum" "datasum" "$DEFAULT_OPTS"
+       fi
 
        test_should_fail "discard=invalid"
        if [ "$enable_discard_sync" = true ]; then
index 158eaf79a92c87752fd60c32ddadbb4573e32649..da073333f50cd3a25908adbdf6385c6309bfd7a0 100755 (executable)
@@ -10,7 +10,6 @@
 . ./common/preamble
 _begin_fstest auto defrag quick
 
-. ./common/btrfs
 . ./common/filter
 
 # real QA test starts here
index e7bd8ddd7f8b52aabb001e7af61b9a6da4cee00c..92d0b9a65039a08fd86d14f01be677da77c7bc77 100755 (executable)
@@ -12,7 +12,6 @@ _begin_fstest auto quick defrag
 
 # Import common functions.
 . ./common/filter
-. ./common/btrfs
 
 # real QA test starts here
 
diff --git a/tests/btrfs/265 b/tests/btrfs/265
new file mode 100755 (executable)
index 0000000..b75d9c8
--- /dev/null
@@ -0,0 +1,85 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2017 Liu Bo.  All Rights Reserved.
+# Copyright (c) 2022 Christoph Hellwig.
+#
+# FS QA Test 265
+#
+# Test that btrfs raid repair on a raid1c3 profile can repair corruption on two
+# mirrors for the same logical offset.
+#
+. ./common/preamble
+_begin_fstest auto quick read_repair
+
+# Import common functions.
+. ./common/filter
+
+# real QA test starts here
+
+_supported_fs btrfs
+_require_scratch_dev_pool 3
+
+_require_odirect
+# Overwriting data is forbidden on a zoned block device
+_require_non_zoned_device "${SCRATCH_DEV}"
+
+_scratch_dev_pool_get 3
+# step 1, create a raid1 btrfs which contains one 128k file.
+echo "step 1......mkfs.btrfs"
+
+mkfs_opts="-d raid1c3 -b 1G"
+_scratch_pool_mkfs $mkfs_opts >>$seqres.full 2>&1
+
+_scratch_mount
+
+$XFS_IO_PROG -f -d -c "pwrite -S 0xaa -b 128K 0 128K" \
+       "$SCRATCH_MNT/foobar" | \
+       _filter_xfs_io_offset
+
+# step 2, corrupt the first 64k of one copy (on SCRATCH_DEV which is the first
+# one in $SCRATCH_DEV_POOL
+echo "step 2......corrupt file extent"
+
+# ensure btrfs-map-logical sees the tree updates
+sync
+
+logical=$(_btrfs_get_first_logical $SCRATCH_MNT/foobar)
+
+physical1=$(_btrfs_get_physical ${logical} 1)
+devpath1=$(_btrfs_get_device_path ${logical} 1)
+
+physical2=$(_btrfs_get_physical ${logical} 2)
+devpath2=$(_btrfs_get_device_path ${logical} 2)
+
+_scratch_unmount
+
+echo " corrupt stripe #1, devpath $devpath1 physical $physical1" \
+       >> $seqres.full
+$XFS_IO_PROG -d -c "pwrite -S 0xbf -b 64K $physical1 64K" $devpath1 \
+       > /dev/null
+
+echo " corrupt stripe #2, devpath $devpath2 physical $physical2" \
+       >> $seqres.full
+$XFS_IO_PROG -d -c "pwrite -S 0xbf -b 64K $physical2 64K" $devpath2 \
+       > /dev/null
+
+_scratch_mount
+
+# step 3, 128k dio read (this read can repair bad copy)
+echo "step 3......repair the bad copy"
+
+_btrfs_direct_read_on_mirror 0 3 "$SCRATCH_MNT/foobar" 0 128K
+_btrfs_direct_read_on_mirror 1 3 "$SCRATCH_MNT/foobar" 0 128K
+
+_scratch_unmount
+
+echo "step 4......check if the repair worked"
+$XFS_IO_PROG -d -c "pread -v -b 512 $physical1 512" $devpath1 |\
+       _filter_xfs_io_offset
+$XFS_IO_PROG -d -c "pread -v -b 512 $physical2 512" $devpath2 |\
+       _filter_xfs_io_offset
+
+_scratch_dev_pool_put
+# success, all done
+status=0
+exit
diff --git a/tests/btrfs/265.out b/tests/btrfs/265.out
new file mode 100644 (file)
index 0000000..c62c7a3
--- /dev/null
@@ -0,0 +1,75 @@
+QA output created by 265
+step 1......mkfs.btrfs
+wrote 131072/131072 bytes
+XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+step 2......corrupt file extent
+step 3......repair the bad copy
+step 4......check if the repair worked
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+read 512/512 bytes
+XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+read 512/512 bytes
+XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
diff --git a/tests/btrfs/266 b/tests/btrfs/266
new file mode 100755 (executable)
index 0000000..42aff7c
--- /dev/null
@@ -0,0 +1,93 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2017 Liu Bo.  All Rights Reserved.
+# Copyright (c) 2022 Christoph Hellwig.
+#
+# FS QA Test 266
+#
+# Test that btrfs raid repair on a raid1c3 profile can repair interleaving
+# errors on all mirrors.
+#
+
+. ./common/preamble
+_begin_fstest auto quick read_repair
+
+# Import common functions.
+. ./common/filter
+
+# real QA test starts here
+
+_supported_fs btrfs
+_require_scratch_dev_pool 3
+
+_require_odirect
+# Overwriting data is forbidden on a zoned block device
+_require_non_zoned_device "${SCRATCH_DEV}"
+
+_scratch_dev_pool_get 3
+# step 1, create a raid1 btrfs which contains one 128k file.
+echo "step 1......mkfs.btrfs"
+
+mkfs_opts="-d raid1c3 -b 1G"
+_scratch_pool_mkfs $mkfs_opts >>$seqres.full 2>&1
+
+_scratch_mount
+
+$XFS_IO_PROG -f -d -c "pwrite -S 0xaa -b 256K 0 256K" \
+       "$SCRATCH_MNT/foobar" | \
+       _filter_xfs_io_offset
+
+# step 2, corrupt 64k in each copy
+echo "step 2......corrupt file extent"
+
+# ensure btrfs-map-logical sees the tree updates
+sync
+
+logical=$(_btrfs_get_first_logical $SCRATCH_MNT/foobar)
+
+physical1=$(_btrfs_get_physical ${logical} 1)
+devpath1=$(_btrfs_get_device_path ${logical} 1)
+
+physical2=$(_btrfs_get_physical ${logical} 2)
+devpath2=$(_btrfs_get_device_path ${logical} 2)
+
+physical3=$(_btrfs_get_physical ${logical} 3)
+devpath3=$(_btrfs_get_device_path ${logical} 3)
+
+_scratch_unmount
+
+$XFS_IO_PROG -d -c "pwrite -S 0xbd -b 64K $physical3 64K" \
+       $devpath3 > /dev/null
+
+$XFS_IO_PROG -d -c "pwrite -S 0xba -b 64K $physical1 128K" \
+       $devpath1 > /dev/null
+
+$XFS_IO_PROG -d -c "pwrite -S 0xbb -b 64K $((physical2 + 65536)) 128K" \
+       $devpath2 > /dev/null
+
+$XFS_IO_PROG -d -c "pwrite -S 0xbc -b 64K $((physical3 + (2 * 65536))) 128K"  \
+       $devpath3 > /dev/null
+
+_scratch_mount
+
+# step 3, 128k dio read (this read can repair bad copy)
+echo "step 3......repair the bad copy"
+
+_btrfs_buffered_read_on_mirror 0 3 "$SCRATCH_MNT/foobar" 0 256K
+_btrfs_buffered_read_on_mirror 1 3 "$SCRATCH_MNT/foobar" 0 256K
+_btrfs_buffered_read_on_mirror 2 3 "$SCRATCH_MNT/foobar" 0 256K
+
+_scratch_unmount
+
+echo "step 4......check if the repair worked"
+$XFS_IO_PROG -d -c "pread -v -b 512 $physical1 512" $devpath1 |\
+       _filter_xfs_io_offset
+$XFS_IO_PROG -d -c "pread -v -b 512 $physical2 512" $devpath2 |\
+       _filter_xfs_io_offset
+$XFS_IO_PROG -d -c "pread -v -b 512 $physical3 512" $devpath3 |\
+       _filter_xfs_io_offset
+
+_scratch_dev_pool_put
+# success, all done
+status=0
+exit
diff --git a/tests/btrfs/266.out b/tests/btrfs/266.out
new file mode 100644 (file)
index 0000000..fcf2f5b
--- /dev/null
@@ -0,0 +1,109 @@
+QA output created by 266
+step 1......mkfs.btrfs
+wrote 262144/262144 bytes
+XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+step 2......corrupt file extent
+step 3......repair the bad copy
+step 4......check if the repair worked
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+read 512/512 bytes
+XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+read 512/512 bytes
+XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+read 512/512 bytes
+XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
diff --git a/tests/btrfs/267 b/tests/btrfs/267
new file mode 100755 (executable)
index 0000000..75a6fdc
--- /dev/null
@@ -0,0 +1,93 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2017 Liu Bo.  All Rights Reserved.
+# Copyright (c) 2022 Christoph Hellwig.
+#
+# FS QA Test 267
+#
+# Test that btrfs buffered read repair on a raid1c3 profile can repair
+# interleaving errors on all mirrors.
+#
+
+. ./common/preamble
+_begin_fstest auto quick read_repair
+
+# Import common functions.
+. ./common/filter
+
+# real QA test starts here
+
+_supported_fs btrfs
+_require_scratch_dev_pool 3
+
+_require_odirect
+# Overwriting data is forbidden on a zoned block device
+_require_non_zoned_device "${SCRATCH_DEV}"
+
+_scratch_dev_pool_get 3
+# step 1, create a raid1 btrfs which contains one 128k file.
+echo "step 1......mkfs.btrfs"
+
+mkfs_opts="-d raid1c3 -b 1G"
+_scratch_pool_mkfs $mkfs_opts >>$seqres.full 2>&1
+
+_scratch_mount
+
+$XFS_IO_PROG -f -d -c "pwrite -S 0xaa -b 256K 0 256K" \
+       "$SCRATCH_MNT/foobar" | \
+       _filter_xfs_io_offset
+
+# step 2, corrupt 64k in each copy
+echo "step 2......corrupt file extent"
+
+# ensure btrfs-map-logical sees the tree updates
+sync
+
+logical=$(_btrfs_get_first_logical $SCRATCH_MNT/foobar)
+
+physical1=$(_btrfs_get_physical ${logical} 1)
+devpath1=$(_btrfs_get_device_path ${logical} 1)
+
+physical2=$(_btrfs_get_physical ${logical} 2)
+devpath2=$(_btrfs_get_device_path ${logical} 2)
+
+physical3=$(_btrfs_get_physical ${logical} 3)
+devpath3=$(_btrfs_get_device_path ${logical} 3)
+
+_scratch_unmount
+
+$XFS_IO_PROG -d -c "pwrite -S 0xbd -b 64K $physical3 64K" \
+       $devpath3 > /dev/null
+
+$XFS_IO_PROG -d -c "pwrite -S 0xba -b 64K $physical1 128K" \
+       $devpath1 > /dev/null
+
+$XFS_IO_PROG -d -c "pwrite -S 0xbb -b 64K $((physical2 + 65536)) 128K" \
+       $devpath2 > /dev/null
+
+$XFS_IO_PROG -d -c "pwrite -S 0xbc -b 64K $((physical3 + (2 * 65536))) 128K"  \
+       $devpath3 > /dev/null
+
+_scratch_mount
+
+# step 3, 128k dio read (this read can repair bad copy)
+echo "step 3......repair the bad copy"
+
+_btrfs_direct_read_on_mirror 0 3 "$SCRATCH_MNT/foobar" 0 256K
+_btrfs_direct_read_on_mirror 1 3 "$SCRATCH_MNT/foobar" 0 256K
+_btrfs_direct_read_on_mirror 2 3 "$SCRATCH_MNT/foobar" 0 256K
+
+_scratch_unmount
+
+echo "step 4......check if the repair worked"
+$XFS_IO_PROG -d -c "pread -v -b 512 $physical1 512" $devpath1 |\
+       _filter_xfs_io_offset
+$XFS_IO_PROG -d -c "pread -v -b 512 $physical2 512" $devpath2 |\
+       _filter_xfs_io_offset
+$XFS_IO_PROG -d -c "pread -v -b 512 $physical3 512" $devpath3 |\
+       _filter_xfs_io_offset
+
+_scratch_dev_pool_put
+# success, all done
+status=0
+exit
diff --git a/tests/btrfs/267.out b/tests/btrfs/267.out
new file mode 100644 (file)
index 0000000..2bdd32e
--- /dev/null
@@ -0,0 +1,109 @@
+QA output created by 267
+step 1......mkfs.btrfs
+wrote 262144/262144 bytes
+XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+step 2......corrupt file extent
+step 3......repair the bad copy
+step 4......check if the repair worked
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+read 512/512 bytes
+XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+read 512/512 bytes
+XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+XXXXXXXX:  aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa  ................
+read 512/512 bytes
+XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
index 7970ce352babfd2e69133cec57194e576b56914f..060c4c450091f9af2f45e33b4f5d7092b84838c9 100755 (executable)
@@ -86,11 +86,15 @@ check_copyfrom_metrics()
        local copies=$4
        local c1=$(get_copyfrom_total_copies)
        local s1=$(get_copyfrom_total_size)
+       local hascopyfrom=$(_fs_options $TEST_DEV | grep "copyfrom")
        local sum
 
-       if [ ! -d $metrics_dir ]; then
+       if [ ! -d "$metrics_dir" ]; then
                return # skip metrics check if debugfs isn't mounted
        fi
+       if [ -z "$hascopyfrom" ]; then
+               return # ... or if we don't have copyfrom mount option
+       fi
 
        sum=$(($c0+$copies))
        if [ $sum -ne $c1 ]; then
index f7f1c0ba84876cc392e78e88d607956d2aecdd96..4f766c257a9cea734ba4af33ea3246314d027c04 100644 (file)
@@ -5,4 +5,4 @@ QA output created by 002
 *
 800000 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63  >cccccccccccccccc<
 *
-c000000
+c00000
index 187a25154cd60419e81c404c022c83658ccef327..555e474ef8a5a39f5af78a016fa5cb22c15329fe 100755 (executable)
@@ -511,20 +511,6 @@ for fstype in ext2 ext3 ext4; do
        mnt noinit_itable
        mnt max_dir_size_kb=4096
 
-       if _has_kernel_config CONFIG_FS_ENCRYPTION; then
-               mnt test_dummy_encryption
-               mnt test_dummy_encryption=v1
-               mnt test_dummy_encryption=v2
-               not_mnt test_dummy_encryption=v3
-               not_mnt test_dummy_encryption=
-       else
-               mnt test_dummy_encryption ^test_dummy_encryption
-               mnt test_dummy_encryption=v1 ^test_dummy_encryption=v1
-               mnt test_dummy_encryption=v2 ^test_dummy_encryption=v2
-               mnt test_dummy_encryption=v3 ^test_dummy_encryption=v3
-               not_mnt test_dummy_encryption=
-       fi
-
        if _has_kernel_config CONFIG_FS_ENCRYPTION_INLINE_CRYPT; then
                mnt inlinecrypt
        else
@@ -686,6 +672,30 @@ for fstype in ext2 ext3 ext4; do
        mnt_then_not_remount defaults jqfmt=vfsv1
        remount defaults grpjquota=,usrjquota= ignored
 
+       echo "== Testing the test_dummy_encryption option" >> $seqres.full
+       # Since kernel commit 5f41fdaea63d ("ext4: only allow
+       # test_dummy_encryption when supported"), the test_dummy_encryption
+       # option is only allowed when the filesystem has the encrypt feature and
+       # the kernel has CONFIG_FS_ENCRYPTION.  The encrypt feature requirement
+       # implies that this option is never allowed on ext2 or ext3 mounts.
+       if [[ $fstype == ext4 ]] && _has_kernel_config CONFIG_FS_ENCRYPTION; then
+               do_mkfs -O encrypt $SCRATCH_DEV ${SIZE}k
+               mnt test_dummy_encryption
+               mnt test_dummy_encryption=v1
+               mnt test_dummy_encryption=v2
+               not_mnt test_dummy_encryption=bad
+               not_mnt test_dummy_encryption=
+               # Can't be set or changed on remount.
+               mnt_then_not_remount defaults test_dummy_encryption
+               mnt_then_not_remount test_dummy_encryption=v1 test_dummy_encryption=v2
+               do_mkfs -O ^encrypt $SCRATCH_DEV ${SIZE}k
+       fi
+       not_mnt test_dummy_encryption
+       not_mnt test_dummy_encryption=v1
+       not_mnt test_dummy_encryption=v2
+       not_mnt test_dummy_encryption=bad
+       not_mnt test_dummy_encryption=
+
 done #for fstype in ext2 ext3 ext4; do
 
 $UMOUNT_PROG $SCRATCH_MNT > /dev/null 2>&1
index d8648e96286e1b0491b05ed314b1446a5d168411..b91bca34dcd485bfc3727caaa1f226f94b1d9286 100755 (executable)
@@ -51,13 +51,9 @@ _attr_list()
     fi
 }
 
-# set fs-specific max_attrs and max_attrval_size values. The parameter
-# @max_attrval_namelen is required for filesystems which take into account attr
-# name lengths (including namespace prefix) when determining limits.
+# set fs-specific max_attrs
 _attr_get_max()
 {
-       local max_attrval_namelen="$1"
-
        # set maximum total attr space based on fs type
        case "$FSTYP" in
        xfs|udf|pvfs2|9p|ceph|nfs)
@@ -112,6 +108,16 @@ _attr_get_max()
                # overhead
                let max_attrs=$BLOCK_SIZE/40
        esac
+}
+
+# set fs-specific max_attrval_size values. The parameter @max_attrval_namelen is
+# required for filesystems which take into account attr name lengths (including
+# namespace prefix) when determining limits; parameter @filename is required for
+# filesystems that need to take into account already existing attrs.
+_attr_get_maxval_size()
+{
+       local max_attrval_namelen="$1"
+       local filename="$2"
 
        # Set max attr value size in bytes based on fs type
        case "$FSTYP" in
@@ -128,7 +134,7 @@ _attr_get_max()
        pvfs2)
                max_attrval_size=8192
                ;;
-       xfs|udf|9p|ceph)
+       xfs|udf|9p)
                max_attrval_size=65536
                ;;
        bcachefs)
@@ -139,6 +145,15 @@ _attr_get_max()
                # the underlying filesystem, so just use the lowest value above.
                max_attrval_size=1024
                ;;
+       ceph)
+               # CephFS does not have a maximum value for attributes.  Instead,
+               # it imposes a maximum size for the full set of xattrs
+               # names+values, which by default is 64K.  Compute the maximum
+               # taking into account the already existing attributes
+               max_attrval_size=$(getfattr --dump -e hex $filename 2>/dev/null | \
+                       awk -F "=0x" '/^user/ {len += length($1) + length($2) / 2} END {print len}')
+               max_attrval_size=$((65536 - $max_attrval_size - $max_attrval_namelen))
+               ;;
        *)
                # Assume max ~1 block of attrs
                BLOCK_SIZE=`_get_block_size $TEST_DIR`
@@ -181,8 +196,7 @@ echo "*** remove attribute"
 _attr -r fish $testfile
 _attr_list $testfile
 
-max_attrval_name="long_attr"   # add 5 for "user." prefix
-_attr_get_max "$(( 5 + ${#max_attrval_name} ))"
+_attr_get_max
 
 echo "*** add lots of attributes"
 v=0
@@ -226,6 +240,9 @@ done
 _attr_list $testfile
 
 echo "*** really long value"
+max_attrval_name="long_attr"   # add 5 for "user." prefix
+_attr_get_maxval_size "$(( 5 + ${#max_attrval_name} ))" "$testfile"
+
 dd if=/dev/zero bs=1 count=$max_attrval_size 2>/dev/null \
     | _attr -s "$max_attrval_name" $testfile >/dev/null
 
index c6cea94e345bb479a36ff9e503f4f666710a8aef..e9b4996787f4a0ecd0380107425ad36820b31cba 100755 (executable)
@@ -36,6 +36,10 @@ _begin_fstest auto stress trim
 # Override the default cleanup function.
 _cleanup()
 {
+       [ -n "${create_pids}" ] && kill ${create_pids[@]}
+       [ -n "${fallocate_pids}" ] && kill ${fallocate_pids[@]}
+       [ -n "${trim_pids}" ] && kill ${trim_pids[@]}
+       wait
        rm -fr $tmp
 }
 
@@ -47,6 +51,8 @@ _supported_fs generic
 _require_scratch
 _require_xfs_io_command "falloc"
 
+echo "Silence is golden"
+
 # Keep allocating and deallocating 1G of data space with the goal of creating
 # and deleting 1 block group constantly. The intention is to race with the
 # fstrim loop below.
@@ -113,7 +119,7 @@ create_files()
        done
 
        wait ${create_pids[@]}
-
+       unset create_pids
 }
 
 _scratch_mkfs >>$seqres.full 2>&1
@@ -136,12 +142,8 @@ create_files "foobar"
 kill ${fallocate_pids[@]}
 kill ${trim_pids[@]}
 wait
+unset fallocate_pids
+unset trim_pids
 
-# The fstests framework will now check for fs consistency with fsck.
-# The trimming was racy and caused some btree nodes to get full of zeroes on
-# disk, which obviously caused fs metadata corruption. The race often lead
-# to missing free space entries in a block group's free space cache too.
-
-echo "Silence is golden"
 status=0
 exit
index 56262cd7a646168632c83ce0f1e4ccd08b52ee91..eeddf6d1d99c61d41397a23290664f4f438549d9 100755 (executable)
@@ -17,9 +17,12 @@ ITERATIONS=10
 # Override the default cleanup function.
 _cleanup()
 {
-    cd /
-
-    trap 0 1 2 3 15
+       # Make sure $SCRATCH_MNT is unfreezed
+       xfs_freeze -u $SCRATCH_MNT 2>/dev/null
+       [ -n "$pid" ] && kill -9 $pid 2>/dev/null
+       wait $pid
+       cd /
+       rm -f $tmp.*
 }
 
 # Import common functions.
@@ -60,6 +63,7 @@ touch $tmp.running
     rm -r $STRESS_DIR/*
     rmdir $STRESS_DIR
 } &
+pid=$!
 
 # start fstest -m loop in a background block; this gets us mmap coverage
 {
@@ -75,6 +79,7 @@ touch $tmp.running
     rm -rf $FSTEST_DIR/*
     rmdir $FSTEST_DIR
 } &
+pid="$pid $!"
 
 i=0
 let ITERATIONS=$ITERATIONS-1
@@ -103,6 +108,7 @@ done
 rm $tmp.running
 
 # wait for fsstresses to finish
-wait
+wait $pid
+unset pid
 
 exit 1
index 20cf875a27ec621b581dd5a643257ba1bc3b0700..786d8e6fab162d66cd8790ee9158fb99a5dd2ee5 100755 (executable)
@@ -25,6 +25,8 @@ cleanup_dmdev()
 {
        # in case it's still suspended and/or mounted
        $DMSETUP_PROG resume $lvdev >/dev/null 2>&1
+       [ -n "$pid" ] && kill -9 $pid 2>/dev/null
+       wait $pid
        $UMOUNT_PROG $lvdev >/dev/null 2>&1
        _dmsetup_remove $node
 }
@@ -75,6 +77,7 @@ done &
 pid="$pid $!"
 
 wait $pid
+unset pid
 
 status=0
 exit
index 0bbc222ca3d5b06cb3fb5bdc6f829a74617b2284..3eb1519d8718012b556c40a599af4bc2db42c0b2 100755 (executable)
@@ -26,7 +26,7 @@ _cleanup()
 # real QA test starts here
 _require_test_reflink
 _require_cp_reflink
-_require_odirect
+_require_odirect 512
 
 testdir=$TEST_DIR/test-$seq
 rm -rf $testdir
index 071445558e75d1f0e43c3e58718bc7173e3843b0..8e1ae4d298163b874cf701d899f123a5caeb3565 100755 (executable)
 . ./common/preamble
 _begin_fstest auto quota freeze
 
+# Override the default cleanup function.
+_cleanup()
+{
+       # Make sure $SCRATCH_MNT is unfreezed
+       xfs_freeze -u $SCRATCH_MNT 2>/dev/null
+       [ -n "$pid" ] && kill -9 $pid 2>/dev/null
+       wait $pid
+       cd /
+       rm -f $tmp.*
+}
+
 # Import common functions.
 . ./common/filter
 . ./common/quota
@@ -34,7 +45,7 @@ pid=$!
 sleep 1
 xfs_freeze -u $SCRATCH_MNT
 wait $pid
-_scratch_unmount
+unset pid
 
 # Failure comes in the form of a deadlock.
 
index 676b876b4f0a38eafb192f9bab74e0cb93ce0d7b..cdffaaf3f9e31fd942b3db2b8411e1a131a8a2d2 100755 (executable)
@@ -31,6 +31,11 @@ _require_dm_target flakey
 
 _scratch_mkfs >>$seqres.full 2>&1
 _require_metadata_journaling $SCRATCH_DEV
+
+if [ $FSTYP = "f2fs" ]; then
+       export MOUNT_OPTIONS="-o fsync_mode=strict $MOUNT_OPTIONS"
+fi
+
 _init_flakey
 _mount_flakey
 
index 20c66e22946bf6140bf8543edc791e0ac271b14e..e8f6a5dc1ceac9a5a90e72f35cfcc04d5974de3a 100755 (executable)
@@ -14,8 +14,12 @@ _begin_fstest auto freeze stress
 _cleanup()
 {
        cd /
-       # Make sure $SCRATCH_MNT is unfreezed
+       # Kill freeze loops and make sure $SCRATCH_MNT is unfreezed
+       [ -n "$freeze_pids" ] && kill -9 $freeze_pids 2>/dev/null
+       wait $freeze_pids
        xfs_freeze -u $SCRATCH_MNT 2>/dev/null
+       [ -n "$fsstress_pid" ] && kill -9 $fsstress_pid 2>/dev/null
+       wait $fsstress_pid
        rm -f $tmp.*
 }
 
@@ -62,7 +66,9 @@ done
 
 wait $fsstress_pid
 result=$?
+unset fsstress_pid
 wait $freeze_pids
+unset freeze_pids
 
 # Exit with fsstress return value
 status=$result
index 57d58e55c10d5d0b860d57665318d32e2bc9e4df..7be3908995dff4feacc99367b6270aad7b9c4f54 100755 (executable)
@@ -24,6 +24,8 @@ _begin_fstest auto freeze thin
 # Override the default cleanup function.
 _cleanup()
 {
+       # Make sure $SCRATCH_MNT is unfreezed
+       xfs_freeze -u $SCRATCH_MNT 2>/dev/null
        cd /
        rm -f $tmp.*
        $UMOUNT_PROG $SCRATCH_MNT >>$seqres.full 2>&1
index 7de198f93a7174abfe8c58350c3c3915ab4900c4..7dbfcb9835d962cf58fd08633fb88dd4ca474a33 100755 (executable)
@@ -41,7 +41,16 @@ filter_attr_output() {
                sed -e 's/has a [0-9]* byte value/has a NNNN byte value/g'
 }
 
-$here/src/attr_replace_test $SCRATCH_MNT/hello
+max_attr_size=65536
+
+# attr_replace_test can't easily auto-probe the attr size for ceph because:
+# - ceph imposes a maximum value for the total xattr names+values, and
+# - ceph reports the 'object size' in the block size, which is, by default, much
+#   larger than XATTR_SIZE_MAX (4M > 64k)
+# Hence, we need to provide it with a maximum size.
+[ "$FSTYP" = "ceph" ] && max_attr_size=65000
+
+$here/src/attr_replace_test -m $max_attr_size $SCRATCH_MNT/hello
 $ATTR_PROG -l $SCRATCH_MNT/hello >>$seqres.full 2>&1
 $ATTR_PROG -l $SCRATCH_MNT/hello | filter_attr_output
 
index e6e57dcd6946d335bced2ff475e50cb7d2a05fd0..797b08d506ea9607c08ef367347bb2bf9d30b75f 100755 (executable)
 . ./common/preamble
 _begin_fstest auto quick freeze mount
 
+# Override the default cleanup function.
+_cleanup()
+{
+       cd /
+       # Make sure $SCRATCH_MNT is unfreezed
+       xfs_freeze -u $SCRATCH_MNT 2>/dev/null
+       rm -f $tmp.*
+}
+
 # Import common functions.
 . ./common/filter
 
index b0f9077fc3b3058e78ad747c09145ef9cc093b01..b5589b8139d17a447d74c8028371372cc0900cee 100755 (executable)
@@ -34,6 +34,11 @@ _require_dm_target flakey
 
 _scratch_mkfs >>$seqres.full 2>&1
 _require_metadata_journaling $SCRATCH_DEV
+
+if [ $FSTYP = "f2fs" ]; then
+       export MOUNT_OPTIONS="-o fsync_mode=strict $MOUNT_OPTIONS"
+fi
+
 _init_flakey
 _mount_flakey
 
index 25a5b0f8c2dd12e275a4b321cc917f8ba69d9173..ec91af781c7582f97736d429a4dbb9513c8bfb2d 100755 (executable)
@@ -27,6 +27,7 @@ _begin_fstest shutdown auto quick metadata quota
 _supported_fs generic
 
 _require_scratch
+_require_quota
 _require_scratch_shutdown
 
 _scratch_mkfs >/dev/null 2>&1
index dc7cb36c198fcfb7043835cfa1fd6af7898e07fc..ada4dbeebd2253ebc7a09f894fa1eeacdf2e999e 100755 (executable)
@@ -32,6 +32,11 @@ _require_dm_target flakey
 
 _scratch_mkfs >>$seqres.full 2>&1
 _require_metadata_journaling $SCRATCH_DEV
+
+if [ $FSTYP = "f2fs" ]; then
+       export MOUNT_OPTIONS="-o fsync_mode=strict $MOUNT_OPTIONS"
+fi
+
 _init_flakey
 _mount_flakey
 
index 40cd1c6a29e8fc6fd360e79eab119c6696f7c47f..de09d1718f9c078666d31563d65619c5bbce3db9 100755 (executable)
@@ -32,6 +32,11 @@ _require_dm_target flakey
 
 _scratch_mkfs >>$seqres.full 2>&1
 _require_metadata_journaling $SCRATCH_DEV
+
+if [ $FSTYP = "f2fs" ]; then
+       export MOUNT_OPTIONS="-o fsync_mode=strict $MOUNT_OPTIONS"
+fi
+
 _init_flakey
 _mount_flakey
 
index 5efc5136f31a086edbf936f7e720a9ddeecc6009..4de50e2a4ec938332cfd9c9f8991be379094defc 100755 (executable)
@@ -24,9 +24,11 @@ _require_test
 _require_odirect
 _require_test_program "splice-test"
 
-$here/src/splice-test -r $TEST_DIR/a
+diosize=`_min_dio_alignment $TEST_DEV`
+
+$here/src/splice-test -s $diosize -r $TEST_DIR/a
 $here/src/splice-test -rd $TEST_DIR/a
-$here/src/splice-test $TEST_DIR/a
+$here/src/splice-test -s $diosize $TEST_DIR/a
 $here/src/splice-test -d $TEST_DIR/a
 
 # success, all done
index d61811ee9c7003c42556a1150f1fcd349da9d590..e9fffd1da472a296af11d7487c56491b157666eb 100644 (file)
@@ -1,7 +1,5 @@
 QA output created by 591
 concurrent reader with O_DIRECT
-concurrent reader with O_DIRECT
-concurrent reader without O_DIRECT
 concurrent reader without O_DIRECT
 sequential reader with O_DIRECT
 sequential reader without O_DIRECT
index 324251b7c642eb13d800d14792eb14ef9dc3cdc7..ea016d91a1c651ffa31dd6cf03a08f18d0677934 100755 (executable)
@@ -12,6 +12,9 @@ _begin_fstest auto quick shutdown
 . ./common/filter
 
 _supported_fs generic
+_fixed_by_kernel_commit e4826691cc7e \
+       "xfs: restore shutdown check in mapped write fault path"
+
 _require_scratch_nocheck
 _require_scratch_shutdown
 
index 219f7a05e7fc4ba0fd66c949aa9bd90c53a266ac..ff1bb11301b62976de079f9e633187ca0d888e5a 100755 (executable)
@@ -40,6 +40,8 @@ _require_scratch
 _require_attrs trusted
 _supported_fs ^overlay
 _require_extra_fs overlay
+_fixed_by_kernel_commit 6da1b4b1ab36 \
+       "xfs: fix an ABBA deadlock in xfs_rename"
 
 _scratch_mkfs >> $seqres.full
 _scratch_mount
index 79d3f17cb4ed9313c426f5ade9bcec51236726a9..027df5570f81ca5c56762b3ffac14c64f82b17fa 100755 (executable)
@@ -15,6 +15,9 @@
 _begin_fstest auto quick recoveryloop shutdown
 
 # real QA test starts here
+_supported_fs generic
+_fixed_by_kernel_commit 50d25484bebe \
+       "xfs: sync lazy sb accounting on quiesce of read-only mounts"
 
 _require_scratch
 _require_scratch_shutdown
index a6aabfaf724233837c1aa43b54728c647606bbe7..d6727765d7a3ae98ae1bc7fec6e9f637c72be1a2 100755 (executable)
@@ -33,6 +33,9 @@ _cleanup()
 
 # Modify as appropriate.
 _supported_fs generic
+_fixed_by_kernel_commit 72a048c1056a \
+       "xfs: only set IOMAP_F_SHARED when providing a srcmap to a write"
+
 _require_cp_reflink
 _require_test_reflink
 _require_test_program "punch-alternating"
index d6e9099e961a79d4a033a472f7ad1ebb3e11554e..ed44d074b55925fcc3a7513813b0b2554e9895c6 100755 (executable)
@@ -16,10 +16,11 @@ _begin_fstest auto freeze log metadata quick
 # Override the default cleanup function.
 _cleanup()
 {
+       # Make sure $SCRATCH_MNT is unfreezed
+       xfs_freeze -u $SCRATCH_MNT 2>/dev/null
        $KILLALL_PROG -9 fsstress 2>/dev/null
        wait
        cd /
-       _scratch_unmount 2>/dev/null
        rm -f $tmp.*
 }
 
diff --git a/tests/xfs/018 b/tests/xfs/018
new file mode 100755 (executable)
index 0000000..041a3b2
--- /dev/null
@@ -0,0 +1,181 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2022, Oracle and/or its affiliates.  All Rights Reserved.
+#
+# FS QA Test No. 018
+#
+# Log attribute replay test
+#
+. ./common/preamble
+_begin_fstest auto quick attr
+
+# get standard environment, filters and checks
+. ./common/filter
+. ./common/attr
+. ./common/inject
+
+_cleanup()
+{
+       rm -rf $tmp.*
+       if [ -n "$ORIG_XFS_LARP" ];then
+               echo $ORIG_XFS_LARP > /sys/fs/xfs/debug/larp
+       fi
+}
+
+test_attr_replay()
+{
+       testfile=$testdir/$1
+       attr_name=$2
+       attr_value=$3
+       flag=$4
+       error_tag=$5
+
+       # Inject error
+       _scratch_inject_error $error_tag
+
+       # Set attribute
+       echo "$attr_value" | ${ATTR_PROG} -$flag "$attr_name" $testfile 2>&1 | \
+                           _filter_scratch
+
+       # FS should be shut down, touch will fail
+       touch $testfile 2>&1 | _filter_scratch
+
+       # Remount to replay log
+       _scratch_remount_dump_log >> $seqres.full
+
+       # FS should be online, touch should succeed
+       touch $testfile
+
+       # Verify attr recovery
+       $ATTR_PROG -l $testfile | _filter_scratch
+       echo -n "$attr_name: "
+       $ATTR_PROG -q -g $attr_name $testfile 2> /dev/null | md5sum;
+
+       echo ""
+}
+
+create_test_file()
+{
+       filename=$testdir/$1
+       count=$2
+       attr_value=$3
+
+       touch $filename
+
+       for i in `seq $count`
+       do
+               $ATTR_PROG -s "attr_name$i" -V $attr_value $filename >> \
+                       $seqres.full
+       done
+}
+
+# real QA test starts here
+_supported_fs xfs
+
+_require_scratch
+_require_scratch_xfs_crc
+_require_attrs
+_require_xfs_io_error_injection "larp"
+_require_xfs_io_error_injection "da_leaf_split"
+_require_xfs_io_error_injection "attr_leaf_to_node"
+_require_xfs_sysfs debug/larp
+test -w /sys/fs/xfs/debug/larp || _notrun "larp knob not writable"
+
+ORIG_XFS_LARP=`cat /sys/fs/xfs/debug/larp`
+# turn on log attributes
+echo 1 > /sys/fs/xfs/debug/larp
+
+attr16="0123456789ABCDEF"
+attr64="$attr16$attr16$attr16$attr16"
+attr256="$attr64$attr64$attr64$attr64"
+attr1k="$attr256$attr256$attr256$attr256"
+attr4k="$attr1k$attr1k$attr1k$attr1k"
+attr8k="$attr4k$attr4k"
+attr16k="$attr8k$attr8k"
+attr32k="$attr16k$attr16k"
+attr64k="$attr32k$attr32k"
+
+echo "*** mkfs"
+_scratch_mkfs >/dev/null
+
+echo "*** mount FS"
+_scratch_mount
+
+testdir=$SCRATCH_MNT/testdir
+mkdir $testdir
+
+# empty, inline
+create_test_file empty_file1 0
+test_attr_replay empty_file1 "attr_name" $attr64 "s" "larp"
+test_attr_replay empty_file1 "attr_name" $attr64 "r" "larp"
+
+# empty, internal
+create_test_file empty_file2 0
+test_attr_replay empty_file2 "attr_name" $attr1k "s" "larp"
+test_attr_replay empty_file2 "attr_name" $attr1k "r" "larp"
+
+# empty, remote
+create_test_file empty_file3 0
+test_attr_replay empty_file3 "attr_name" $attr64k "s" "larp"
+test_attr_replay empty_file3 "attr_name" $attr64k "r" "larp"
+
+# inline, inline
+create_test_file inline_file1 1 $attr16
+test_attr_replay inline_file1 "attr_name2" $attr64 "s" "larp"
+test_attr_replay inline_file1 "attr_name2" $attr64 "r" "larp"
+
+# inline, internal
+create_test_file inline_file2 1 $attr16
+test_attr_replay inline_file2 "attr_name2" $attr1k "s" "larp"
+test_attr_replay inline_file2 "attr_name2" $attr1k "r" "larp"
+
+# inline, remote
+create_test_file inline_file3 1 $attr16
+test_attr_replay inline_file3 "attr_name2" $attr64k "s" "larp"
+test_attr_replay inline_file3 "attr_name2" $attr64k "r" "larp"
+
+# extent, internal
+create_test_file extent_file1 1 $attr1k
+test_attr_replay extent_file1 "attr_name2" $attr1k "s" "larp"
+test_attr_replay extent_file1 "attr_name2" $attr1k "r" "larp"
+
+# extent, inject error on split
+create_test_file extent_file2 3 $attr1k
+test_attr_replay extent_file2 "attr_name4" $attr1k "s" "da_leaf_split"
+
+# extent, inject error on fork transition
+create_test_file extent_file3 3 $attr1k
+test_attr_replay extent_file3 "attr_name4" $attr1k "s" "attr_leaf_to_node"
+
+# extent, remote
+create_test_file extent_file4 1 $attr1k
+test_attr_replay extent_file4 "attr_name2" $attr64k "s" "larp"
+test_attr_replay extent_file4 "attr_name2" $attr64k "r" "larp"
+
+# remote, internal
+create_test_file remote_file1 1 $attr64k
+test_attr_replay remote_file1 "attr_name2" $attr1k "s" "larp"
+test_attr_replay remote_file1 "attr_name2" $attr1k "r" "larp"
+
+# remote, remote
+create_test_file remote_file2 1 $attr64k
+test_attr_replay remote_file2 "attr_name2" $attr64k "s" "larp"
+test_attr_replay remote_file2 "attr_name2" $attr64k "r" "larp"
+
+# replace shortform with different value
+create_test_file sf_file 2 $attr64
+test_attr_replay sf_file "attr_name2" $attr16 "s" "larp"
+
+# replace leaf with different value
+create_test_file leaf_file 3 $attr1k
+test_attr_replay leaf_file "attr_name2" $attr256 "s" "larp"
+
+# replace node with a different value
+create_test_file node_file 1 $attr64k
+$ATTR_PROG -s "attr_name2" -V $attr1k $testdir/node_file \
+               >> $seqres.full
+test_attr_replay node_file "attr_name2" $attr256 "s" "larp"
+
+echo "*** done"
+status=0
+exit
diff --git a/tests/xfs/018.out b/tests/xfs/018.out
new file mode 100644 (file)
index 0000000..022b0ca
--- /dev/null
@@ -0,0 +1,168 @@
+QA output created by 018
+*** mkfs
+*** mount FS
+attr_set: Input/output error
+Could not set "attr_name" for SCRATCH_MNT/testdir/empty_file1
+touch: cannot touch 'SCRATCH_MNT/testdir/empty_file1': Input/output error
+Attribute "attr_name" has a 65 byte value for SCRATCH_MNT/testdir/empty_file1
+attr_name: cfbe2a33be4601d2b655d099a18378fc  -
+
+attr_remove: Input/output error
+Could not remove "attr_name" for SCRATCH_MNT/testdir/empty_file1
+touch: cannot touch 'SCRATCH_MNT/testdir/empty_file1': Input/output error
+attr_name: d41d8cd98f00b204e9800998ecf8427e  -
+
+attr_set: Input/output error
+Could not set "attr_name" for SCRATCH_MNT/testdir/empty_file2
+touch: cannot touch 'SCRATCH_MNT/testdir/empty_file2': Input/output error
+Attribute "attr_name" has a 1025 byte value for SCRATCH_MNT/testdir/empty_file2
+attr_name: 9fd415c49d67afc4b78fad4055a3a376  -
+
+attr_remove: Input/output error
+Could not remove "attr_name" for SCRATCH_MNT/testdir/empty_file2
+touch: cannot touch 'SCRATCH_MNT/testdir/empty_file2': Input/output error
+attr_name: d41d8cd98f00b204e9800998ecf8427e  -
+
+attr_set: Input/output error
+Could not set "attr_name" for SCRATCH_MNT/testdir/empty_file3
+touch: cannot touch 'SCRATCH_MNT/testdir/empty_file3': Input/output error
+Attribute "attr_name" has a 65536 byte value for SCRATCH_MNT/testdir/empty_file3
+attr_name: 7f6fd1b6d872108bd44bd143cbcdfa19  -
+
+attr_remove: Input/output error
+Could not remove "attr_name" for SCRATCH_MNT/testdir/empty_file3
+touch: cannot touch 'SCRATCH_MNT/testdir/empty_file3': Input/output error
+attr_name: d41d8cd98f00b204e9800998ecf8427e  -
+
+attr_set: Input/output error
+Could not set "attr_name2" for SCRATCH_MNT/testdir/inline_file1
+touch: cannot touch 'SCRATCH_MNT/testdir/inline_file1': Input/output error
+Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file1
+Attribute "attr_name2" has a 65 byte value for SCRATCH_MNT/testdir/inline_file1
+attr_name2: cfbe2a33be4601d2b655d099a18378fc  -
+
+attr_remove: Input/output error
+Could not remove "attr_name2" for SCRATCH_MNT/testdir/inline_file1
+touch: cannot touch 'SCRATCH_MNT/testdir/inline_file1': Input/output error
+Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file1
+attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
+
+attr_set: Input/output error
+Could not set "attr_name2" for SCRATCH_MNT/testdir/inline_file2
+touch: cannot touch 'SCRATCH_MNT/testdir/inline_file2': Input/output error
+Attribute "attr_name2" has a 1025 byte value for SCRATCH_MNT/testdir/inline_file2
+Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file2
+attr_name2: 9fd415c49d67afc4b78fad4055a3a376  -
+
+attr_remove: Input/output error
+Could not remove "attr_name2" for SCRATCH_MNT/testdir/inline_file2
+touch: cannot touch 'SCRATCH_MNT/testdir/inline_file2': Input/output error
+Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file2
+attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
+
+attr_set: Input/output error
+Could not set "attr_name2" for SCRATCH_MNT/testdir/inline_file3
+touch: cannot touch 'SCRATCH_MNT/testdir/inline_file3': Input/output error
+Attribute "attr_name2" has a 65536 byte value for SCRATCH_MNT/testdir/inline_file3
+Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file3
+attr_name2: 7f6fd1b6d872108bd44bd143cbcdfa19  -
+
+attr_remove: Input/output error
+Could not remove "attr_name2" for SCRATCH_MNT/testdir/inline_file3
+touch: cannot touch 'SCRATCH_MNT/testdir/inline_file3': Input/output error
+Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file3
+attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
+
+attr_set: Input/output error
+Could not set "attr_name2" for SCRATCH_MNT/testdir/extent_file1
+touch: cannot touch 'SCRATCH_MNT/testdir/extent_file1': Input/output error
+Attribute "attr_name2" has a 1025 byte value for SCRATCH_MNT/testdir/extent_file1
+Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file1
+attr_name2: 9fd415c49d67afc4b78fad4055a3a376  -
+
+attr_remove: Input/output error
+Could not remove "attr_name2" for SCRATCH_MNT/testdir/extent_file1
+touch: cannot touch 'SCRATCH_MNT/testdir/extent_file1': Input/output error
+Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file1
+attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
+
+attr_set: Input/output error
+Could not set "attr_name4" for SCRATCH_MNT/testdir/extent_file2
+touch: cannot touch 'SCRATCH_MNT/testdir/extent_file2': Input/output error
+Attribute "attr_name4" has a 1025 byte value for SCRATCH_MNT/testdir/extent_file2
+Attribute "attr_name2" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file2
+Attribute "attr_name3" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file2
+Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file2
+attr_name4: 9fd415c49d67afc4b78fad4055a3a376  -
+
+attr_set: Input/output error
+Could not set "attr_name4" for SCRATCH_MNT/testdir/extent_file3
+touch: cannot touch 'SCRATCH_MNT/testdir/extent_file3': Input/output error
+Attribute "attr_name4" has a 1025 byte value for SCRATCH_MNT/testdir/extent_file3
+Attribute "attr_name2" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file3
+Attribute "attr_name3" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file3
+Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file3
+attr_name4: 9fd415c49d67afc4b78fad4055a3a376  -
+
+attr_set: Input/output error
+Could not set "attr_name2" for SCRATCH_MNT/testdir/extent_file4
+touch: cannot touch 'SCRATCH_MNT/testdir/extent_file4': Input/output error
+Attribute "attr_name2" has a 65536 byte value for SCRATCH_MNT/testdir/extent_file4
+Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file4
+attr_name2: 7f6fd1b6d872108bd44bd143cbcdfa19  -
+
+attr_remove: Input/output error
+Could not remove "attr_name2" for SCRATCH_MNT/testdir/extent_file4
+touch: cannot touch 'SCRATCH_MNT/testdir/extent_file4': Input/output error
+Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file4
+attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
+
+attr_set: Input/output error
+Could not set "attr_name2" for SCRATCH_MNT/testdir/remote_file1
+touch: cannot touch 'SCRATCH_MNT/testdir/remote_file1': Input/output error
+Attribute "attr_name2" has a 1025 byte value for SCRATCH_MNT/testdir/remote_file1
+Attribute "attr_name1" has a 65536 byte value for SCRATCH_MNT/testdir/remote_file1
+attr_name2: 9fd415c49d67afc4b78fad4055a3a376  -
+
+attr_remove: Input/output error
+Could not remove "attr_name2" for SCRATCH_MNT/testdir/remote_file1
+touch: cannot touch 'SCRATCH_MNT/testdir/remote_file1': Input/output error
+Attribute "attr_name1" has a 65536 byte value for SCRATCH_MNT/testdir/remote_file1
+attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
+
+attr_set: Input/output error
+Could not set "attr_name2" for SCRATCH_MNT/testdir/remote_file2
+touch: cannot touch 'SCRATCH_MNT/testdir/remote_file2': Input/output error
+Attribute "attr_name2" has a 65536 byte value for SCRATCH_MNT/testdir/remote_file2
+Attribute "attr_name1" has a 65536 byte value for SCRATCH_MNT/testdir/remote_file2
+attr_name2: 7f6fd1b6d872108bd44bd143cbcdfa19  -
+
+attr_remove: Input/output error
+Could not remove "attr_name2" for SCRATCH_MNT/testdir/remote_file2
+touch: cannot touch 'SCRATCH_MNT/testdir/remote_file2': Input/output error
+Attribute "attr_name1" has a 65536 byte value for SCRATCH_MNT/testdir/remote_file2
+attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
+
+attr_set: Input/output error
+Could not set "attr_name2" for SCRATCH_MNT/testdir/sf_file
+touch: cannot touch 'SCRATCH_MNT/testdir/sf_file': Input/output error
+Attribute "attr_name1" has a 64 byte value for SCRATCH_MNT/testdir/sf_file
+Attribute "attr_name2" has a 17 byte value for SCRATCH_MNT/testdir/sf_file
+attr_name2: 9a6eb1bc9da3c66a9b495dfe2fe8a756  -
+
+attr_set: Input/output error
+Could not set "attr_name2" for SCRATCH_MNT/testdir/leaf_file
+touch: cannot touch 'SCRATCH_MNT/testdir/leaf_file': Input/output error
+Attribute "attr_name2" has a 257 byte value for SCRATCH_MNT/testdir/leaf_file
+Attribute "attr_name3" has a 1024 byte value for SCRATCH_MNT/testdir/leaf_file
+Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/leaf_file
+attr_name2: f4ea5799d72a0a9bf2d56a685c9cba7a  -
+
+attr_set: Input/output error
+Could not set "attr_name2" for SCRATCH_MNT/testdir/node_file
+touch: cannot touch 'SCRATCH_MNT/testdir/node_file': Input/output error
+Attribute "attr_name2" has a 257 byte value for SCRATCH_MNT/testdir/node_file
+Attribute "attr_name1" has a 65536 byte value for SCRATCH_MNT/testdir/node_file
+attr_name2: f4ea5799d72a0a9bf2d56a685c9cba7a  -
+
+*** done
diff --git a/tests/xfs/081 b/tests/xfs/081
new file mode 100755 (executable)
index 0000000..3af7377
--- /dev/null
@@ -0,0 +1,80 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2022 Red Hat, Inc.  All Rights Reserved.
+#
+# FS QA Test No. 081
+#
+# This's a regression test for:
+#   a1de97fe296c ("xfs: Fix the free logic of state in xfs_attr_node_hasname")
+#
+# After we corrupted an attr leaf block (under node block), getxattr might hit
+# EFSCORRUPTED in xfs_attr_node_get when it does xfs_attr_node_hasname. A bug
+# cause xfs_attr_node_get won't do xfs_buf_trans release job, then a subsequent
+# removexattr will hang.
+#
+. ./common/preamble
+_begin_fstest auto quick attr
+
+# Import common functions.
+. ./common/filter
+. ./common/attr
+. ./common/populate
+
+# real QA test starts here
+_supported_fs xfs
+_fixed_by_kernel_commit a1de97fe296c \
+       "xfs: Fix the free logic of state in xfs_attr_node_hasname"
+
+_require_scratch_nocheck
+# Only test with v5 xfs on-disk format
+_require_scratch_xfs_crc
+_require_attrs
+_require_populate_commands
+_require_xfs_db_blocktrash_z_command
+
+_scratch_mkfs_xfs | _filter_mkfs >$seqres.full 2>$tmp.mkfs
+source $tmp.mkfs
+_scratch_mount
+
+# Create more than $((dbsize / 32)) xattr entries to force the creation of a
+# node block and two (or more) leaf blocks, which we need for this test.
+nr_xattr="$((dbsize / 32))"
+localfile="${SCRATCH_MNT}/attrfile"
+touch $localfile
+for ((i=0; i<nr_xattr; i++));do
+       $SETFATTR_PROG -n user.x$(printf "%.09d" "$i") -v "aaaaaaaaaaaaaaaa" $localfile
+done
+inumber="$(stat -c '%i' $localfile)"
+_scratch_unmount
+
+# Expect the ablock 0 is a node block, later ablocks(>=1) are leaf blocks, then corrupt
+# the last leaf block. (Don't corrupt node block, or can't reproduce the bug)
+magic=$(_scratch_xfs_get_metadata_field "hdr.info.hdr.magic" "inode $inumber" "ablock 0")
+level=$(_scratch_xfs_get_metadata_field "hdr.level" "inode $inumber" "ablock 0")
+count=$(_scratch_xfs_get_metadata_field "hdr.count" "inode $inumber" "ablock 0")
+if [ "$magic" = "0x3ebe" -a "$level" = "1" ];then
+       # Corrupt the last leaf block
+       _scratch_xfs_db -x -c "inode ${inumber}" -c "ablock $count" -c "stack" \
+               -c "blocktrash -x 32 -y $((dbsize*8)) -3 -z" >> $seqres.full
+else
+       _fail "The ablock 0 (magic=$magic, level=$level) isn't a root node block, maybe case issue"
+fi
+
+# This's the real testing, expect removexattr won't hang or panic.
+if _try_scratch_mount >> $seqres.full 2>&1; then
+       for ((i=0; i<nr_xattr; i++));do
+               $GETFATTR_PROG -n user.x$(printf "%.09d" "$i") $localfile >/dev/null 2>&1
+               $SETFATTR_PROG -x user.x$(printf "%.09d" "$i") $localfile 2>/dev/null
+       done
+else
+       # Due to we corrupt the xfs manually, so can't be sure if xfs can
+       # detect this corruption and refuse the mount directly in one day.
+       # If so, it's not a testing fail, so "notrun" directly to mark this
+       # test isn't really done
+       _notrun "XFS refused to mount with this xattr corruption, test skipped"
+fi
+
+echo "Silence is golden"
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/081.out b/tests/xfs/081.out
new file mode 100644 (file)
index 0000000..663a886
--- /dev/null
@@ -0,0 +1,2 @@
+QA output created by 081
+Silence is golden
index a118037115c4b2e2c85b9a0539483c05a80927bc..5ffbce25c6a5f7ffbde4ccec39289de44d246051 100755 (executable)
 . ./common/preamble
 _begin_fstest log v2log auto freeze
 
+# Override the default cleanup function.
+_cleanup()
+{
+       # Make sure $SCRATCH_MNT is unfreezed
+       xfs_freeze -u $SCRATCH_MNT 2>/dev/null
+       cd /
+       rm -f $tmp.*
+}
+
 # Import common functions.
 . ./common/filter
 
@@ -20,6 +29,7 @@ _begin_fstest log v2log auto freeze
 _supported_fs xfs
 
 _require_scratch
+_require_freeze
 
 # this may hang
 sync
index 520061508803eb76fb2e572d5b3f57ffe0cd8be3..18748e67f413631933390ae2ce840b7c5c2cedc9 100755 (executable)
@@ -186,7 +186,7 @@ egrep '(} *xfs_.*_t|^struct xfs_[a-z0-9_]*$)' |\
 egrep -v -f $tmp.ignore |\
 sed -e 's/^.*}[[:space:]]*//g' -e 's/;.*$//g' -e 's/_t, /_t\n/g' |\
 sort | uniq |\
-awk '{printf("printf(\"sizeof(%s) = \\%zu\\n\", sizeof(%s));\n", $0, $0);}' |\
+awk '{printf("printf(\"sizeof(%s) = %%zu\\n\", sizeof(%s));\n", $0, $0);}' |\
 cat >> $cprog
 
 #
@@ -199,7 +199,7 @@ awk '
    /typedef struct xfs_sb/ { structon = 1; next }
    structon && $2 ~ /^sb_/ { sub(/[;,]/,"",$2)
                              sub(/XFSLABEL_MAX/,"12",$2)
-                             printf("printf(\"offsetof(xfs_sb_t, %s) = \\%zu\\n\", offsetof(xfs_sb_t, %s));", $2, $2); next}
+                             printf("printf(\"offsetof(xfs_sb_t, %s) = %%zu\\n\", offsetof(xfs_sb_t, %s));", $2, $2); next}
    structon && /}/ { structon = 0; next}
 '>>$cprog
 
index d32e726e7e5582ff206d5efebff9486b14ae3a36..5fd8dcadfcb05ab95cf2d6b484cda7dcb6d63995 100755 (executable)
@@ -18,6 +18,9 @@ _begin_fstest auto quick quota
 
 # real QA test starts here
 _supported_fs xfs
+_fixed_by_kernel_commit 1aecf3734a95 \
+       "xfs: fix chown leaking delalloc quota blocks when fssetxattr fails"
+
 _require_command "$FILEFRAG_PROG" filefrag
 _require_test_program "chprojid_fail"
 _require_quota
index 3f90a397d843acc2635d56c7b7ffcb77fa241505..548c94905f5b03452ee7a10aece853181bf18101 100755 (executable)
@@ -48,7 +48,7 @@ test $? -eq 137 || echo "repair should have been killed??"
 _check_scratch_xfs_features NEEDSREPAIR
 _try_scratch_mount &> $tmp.mount
 res=$?
-_filter_scratch < $tmp.mount
+_filter_error_mount < $tmp.mount
 if [ $res -eq 0 ]; then
        echo "Should not be able to mount after needsrepair crash"
        _scratch_unmount
index 12f154abd07f2676a8dbae89562e48d1c093eb2c..1263f091ffa02e56303b028340c65f3986a26ec2 100644 (file)
@@ -1,4 +1,4 @@
 QA output created by 154
 FEATURES: NEEDSREPAIR:YES
-mount: SCRATCH_MNT: mount(2) system call failed: Structure needs cleaning.
+mount: Structure needs cleaning
 FEATURES: NEEDSREPAIR:NO
index 505a9c73286ca1d07be43b7e911cd7c1194d749d..4440adf6ee5723f727ddb5da766b8a933f1057b0 100755 (executable)
@@ -51,7 +51,7 @@ test $? -eq 137 || echo "repair should have been killed??"
 _check_scratch_xfs_features NEEDSREPAIR INOBTCNT
 _try_scratch_mount &> $tmp.mount
 res=$?
-_filter_scratch < $tmp.mount
+_filter_error_mount < $tmp.mount
 if [ $res -eq 0 ]; then
        echo "needsrepair should have prevented mount"
        _scratch_unmount
index 4f9dfd0882c8d24aa12354531f60b750597936ac..5461031a38d4e0f509f46c608c5a8294d7e9509c 100644 (file)
@@ -8,7 +8,7 @@ FEATURES: INOBTCNT:NO
 Fail partway through upgrading
 Adding inode btree counts to filesystem.
 FEATURES: NEEDSREPAIR:YES INOBTCNT:YES
-mount: SCRATCH_MNT: mount(2) system call failed: Structure needs cleaning.
+mount: Structure needs cleaning
 Re-run repair to finish upgrade
 FEATURES: NEEDSREPAIR:NO INOBTCNT:YES
 Filesystem should be usable again
index 5f9850102aa614518bb352d4958299899883972b..15bb1854db51087d68fd4ea35611816e82c5a6d3 100755 (executable)
@@ -47,13 +47,11 @@ _require_fs_space $SCRATCH_MNT 10485760
 
 TEST_FILE=$SCRATCH_MNT/test_file
 TEST_PROG=$here/src/unwritten_sync
-LOOPS=50
+LOOPS=$((5 * $TIME_FACTOR))
 
 echo "*** test unwritten extent conversion under heavy I/O"
-
-workout
-
 rm -f $TEST_FILE
+workout
 $TEST_PROG $LOOPS $TEST_FILE
 
 echo "     *** test done"
index 10891550853af7f42de8ff78d2ecfaffc158042b..1e59bd6c507e773ae856441093ccad755da3a000 100755 (executable)
@@ -39,6 +39,8 @@ _cleanup()
 
 # Modify as appropriate.
 _supported_fs xfs
+_fixed_by_kernel_commit f38a032b165d "xfs: fix I_DONTCACHE"
+
 _require_xfs_io_command "bulkstat"
 _require_scratch
 
index e601881a6fbacf1f832b721f17317aed3ce3f99d..bc7ccca565a7f7fd7fe76d505ce51eee7608cc16 100755 (executable)
 #
 # <---- Normal programming is resumed ---->
 #
+# <---- Bbbzzzzzzztttt ---->
+#
+# < systemd enters the chat >
+#
+# xfs/189 [not run] noattr2 mount option not supported on /dev/vdc
+# xfs/190 1s ... mount: (hint) your fstab has been modified, but systemd still uses
+#        the old version; use 'systemctl daemon-reload' to reload.
+#  1s
+#  xfs/192 3s ... mount: (hint) your fstab has been modified, but systemd still uses
+#        the old version; use 'systemctl daemon-reload' to reload.
+#
+# mount/systemd sees that /etc/fstab has changed (because mtime changed)
+# and so it whines that systemd needs updating on every mount from this point
+# onwards. Yes, that's totally obnoxious behaviour from mount/systemd but we
+# have to work around it.
+#
+# < systemd leaves the chat >
 #
 . ./common/preamble
 _begin_fstest mount auto quick
@@ -190,6 +207,10 @@ ENDL
 # Example fstab entry
 # /dev/sdb2            /mnt/scratch1        xfs       defaults 0 0
 #
+# Note that to avoid mnt/systemd whining about /etc/fstab being modified, we
+# need to ensure that it reloads it's state once we restore the fstab to
+# original.
+#
 _add_scratch_fstab()
 {
        # comment out any existing SCRATCH_DEV
@@ -201,7 +222,7 @@ _add_scratch_fstab()
 
 _modify_scratch_fstab()
 {
-       opts=$1
+       local opts=$1
 
        # modify our fstab entry that we added
        # modify opts by looking for last word which has non-space chars
@@ -215,6 +236,9 @@ _putback_scratch_fstab()
 
        # remove the one we added at the end
        $SED_PROG -i "/# $tag/d" /etc/fstab
+
+       # stop mount/systemd whining that /etcfstab was changed.
+       command -v systemctl > /dev/null 2>&1 && systemctl daemon-reload
 }
 
 # Import common functions.
index 0ab0c7d807ad3a2dd7edf9d8ed7475bbf65f6d7a..b740c37949919b8ebd503bb1b88eba230b3c5283 100755 (executable)
@@ -27,8 +27,30 @@ _scratch_mkfs_xfs >>$seqres.full 2>&1
 # set the highest bit of features_ro_compat, use it as an unknown
 # feature bit. If one day this bit become known feature, please
 # change this case.
-_scratch_xfs_set_metadata_field "features_ro_compat" "$((2**31))" "sb 0" | \
-       grep 'features_ro_compat'
+
+ro_compat=$(_scratch_xfs_get_metadata_field "features_ro_compat" "sb 0")
+echo $ro_compat | grep -q -E '^0x[[:xdigit:]]$'
+if [[ $? != 0  ]]; then
+       echo "features_ro_compat has an invalid value."
+fi
+
+ro_compat=$(echo $ro_compat | \
+                   awk '/^0x[[:xdigit:]]+/ {
+                               printf("0x%x\n", or(strtonum($1), 0x80000000))
+                       }')
+
+# write the new ro compat field to the superblock
+_scratch_xfs_set_metadata_field "features_ro_compat" "$ro_compat" "sb 0" \
+                               > $seqres.full 2>&1
+
+# read the newly set ro compat filed for verification
+new_ro_compat=$(_scratch_xfs_get_metadata_field "features_ro_compat" "sb 0" \
+                                               2>/dev/null)
+
+# verify the new ro_compat field is correct.
+if [ $new_ro_compat != $ro_compat ]; then
+       echo "Unable to set new features_ro_compat. Wanted $ro_compat, got $new_ro_compat"
+fi
 
 # rw mount with unknown ro-compat feature should fail
 echo "rw mount test"
index 0a8b385137f8c41daa651aa54e25d6345c111bd3..edf4c25489ff1493de9d4b16482a0bbe5c755917 100644 (file)
@@ -1,5 +1,4 @@
 QA output created by 270
-features_ro_compat = 0x80000000
 rw mount test
 ro mount test
 rw remount test
index ca482e064f388899ca25c3d6abb03e9fa7b7e92c..07f84c25e90887ca11cd7ca811a44e4dead8aeb3 100755 (executable)
 . ./common/preamble
 _begin_fstest auto freeze
 
+# Override the default cleanup function.
+_cleanup()
+{
+       # Make sure $SCRATCH_MNT is unfreezed
+       xfs_freeze -u $SCRATCH_MNT 2>/dev/null
+       $KILLALL_PROG -q -9 $FSSTRESS_PROG
+       wait
+       cd /
+       rm -f $tmp.*
+}
+
 # Import common functions.
 . ./common/filter
 
index 38c7aa6016b4cf79bac0a61db488427340bdd510..5798f9a38eac826dc0315cd1f9f788eaf8a216d0 100755 (executable)
@@ -7,13 +7,14 @@
 # Simulate free extent errors with a file write and a file remove.
 #
 . ./common/preamble
-_begin_fstest auto quick rw
+_begin_fstest auto quick rw freeze
 
 # Override the default cleanup function.
 _cleanup()
 {
+       # Make sure $SCRATCH_MNT is unfreezed
+       xfs_freeze -u $SCRATCH_MNT 2>/dev/null
        cd /
-       _scratch_unmount > /dev/null 2>&1
        rm -rf $tmp.*
 }
 
@@ -26,6 +27,7 @@ _supported_fs xfs
 _require_scratch
 _require_error_injection
 _require_xfs_io_error_injection "rmap_finish_one"
+_require_freeze
 
 blksz=65536
 blks=64
index 5b26b2b37f385f4ae7a8b65a78ba5b552785ad21..43fb09a6be4ed970f32e7d988de8cdc2c3874cb3 100755 (executable)
@@ -8,13 +8,14 @@
 # Inject an error during extent freeing to test log recovery.
 #
 . ./common/preamble
-_begin_fstest auto quick clone
+_begin_fstest auto quick clone freeze
 
 # Override the default cleanup function.
 _cleanup()
 {
+       # Make sure $SCRATCH_MNT is unfreezed
+       xfs_freeze -u $SCRATCH_MNT 2>/dev/null
        cd /
-       _scratch_unmount > /dev/null 2>&1
        rm -rf $tmp.*
 }
 
@@ -29,6 +30,7 @@ _require_cp_reflink
 _require_scratch_reflink
 _require_error_injection
 _require_xfs_io_error_injection "free_extent"
+_require_freeze
 
 blksz=65536
 blks=30
index 77db492e26601338a72c983024ff45ef20a08233..fdbb8bf14c899ffae4ec6e8a43a32a54d102510b 100755 (executable)
@@ -9,15 +9,40 @@
 # activity, so we can't have userspace wandering in and thawing it.
 #
 . ./common/preamble
-_begin_fstest dangerous_scrub dangerous_online_repair
+_begin_fstest dangerous_scrub dangerous_online_repair freeze
 
 _register_cleanup "_cleanup" BUS
 
+# First kill and wait the freeze loop so it won't try to freeze fs again
+# Then make sure fs is not frozen
+# Then kill and wait for the rest of the workers
+# Because if fs is frozen a killed writer will never exit
+kill_loops() {
+       local sig=$1
+
+       [ -n "$freeze_pid" ] && kill $sig $freeze_pid
+       wait $freeze_pid
+       unset freeze_pid
+       $XFS_IO_PROG -x -c 'thaw' $SCRATCH_MNT
+       [ -n "$stress_pid" ] && kill $sig $stress_pid
+       [ -n "$repair_pid" ] && kill $sig $repair_pid
+       wait
+       unset stress_pid
+       unset repair_pid
+}
+
+# Override the default cleanup function.
+_cleanup()
+{
+       kill_loops -9 > /dev/null 2>&1
+       cd /
+       rm -rf $tmp.*
+}
+
 # Import common functions.
 . ./common/filter
 . ./common/fuzzy
 . ./common/inject
-. ./common/xfs
 
 # real QA test starts here
 _supported_fs xfs
@@ -25,6 +50,7 @@ _require_xfs_scratch_rmapbt
 _require_xfs_io_command "scrub"
 _require_xfs_io_error_injection "force_repair"
 _require_command "$KILLALL_PROG" killall
+_require_freeze
 
 echo "Format and populate"
 _scratch_mkfs > "$seqres.full" 2>&1
@@ -78,8 +104,11 @@ end=$((start + (30 * TIME_FACTOR) ))
 
 echo "Loop started at $(date --date="@${start}"), ending at $(date --date="@${end}")" >> $seqres.full
 stress_loop $end &
+stress_pid=$!
 freeze_loop $end &
+freeze_pid=$!
 repair_loop $end &
+repair_pid=$!
 
 # Wait until 2 seconds after the loops should have finished...
 while [ "$(date +%s)" -lt $((end + 2)) ]; do
@@ -87,8 +116,7 @@ while [ "$(date +%s)" -lt $((end + 2)) ]; do
 done
 
 # ...and clean up after the loops in case they didn't do it themselves.
-$KILLALL_PROG -TERM xfs_io fsstress >> $seqres.full 2>&1
-$XFS_IO_PROG -x -c 'thaw' $SCRATCH_MNT >> $seqres.full 2>&1
+kill_loops >> $seqres.full 2>&1
 
 echo "Loop finished at $(date)" >> $seqres.full
 echo "Test done"
index be56f311d106887e686111ad3b3b5c4d0e8bf60b..c9dfaece421a9b38c23caac4a4e9796ce6316465 100755 (executable)
@@ -18,7 +18,6 @@ _register_cleanup "_cleanup" BUS
 . ./common/filter
 . ./common/fuzzy
 . ./common/inject
-. ./common/xfs
 
 # real QA test starts here
 _supported_fs xfs
index c3008b1c9923e708ceba16791afe4ef5b8291a97..0425c5b1f640e72cd690bd737300636b4492dc91 100755 (executable)
 # Fixed by upstream commit 373b058 ("xfs: Properly retry failed dquot
 # items in case of error during buffer writeback")
 . ./common/preamble
-_begin_fstest auto quick quota
+_begin_fstest auto quick quota freeze
 
 # Override the default cleanup function.
 _cleanup()
 {
+       # Make sure $SCRATCH_MNT is unfreezed
+       xfs_freeze -u $SCRATCH_MNT 2>/dev/null
        [ -z "${interval}" ] || \
                sysctl -w fs.xfs.xfssyncd_centisecs=${interval} >/dev/null 2>&1
        cd /
index bfdfd4f612991573e5851ead82fce7643dbe7242..85500af0ebe2744f138900b3a25cf7b95730f96b 100755 (executable)
@@ -31,6 +31,9 @@ _cleanup()
 
 # real QA test starts here
 _supported_fs xfs
+_fixed_by_kernel_commit 237d7887ae72 \
+       "xfs: show the proper user quota options"
+
 _require_test
 _require_loop
 _require_xfs_io_command "falloc"
index 512f795f525c194f1b5055f6315621d6c7f8a7dd..6877af13bb4e238840e7ee4f6a99b27d74545c35 100755 (executable)
@@ -11,11 +11,29 @@ _begin_fstest auto quick fsmap freeze
 
 _register_cleanup "_cleanup" BUS
 
+# First kill and wait the freeze loop so it won't try to freeze fs again
+# Then make sure fs is not frozen
+# Then kill and wait for the rest of the workers
+# Because if fs is frozen a killed writer will never exit
+kill_loops() {
+       local sig=$1
+
+       [ -n "$freeze_pid" ] && kill $sig $freeze_pid
+       wait $freeze_pid
+       unset freeze_pid
+       $XFS_IO_PROG -x -c 'thaw' $SCRATCH_MNT
+       [ -n "$stress_pid" ] && kill $sig $stress_pid
+       [ -n "$fsmap_pid" ] && kill $sig $fsmap_pid
+       wait
+       unset stress_pid
+       unset fsmap_pid
+}
+
 # Override the default cleanup function.
 _cleanup()
 {
+       kill_loops -9 > /dev/null 2>&1
        cd /
-       $XFS_IO_PROG -x -c 'thaw' $SCRATCH_MNT > /dev/null 2>&1
        rm -rf $tmp.*
 }
 
@@ -23,13 +41,13 @@ _cleanup()
 . ./common/filter
 . ./common/fuzzy
 . ./common/inject
-. ./common/xfs
 
 # real QA test starts here
 _supported_fs xfs
 _require_xfs_scratch_rmapbt
 _require_xfs_io_command "fsmap"
 _require_command "$KILLALL_PROG" killall
+_require_freeze
 
 echo "Format and populate"
 _scratch_mkfs > "$seqres.full" 2>&1
@@ -83,8 +101,11 @@ end=$((start + (30 * TIME_FACTOR) ))
 
 echo "Loop started at $(date --date="@${start}"), ending at $(date --date="@${end}")" >> $seqres.full
 stress_loop $end &
+stress_pid=$!
 freeze_loop $end &
+freeze_pid=$!
 fsmap_loop $end &
+fsmap_pid=$!
 
 # Wait until 2 seconds after the loops should have finished...
 while [ "$(date +%s)" -lt $((end + 2)) ]; do
@@ -92,8 +113,7 @@ while [ "$(date +%s)" -lt $((end + 2)) ]; do
 done
 
 # ...and clean up after the loops in case they didn't do it themselves.
-$KILLALL_PROG -TERM xfs_io fsstress >> $seqres.full 2>&1
-$XFS_IO_PROG -x -c 'thaw' $SCRATCH_MNT >> $seqres.full 2>&1
+kill_loops >> $seqres.full 2>&1
 
 echo "Loop finished at $(date)" >> $seqres.full
 echo "Test done"
index e0102f48528d4795abdcda7ed9456499c54c587d..2b5e97e581d2244c258723310d4a0a5925746036 100755 (executable)
@@ -47,25 +47,23 @@ done
 echo "Inject bmap_alloc_minlen_extent error tag"
 _scratch_inject_error bmap_alloc_minlen_extent 1
 
-echo "Scale fsstress args"
-args=$(_scale_fsstress_args -p $((LOAD_FACTOR * 75)) -n $((TIME_FACTOR * 1000)))
-
-echo "Execute fsstress in background"
-$FSSTRESS_PROG -d $SCRATCH_MNT $args \
-                -f bulkstat=0 \
-                -f bulkstat1=0 \
-                -f fiemap=0 \
-                -f getattr=0 \
-                -f getdents=0 \
-                -f getfattr=0 \
-                -f listfattr=0 \
-                -f mread=0 \
-                -f read=0 \
-                -f readlink=0 \
-                -f readv=0 \
-                -f stat=0 \
-                -f aread=0 \
-                -f dread=0 > /dev/null 2>&1
+echo "Execute fsstress"
+$FSSTRESS_PROG -d $SCRATCH_MNT \
+               $(_scale_fsstress_args -p 75 -n 1000) \
+               -f bulkstat=0 \
+               -f bulkstat1=0 \
+               -f fiemap=0 \
+               -f getattr=0 \
+               -f getdents=0 \
+               -f getfattr=0 \
+               -f listfattr=0 \
+               -f mread=0 \
+               -f read=0 \
+               -f readlink=0 \
+               -f readv=0 \
+               -f stat=0 \
+               -f aread=0 \
+               -f dread=0 > /dev/null 2>&1
 
 # success, all done
 status=0
index 85932c82634a00839e234991e41d9eabdb27c3fc..97ebc314e2e4d64150ad4f627b7f0e1f88e93686 100644 (file)
@@ -3,5 +3,4 @@ Format and mount fs
 Consume free space
 Create fragmented filesystem
 Inject bmap_alloc_minlen_extent error tag
-Scale fsstress args
-Execute fsstress in background
+Execute fsstress
index 4bc52c1ae8671635ec7ba87abd5bb642869dd106..77b44c89244318e01585f1540b6ed4e39cd57a3f 100755 (executable)
@@ -9,15 +9,18 @@
 # the same value as during the mount
 #
 # Regression test for commit:
-# xfs: Skip repetitive warnings about mount options
+# 92cf7d36384b xfs: Skip repetitive warnings about mount options
 
 . ./common/preamble
 _begin_fstest auto quick mount
 
 # Import common functions.
 
-_require_check_dmesg
 _supported_fs xfs
+_fixed_by_kernel_commit 92cf7d36384b \
+       "xfs: Skip repetitive warnings about mount options"
+
+_require_check_dmesg
 _require_scratch
 
 log_tag()
index 5c45eed7cdabfcb42ce1e797ac47f5f0cee55146..1540541ec4c942431ebb9f6dde73c493406ea5ef 100755 (executable)
@@ -26,6 +26,9 @@ _cleanup()
 
 # real QA test starts here
 _supported_fs xfs
+_fixed_by_kernel_commit 5ca5916b6bc9 \
+       "xfs: punch out data fork delalloc blocks on COW writeback failure"
+
 _require_scratch_reflink
 _require_cp_reflink
 _require_xfs_io_command "cowextsize"
index e3dd300ac0d8dbb0e35486c7d84aa1aa3ef674ea..dfe2f2dc70cb5ca302fe4a8dbd20cb4df194bbca 100755 (executable)
@@ -14,6 +14,7 @@ _begin_fstest auto quick dump
 . ./common/dump
 
 _supported_fs xfs
+_require_xfs_io_command "falloc"
 _require_scratch
 
 # A large stripe unit will put the root inode out quite far
diff --git a/tests/xfs/547 b/tests/xfs/547
new file mode 100755 (executable)
index 0000000..9d4216c
--- /dev/null
@@ -0,0 +1,92 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2022 Oracle.  All Rights Reserved.
+#
+# FS QA Test 547
+#
+# Verify that correct inode extent count fields are populated with and without
+# nrext64 feature.
+#
+. ./common/preamble
+_begin_fstest auto quick metadata
+
+# Import common functions.
+. ./common/filter
+. ./common/attr
+. ./common/inject
+. ./common/populate
+
+# real QA test starts here
+_supported_fs xfs
+_require_scratch
+_require_xfs_nrext64
+_require_attrs
+_require_xfs_debug
+_require_xfs_db_command path
+_require_test_program "punch-alternating"
+_require_xfs_io_error_injection "bmap_alloc_minlen_extent"
+
+for nrext64 in 0 1; do
+       echo "* Verify extent counter fields with nrext64=${nrext64} option"
+
+       _scratch_mkfs -i nrext64=${nrext64} -d size=$((512 * 1024 * 1024)) \
+                     >> $seqres.full
+       _scratch_mount >> $seqres.full
+
+       bsize=$(_get_file_block_size $SCRATCH_MNT)
+
+       testfile=$SCRATCH_MNT/testfile
+
+       nr_blks=20
+
+       echo "Add blocks to test file's data fork"
+       $XFS_IO_PROG -f -c "pwrite 0 $((nr_blks * bsize))" $testfile \
+                    >> $seqres.full
+       $here/src/punch-alternating $testfile
+
+       echo "Consume free space"
+       fillerdir=$SCRATCH_MNT/fillerdir
+       nr_free_blks=$(stat -f -c '%f' $SCRATCH_MNT)
+       nr_free_blks=$((nr_free_blks * 90 / 100))
+
+       _fill_fs $((bsize * nr_free_blks)) $fillerdir $bsize 0 \
+                >> $seqres.full 2>&1
+
+       echo "Create fragmented filesystem"
+       for dentry in $(ls -1 $fillerdir/); do
+               $here/src/punch-alternating $fillerdir/$dentry >> $seqres.full
+       done
+
+       echo "Inject bmap_alloc_minlen_extent error tag"
+       _scratch_inject_error bmap_alloc_minlen_extent 1
+
+       echo "Add blocks to test file's attr fork"
+       attr_len=255
+       nr_attrs=$((nr_blks * bsize / attr_len))
+       for i in $(seq 1 $nr_attrs); do
+               attr="$(printf "trusted.%0247d" $i)"
+               $SETFATTR_PROG -n "$attr" $testfile >> $seqres.full 2>&1
+               [[ $? != 0 ]] && break
+       done
+
+       _scratch_unmount >> $seqres.full
+
+       dcnt=$(_scratch_xfs_get_metadata_field core.nextents \
+                                              "path /$(basename $testfile)")
+       acnt=$(_scratch_xfs_get_metadata_field core.naextents \
+                                              "path /$(basename $testfile)")
+
+       if (( $dcnt != 10 )); then
+               echo "Invalid data fork extent count: $dextcnt"
+               exit 1
+       fi
+
+       if (( $acnt < 10 )); then
+               echo "Invalid attr fork extent count: $aextcnt"
+               exit 1
+       fi
+done
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/547.out b/tests/xfs/547.out
new file mode 100644 (file)
index 0000000..49fcc3c
--- /dev/null
@@ -0,0 +1,13 @@
+QA output created by 547
+* Verify extent counter fields with nrext64=0 option
+Add blocks to test file's data fork
+Consume free space
+Create fragmented filesystem
+Inject bmap_alloc_minlen_extent error tag
+Add blocks to test file's attr fork
+* Verify extent counter fields with nrext64=1 option
+Add blocks to test file's data fork
+Consume free space
+Create fragmented filesystem
+Inject bmap_alloc_minlen_extent error tag
+Add blocks to test file's attr fork
diff --git a/tests/xfs/548 b/tests/xfs/548
new file mode 100755 (executable)
index 0000000..560c90f
--- /dev/null
@@ -0,0 +1,112 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2022 Oracle.  All Rights Reserved.
+#
+# FS QA Test 548
+#
+# Test to verify upgrade of an existing V5 filesystem to support large extent
+# counters.
+#
+. ./common/preamble
+_begin_fstest auto quick metadata
+
+# Import common functions.
+. ./common/filter
+. ./common/attr
+. ./common/inject
+. ./common/populate
+
+# real QA test starts here
+_supported_fs xfs
+_require_scratch
+_require_xfs_nrext64
+_require_attrs
+_require_xfs_debug
+_require_xfs_db_command path
+_require_test_program "punch-alternating"
+_require_xfs_io_error_injection "bmap_alloc_minlen_extent"
+
+_scratch_mkfs -d size=$((512 * 1024 * 1024)) >> $seqres.full
+_scratch_mount >> $seqres.full
+
+bsize=$(_get_file_block_size $SCRATCH_MNT)
+
+testfile=$SCRATCH_MNT/testfile
+
+nr_blks=20
+
+echo "Add blocks to file's data fork"
+$XFS_IO_PROG -f -c "pwrite 0 $((nr_blks * bsize))" $testfile \
+            >> $seqres.full
+$here/src/punch-alternating $testfile
+
+echo "Consume free space"
+fillerdir=$SCRATCH_MNT/fillerdir
+nr_free_blks=$(stat -f -c '%f' $SCRATCH_MNT)
+nr_free_blks=$((nr_free_blks * 90 / 100))
+
+_fill_fs $((bsize * nr_free_blks)) $fillerdir $bsize 0 \
+        >> $seqres.full 2>&1
+
+echo "Create fragmented filesystem"
+for dentry in $(ls -1 $fillerdir/); do
+       $here/src/punch-alternating $fillerdir/$dentry >> $seqres.full
+done
+
+echo "Inject bmap_alloc_minlen_extent error tag"
+_scratch_inject_error bmap_alloc_minlen_extent 1
+
+echo "Add blocks to file's attr fork"
+nr_blks=10
+attr_len=255
+nr_attrs=$((nr_blks * bsize / attr_len))
+for i in $(seq 1 $nr_attrs); do
+       attr="$(printf "trusted.%0247d" $i)"
+       $SETFATTR_PROG -n "$attr" $testfile >> $seqres.full 2>&1
+       [[ $? != 0 ]] && break
+done
+
+echo "Unmount filesystem"
+_scratch_unmount >> $seqres.full
+
+orig_dcnt=$(_scratch_xfs_get_metadata_field core.nextents \
+                                           "path /$(basename $testfile)")
+orig_acnt=$(_scratch_xfs_get_metadata_field core.naextents \
+                                           "path /$(basename $testfile)")
+
+echo "Upgrade filesystem to support large extent counters"
+_scratch_xfs_admin -O nrext64=1 >> $seqres.full 2>&1
+if [[ $? != 0 ]]; then
+       _notrun "Filesystem geometry is not suitable for upgrading"
+fi
+
+
+echo "Mount filesystem"
+_scratch_mount >> $seqres.full
+
+echo "Modify inode core"
+touch $testfile
+
+echo "Unmount filesystem"
+_scratch_unmount >> $seqres.full
+
+dcnt=$(_scratch_xfs_get_metadata_field core.nextents \
+                                      "path /$(basename $testfile)")
+acnt=$(_scratch_xfs_get_metadata_field core.naextents \
+                                      "path /$(basename $testfile)")
+
+echo "Verify inode extent counter values after fs upgrade"
+
+if [[ $orig_dcnt != $dcnt ]]; then
+       echo "Corrupt data extent counter"
+       exit 1
+fi
+
+if [[ $orig_acnt != $acnt ]]; then
+       echo "Corrupt attr extent counter"
+       exit 1
+fi
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/548.out b/tests/xfs/548.out
new file mode 100644 (file)
index 0000000..19a7f90
--- /dev/null
@@ -0,0 +1,12 @@
+QA output created by 548
+Add blocks to file's data fork
+Consume free space
+Create fragmented filesystem
+Inject bmap_alloc_minlen_extent error tag
+Add blocks to file's attr fork
+Unmount filesystem
+Upgrade filesystem to support large extent counters
+Mount filesystem
+Modify inode core
+Unmount filesystem
+Verify inode extent counter values after fs upgrade
index 414cb538c21a9ec91989b7a40371a3ff1a2ff669..dcf896e0a2216810787f328f4eb8eab9cee2e981 100755 (executable)
@@ -62,8 +62,8 @@ ENDL
 
        # Aggregate the groups each test belongs to for the group file
        grep -I -R "^_begin_fstest" $test_dir/ | \
-               sed -e "s/^.*\/\($VALID_TEST_NAME\):_begin_fstest/\1/" \
-               >> $new_groups
+               sed -e "s/^.*\/\($VALID_TEST_NAME\):_begin_fstest/\1/" \
+               sort -ug >> $new_groups
 
        # Create the list of unique groups for existence checking
        grep -I -R "^_begin_fstest" $test_dir/ | \