#! /bin/bash # SPDX-License-Identifier: GPL-2.0+ # Copyright (c) 2020, Jeff Layton. All rights reserved. # FS QA Test No. 484 # # Open a file and write to it and fsync. Then, flip the data device to throw # errors, write to it again and do an fdatasync. Then open an O_RDONLY fd on # the same file and call syncfs against it and ensure that an error is reported. # Then call syncfs again and ensure that no error is reported. Finally, repeat # the open and syncfs and ensure that there is no error reported. # # Kernel with the following patches should pass the test: # # vfs: track per-sb writeback errors and report them to syncfs # buffer: record blockdev write errors in super_block that it backs seq=`basename $0` seqres=$RESULT_DIR/$seq echo "QA output created by $seq" here=`pwd` tmp=/tmp/$$ status=1 # failure is the default! trap "_cleanup; exit \$status" 0 1 2 3 15 _cleanup() { cd / rm -f $tmp.* _dmerror_cleanup } # get standard environment, filters and checks . ./common/rc . ./common/filter . ./common/dmerror # real QA test starts here _require_scratch_nocheck # This test uses "dm" without taking into account the data could be on # realtime subvolume, thus the test will fail with rtinherit=1 _require_no_rtinherit _require_dm_target error _require_xfs_io_command "syncfs" rm -f $seqres.full echo "Format and mount" _scratch_mkfs > $seqres.full 2>&1 _dmerror_init _dmerror_mount # create file testfile=$SCRATCH_MNT/syncfs-reports-errors touch $testfile # write a page of data to file, and call fsync datalen=$(getconf PAGE_SIZE) $XFS_IO_PROG -c "pwrite -W -q 0 $datalen" $testfile # flip device to non-working mode _dmerror_load_error_table # rewrite the data and call fdatasync $XFS_IO_PROG -c "pwrite -w -q 0 $datalen" $testfile # heal the device error _dmerror_load_working_table # open again and call syncfs twice echo "One of the following syncfs calls should fail with EIO:" $XFS_IO_PROG -r -c syncfs -c syncfs $testfile echo "done" echo "This syncfs call should succeed:" $XFS_IO_PROG -r -c syncfs $testfile echo "done" # success, all done _dmerror_cleanup status=0 exit