mirror of
https://github.com/linux-apfs/apfstests.git
synced 2026-05-01 15:01:44 -07:00
8039c7cd3c
On a 64k blocksized filesystem, when the test CoWs the file2's offset range [10 * 64k, 19 * 64k], the call to xfs_bmapi_reserve_delalloc() allocates 32 64k blocks. This is because XFS_DEFAULT_COWEXTSZ_HINT has the value of 32 and xfs_get_cowextsz_hint() uses this to compute the extent alignment. This leads to xfs_bmapi_reserve_delalloc() to reserve space corresponding to the file range [0, 32 * 64k] in the inode's cow fork area. On completion of write I/O corresponding to file2's range [10 * 64k, 19 * 64k], xfs_end_io() moves 10 out of the originally allocated 32 64k blocks to the data fork area. The remaining 22 64k blocks linger on in cow fork area of the inode. Later, when servicing the exit() syscall for the xfs_io process, xfs_free_eofblocks() ends up invoking xfs_reflink_cancel_cow_blocks() since i_delayed_blks has the value 22. xfs_reflink_cancel_cow_blocks() indirectly invokes __xfs_free_extent() which returns EIO since XFS_ERRTAG_FREE_EXTENT has been set. This leads to the filesystem to be shutdown. The "rm" command invoked later ends up returning an error and hence the test fails. The test actually requires that the filesystem gets shutdown when executing the "rm" command. To fix the problem, this commit injects the free_extent error after we CoW file2's [10 * 64k, 19 * 64k] range. Signed-off-by: Chandan Rajendra <chandan@linux.vnet.ibm.com> Tested-by: Zorro Lang <zlang@redhat.com> Signed-off-by: Eryu Guan <guaneryu@gmail.com>
83 lines
1.7 KiB
Bash
Executable File
83 lines
1.7 KiB
Bash
Executable File
#! /bin/bash
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
# Copyright (c) 2016, Oracle and/or its affiliates. All Rights Reserved.
|
|
#
|
|
# FS QA Test No. 325
|
|
#
|
|
# Reflink a file with a few dozen extents, CoW a few blocks, and rm.
|
|
# Inject an error during extent freeing to test log recovery.
|
|
#
|
|
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 /
|
|
_scratch_unmount > /dev/null 2>&1
|
|
rm -rf $tmp.*
|
|
}
|
|
|
|
# get standard environment, filters and checks
|
|
. ./common/rc
|
|
. ./common/filter
|
|
. ./common/reflink
|
|
. ./common/inject
|
|
|
|
# real QA test starts here
|
|
_supported_os Linux
|
|
_supported_fs xfs
|
|
_require_cp_reflink
|
|
_require_scratch_reflink
|
|
_require_error_injection
|
|
_require_xfs_io_error_injection "free_extent"
|
|
|
|
rm -f $seqres.full
|
|
|
|
blksz=65536
|
|
blks=30
|
|
echo "Format filesystem"
|
|
_scratch_mkfs >/dev/null 2>&1
|
|
_scratch_mount >> $seqres.full
|
|
|
|
echo "Create files"
|
|
_pwrite_byte 0x66 0 $((blksz * blks)) $SCRATCH_MNT/file1 >> $seqres.full
|
|
_cp_reflink $SCRATCH_MNT/file1 $SCRATCH_MNT/file2
|
|
sync
|
|
|
|
echo "Check files"
|
|
md5sum $SCRATCH_MNT/file1 | _filter_scratch
|
|
md5sum $SCRATCH_MNT/file2 | _filter_scratch
|
|
|
|
echo "CoW a few blocks"
|
|
$XFS_IO_PROG -c "pwrite -W -S 0x67 $((10 * blksz)) $((10 * blksz))" $SCRATCH_MNT/file2 >> $seqres.full
|
|
|
|
echo "Inject error"
|
|
_scratch_inject_error "free_extent"
|
|
|
|
rm $SCRATCH_MNT/file1
|
|
sync
|
|
|
|
echo "FS should be shut down, touch will fail"
|
|
touch $SCRATCH_MNT/badfs 2>&1 | _filter_scratch
|
|
|
|
echo "Remount to replay log"
|
|
_scratch_inject_logprint >> $seqres.full
|
|
|
|
echo "FS should be online, touch should succeed"
|
|
touch $SCRATCH_MNT/goodfs
|
|
|
|
echo "Check files again"
|
|
md5sum $SCRATCH_MNT/file2 | _filter_scratch
|
|
|
|
echo "Done"
|
|
|
|
# success, all done
|
|
status=0
|
|
exit
|