#! /bin/bash # SPDX-License-Identifier: GPL-2.0 # Copyright (c) 2014 Filipe Manana. All Rights Reserved. # # FS QA Test No. btrfs/037 # # Test for a btrfs data corruption when using compressed files/extents. # Under certain cases, it was possible for reads to return random data # (content from a previously used page) instead of zeroes. This also # caused partial updates to those regions that were supposed to be filled # with zeroes to save random (and invalid) data into the file extents. # # This is fixed by the commit for the linux kernel titled: # # Btrfs: fix data corruption when reading/updating compressed extents # . ./common/preamble _begin_fstest auto quick compress prealloc tmp=`mktemp -d` # Override the default cleanup function. _cleanup() { rm -fr $tmp } # Import common functions. . ./common/filter # real QA test starts here _supported_fs btrfs _require_scratch _require_xfs_io_command "falloc" _scratch_mkfs >/dev/null 2>&1 _scratch_mount "-o compress-force=lzo" $XFS_IO_PROG -f -c "pwrite -S 0x06 -b 18670 266978 18670" \ $SCRATCH_MNT/foobar | _filter_xfs_io $XFS_IO_PROG -c "falloc 26450 665194" $SCRATCH_MNT/foobar | _filter_xfs_io $XFS_IO_PROG -c "truncate 542872" $SCRATCH_MNT/foobar | _filter_xfs_io $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/foobar | _filter_xfs_io # Expected file items in the fs tree are (from btrfs-debug-tree): # # item 4 key (257 INODE_ITEM 0) itemoff 15879 itemsize 160 # inode generation 6 transid 6 size 542872 block group 0 mode 100600 # item 5 key (257 INODE_REF 256) itemoff 15863 itemsize 16 # inode ref index 2 namelen 6 name: foobar # item 6 key (257 EXTENT_DATA 0) itemoff 15810 itemsize 53 # extent data disk byte 0 nr 0 gen 6 # extent data offset 0 nr 24576 ram 266240 # extent compression 0 # item 7 key (257 EXTENT_DATA 24576) itemoff 15757 itemsize 53 # prealloc data disk byte 12849152 nr 241664 gen 6 # prealloc data offset 0 nr 241664 # item 8 key (257 EXTENT_DATA 266240) itemoff 15704 itemsize 53 # extent data disk byte 12845056 nr 4096 gen 6 # extent data offset 0 nr 20480 ram 20480 # extent compression 2 # item 9 key (257 EXTENT_DATA 286720) itemoff 15651 itemsize 53 # prealloc data disk byte 13090816 nr 405504 gen 6 # prealloc data offset 0 nr 258048 # # The on disk extent at 266240, contains 5 compressed chunks of file data. # Each of the first 4 chunks compress 4096 bytes of file data, while the last # one compresses only 3024 bytes of file data. Because this extent item is not # the last one in the file, as it followed by a prealloc extent, reads into # the region [285648 ; 286720[ (length = 4096 - 3024) should return zeroes. _scratch_unmount _check_btrfs_filesystem $SCRATCH_DEV EXPECTED_MD5="b8b0dbb8e02f94123c741c23659a1c0a" for i in `seq 1 27` do _scratch_mount "-o ro" MD5=`md5sum $SCRATCH_MNT/foobar | cut -f 1 -d ' '` _scratch_unmount if [ "${MD5}x" != "${EXPECTED_MD5}x" ] then echo "Unexpected file digest (wanted $EXPECTED_MD5, got $MD5)" fi done status=0 exit