#! /bin/bash # SPDX-License-Identifier: GPL-2.0 # Copyright (c) 2017 Red Hat, Inc. All Rights Reserved. # # FS QA Test No. 057 # # Attempt to reproduce log recovery failure by writing corrupt log records over # the last good tail in the log. The tail is force pinned while a workload runs # the head as close as possible behind the tail. Once the head is pinned, # corrupted log records are written to the log and the filesystem shuts down. # # While log recovery should handle the corrupted log records, it has historical # problems dealing with the situation where the corrupted log records may have # overwritten the tail of the previous good record in the log. If this occurs, # log recovery may fail. # # This can be reproduced more reliably under non-default conditions such as with # the smallest supported FSB sizes and/or largest supported log buffer sizes and # counts (logbufs and logbsize mount options). # # Note that this test requires a DEBUG mode kernel. # 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.* $KILLALL_PROG -9 fsstress > /dev/null 2>&1 [ -e /sys/fs/xfs/$sdev/errortag/log_item_pin ] && echo 0 > /sys/fs/xfs/$sdev/errortag/log_item_pin wait > /dev/null 2>&1 } rm -f $seqres.full # get standard environment, filters and checks . ./common/rc . ./common/inject # real QA test starts here # Modify as appropriate. _supported_fs xfs _supported_os Linux _require_xfs_io_error_injection log_item_pin _require_xfs_io_error_injection log_bad_crc _require_scratch _require_command "$KILLALL_PROG" killall echo "Silence is golden." sdev=$(_short_dev $SCRATCH_DEV) # use a small log fs _scratch_mkfs_sized $((1024 * 1024 * 500)) >> $seqres.full 2>&1 || _fail "mkfs failed" _scratch_mount # populate the fs with some data and cycle the mount to reset the log head/tail $FSSTRESS_PROG -d $SCRATCH_MNT -z -fcreat=1 -p 4 -n 100000 > /dev/null 2>&1 _scratch_cycle_mount || _fail "cycle mount failed" # Pin the tail and start a file removal workload. File removal tends to # reproduce the corruption more reliably. _scratch_inject_error log_item_pin 1 rm -rf $SCRATCH_MNT/* > /dev/null 2>&1 & workpid=$! # wait for the head to stop pushing forward prevhead=-1 head=`cat /sys/fs/xfs/$sdev/log/log_head_lsn` while [ "$head" != "$prevhead" ]; do sleep 5 prevhead=$head head=`cat /sys/fs/xfs/$sdev/log/log_head_lsn` done # Once the head is pinned behind the tail, enable log record corruption and # unpin the tail. All subsequent log buffer writes end up corrupted on-disk and # result in log I/O errors. _scratch_inject_error log_bad_crc 1 _scratch_inject_error log_item_pin 0 # wait for fs shutdown to kill the workload wait $workpid # cycle mount to test log recovery _scratch_cycle_mount # success, all done status=0 exit