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
33 test_clone_and_read_compressed_extent()
37 _scratch_mkfs >>$seqres.full 2>&1
38 _scratch_mount $mount_opts
40 BLOCK_SIZE=$(_get_block_size $SCRATCH_MNT)
42 # Create a test file with a single extent that is compressed (the
43 # data we write into it is highly compressible no matter which
44 # compression algorithm is used, zlib or lzo).
45 $XFS_IO_PROG -f -c "pwrite -S 0xaa 0K $((1 * $BLOCK_SIZE))" \
46 -c "pwrite -S 0xbb $((1 * $BLOCK_SIZE)) $((2 * $BLOCK_SIZE))" \
47 -c "pwrite -S 0xcc $((3 * $BLOCK_SIZE)) $((1 * $BLOCK_SIZE))" \
48 $SCRATCH_MNT/foo | _filter_xfs_io_blocks_modified
51 # Now clone our extent into an adjacent offset.
52 $CLONER_PROG -s $((1 * $BLOCK_SIZE)) -d $((4 * $BLOCK_SIZE)) \
53 -l $((2 * $BLOCK_SIZE)) $SCRATCH_MNT/foo $SCRATCH_MNT/foo
55 # Same as before but for this file we clone the extent into a lower
58 -c "pwrite -S 0xaa $((2 * $BLOCK_SIZE)) $((1 * $BLOCK_SIZE))" \
59 -c "pwrite -S 0xbb $((3 * $BLOCK_SIZE)) $((2 * $BLOCK_SIZE))" \
60 -c "pwrite -S 0xcc $((5 * $BLOCK_SIZE)) $((1 * $BLOCK_SIZE))" \
61 $SCRATCH_MNT/bar | _filter_xfs_io_blocks_modified
63 $CLONER_PROG -s $((3 * $BLOCK_SIZE)) -d 0 -l $((2 * $BLOCK_SIZE)) \
64 $SCRATCH_MNT/bar $SCRATCH_MNT/bar
66 echo "File contents before unmounting filesystem:"
68 od -t x1 $SCRATCH_MNT/foo | _filter_od
70 od -t x1 $SCRATCH_MNT/bar | _filter_od
72 # Evicting the inode or clearing the page cache before reading again
73 # the file would also trigger the bug - reads were returning all bytes
74 # in the range corresponding to the second reference to the extent with
75 # a value of 0, but the correct data was persisted (it was a bug
76 # exclusively in the read path). The issue happened only if the same
77 # readpages() call targeted pages belonging to the first and second
78 # ranges that point to the same compressed extent.
81 echo "File contents after mounting filesystem again:"
82 # Must match the same contents we got before.
84 od -t x1 $SCRATCH_MNT/foo | _filter_od
86 od -t x1 $SCRATCH_MNT/bar | _filter_od
89 echo -e "\nTesting with zlib compression..."
90 test_clone_and_read_compressed_extent "-o compress=zlib"
94 echo -e "\nTesting with lzo compression..."
95 test_clone_and_read_compressed_extent "-o compress=lzo"