| #! /bin/bash |
| # SPDX-License-Identifier: GPL-2.0 |
| # Copyright (c) 2017 Liu Bo. All Rights Reserved. |
| # |
| # FS QA Test 142 |
| # |
| # Regression test for btrfs DIO read's repair during read without checksum. |
| # |
| # Commit 2dabb3248453 ("Btrfs: Direct I/O read: Work on sectorsized blocks") |
| # introduced this regression. It'd cause 'Segmentation fault' error. |
| # |
| # The upstream fix is |
| # commit 97bf5a5589aa ("Btrfs: fix segmentation fault when doing dio read") |
| # |
| . ./common/preamble |
| _begin_fstest auto quick read_repair |
| |
| . ./common/filter |
| . ./common/dmdust |
| |
| _require_scratch_dev_pool 2 |
| _require_dm_target dust |
| |
| _require_btrfs_command inspect-internal dump-tree |
| |
| _scratch_dev_pool_get 2 |
| # step 1, create a raid1 btrfs which contains one 128k file. |
| echo "step 1......mkfs.btrfs" >>$seqres.full |
| |
| _check_minimal_fs_size $(( 1024 * 1024 * 1024 )) |
| mkfs_opts="-d raid1 -b 1G" |
| _scratch_pool_mkfs $mkfs_opts >>$seqres.full 2>&1 |
| |
| # make sure data is written to the start position of the data chunk |
| _scratch_mount -o nodatasum $(_btrfs_no_v1_cache_opt) |
| |
| $XFS_IO_PROG -f -d -c "pwrite -S 0xaa -b 128K 0 128K" "$SCRATCH_MNT/foobar" |\ |
| _filter_xfs_io_offset |
| |
| # step 2, corrupt the first 64k of stripe #1 |
| echo "step 2......corrupt file extent" >>$seqres.full |
| |
| logical_in_btrfs=$(_btrfs_get_first_logical $SCRATCH_MNT/foobar) |
| echo "Logical offset is $logical_in_btrfs" >>$seqres.full |
| _scratch_unmount |
| |
| read -r stripe physical < <( |
| $BTRFS_UTIL_PROG inspect-internal dump-tree -t 3 "$SCRATCH_DEV" | |
| grep "$logical_in_btrfs" -A 6 | |
| $AWK_PROG '$1 == "stripe" && $3 == "devid" && $4 == 1 { print $2 " " $6; exit }') |
| echo "Physical offset of stripe $stripe is $physical on devid 1" >> $seqres.full |
| |
| $XFS_IO_PROG -d -c "pwrite -S 0xbb -b 64K $physical 64K" "$SCRATCH_DEV" > /dev/null |
| |
| _init_dust |
| _mount_dust |
| |
| # step 3, 128k dio read (this read can repair bad copy) |
| echo "step 3......repair the bad copy" >>$seqres.full |
| |
| $DMSETUP_PROG message dust-test 0 addbadblock $((physical / 512)) |
| $DMSETUP_PROG message dust-test 0 enable |
| |
| _btrfs_direct_read_on_mirror $stripe 2 "$SCRATCH_MNT/foobar" 0 128K |
| |
| _cleanup_dust |
| |
| # check if the repair works |
| $XFS_IO_PROG -c "pread -v -b 512 $physical 512" "$SCRATCH_DEV" | |
| _filter_xfs_io_offset |
| |
| _scratch_dev_pool_put |
| # success, all done |
| status=0 |
| exit |