2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (C) 2015 SUSE Linux Products GmbH. All Rights Reserved.
7 # Regression test for file read corruption when using compressed extents that
8 # are shared by multiple consecutive ranges of the same file.
11 seqres=$RESULT_DIR/$seq
12 echo "QA output created by $seq"
14 status=1 # failure is the default!
15 trap "_cleanup; exit \$status" 0 1 2 3 15
22 # get standard environment, filters and checks
26 # real QA test starts here
34 test_clone_and_read_compressed_extent()
38 _scratch_mkfs >>$seqres.full 2>&1
39 _scratch_mount $mount_opts
41 BLOCK_SIZE=$(_get_block_size $SCRATCH_MNT)
43 # Create a test file with a single extent that is compressed (the
44 # data we write into it is highly compressible no matter which
45 # compression algorithm is used, zlib or lzo).
46 $XFS_IO_PROG -f -c "pwrite -S 0xaa 0K $((1 * $BLOCK_SIZE))" \
47 -c "pwrite -S 0xbb $((1 * $BLOCK_SIZE)) $((2 * $BLOCK_SIZE))" \
48 -c "pwrite -S 0xcc $((3 * $BLOCK_SIZE)) $((1 * $BLOCK_SIZE))" \
49 $SCRATCH_MNT/foo | _filter_xfs_io_blocks_modified
52 # Now clone our extent into an adjacent offset.
53 $CLONER_PROG -s $((1 * $BLOCK_SIZE)) -d $((4 * $BLOCK_SIZE)) \
54 -l $((2 * $BLOCK_SIZE)) $SCRATCH_MNT/foo $SCRATCH_MNT/foo
56 # Same as before but for this file we clone the extent into a lower
59 -c "pwrite -S 0xaa $((2 * $BLOCK_SIZE)) $((1 * $BLOCK_SIZE))" \
60 -c "pwrite -S 0xbb $((3 * $BLOCK_SIZE)) $((2 * $BLOCK_SIZE))" \
61 -c "pwrite -S 0xcc $((5 * $BLOCK_SIZE)) $((1 * $BLOCK_SIZE))" \
62 $SCRATCH_MNT/bar | _filter_xfs_io_blocks_modified
64 $CLONER_PROG -s $((3 * $BLOCK_SIZE)) -d 0 -l $((2 * $BLOCK_SIZE)) \
65 $SCRATCH_MNT/bar $SCRATCH_MNT/bar
67 echo "File contents before unmounting filesystem:"
69 od -t x1 $SCRATCH_MNT/foo | _filter_od
71 od -t x1 $SCRATCH_MNT/bar | _filter_od
73 # Evicting the inode or clearing the page cache before reading again
74 # the file would also trigger the bug - reads were returning all bytes
75 # in the range corresponding to the second reference to the extent with
76 # a value of 0, but the correct data was persisted (it was a bug
77 # exclusively in the read path). The issue happened only if the same
78 # readpages() call targeted pages belonging to the first and second
79 # ranges that point to the same compressed extent.
82 echo "File contents after mounting filesystem again:"
83 # Must match the same contents we got before.
85 od -t x1 $SCRATCH_MNT/foo | _filter_od
87 od -t x1 $SCRATCH_MNT/bar | _filter_od
90 echo -e "\nTesting with zlib compression..."
91 test_clone_and_read_compressed_extent "-o compress=zlib"
95 echo -e "\nTesting with lzo compression..."
96 test_clone_and_read_compressed_extent "-o compress=lzo"