2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (C) 2020 SUSE Linux Products GmbH. All Rights Reserved.
5 # FS QA Test No. btrfs/226
7 # Test several (btrfs specific) scenarios with RWF_NOWAIT writes, cases where
8 # they should fail and cases where they should succeed.
11 seqres=$RESULT_DIR/$seq
12 echo "QA output created by $seq"
15 status=1 # failure is the default!
16 trap "_cleanup; exit \$status" 0 1 2 3 15
24 # get standard environment, filters and checks
29 # real QA test starts here
31 _require_scratch_reflink
34 _require_xfs_io_command pwrite -N
35 _require_xfs_io_command falloc -k
36 _require_xfs_io_command fpunch
40 _scratch_mkfs >>$seqres.full 2>&1
43 # Test a write against COW file/extent - should fail with -EAGAIN. Disable the
44 # NOCOW attribute of the file just in case MOUNT_OPTIONS has "-o nodatacow".
45 echo "Testing write against COW file"
47 $CHATTR_PROG -C $SCRATCH_MNT/f1
48 $XFS_IO_PROG -s -c "pwrite -S 0xab 0 128K" $SCRATCH_MNT/f1 | _filter_xfs_io
49 $XFS_IO_PROG -d -c "pwrite -N -V 1 -S 0xff 32K 64K" $SCRATCH_MNT/f1
51 # Check no data was written.
52 echo "File data after write attempt:"
53 od -A d -t x1 $SCRATCH_MNT/f1
55 # Create a file with two extents (NOCOW), then create a snapshot, unshare the
56 # first extent by writing to it without RWF_NOWAIT, and then attempt to write
57 # to a file range that includes both the non-shared and the shared extent -
58 # should fail with -EAGAIN.
60 echo "Testing write against extent shared across snapshots"
62 $CHATTR_PROG +C $SCRATCH_MNT/f2
63 $XFS_IO_PROG -s -c "pwrite -S 0xab 0 64K" \
64 -c "pwrite -S 0xcd 64K 64K" \
65 $SCRATCH_MNT/f2 | _filter_xfs_io
67 $BTRFS_UTIL_PROG subvolume snapshot $SCRATCH_MNT $SCRATCH_MNT/snap \
70 # Write into the range of the first extent so that that range no longer has a
72 $XFS_IO_PROG -s -c "pwrite -S 0xab 0 64K" $SCRATCH_MNT/f2 | _filter_xfs_io
74 # Attempt to write into the file range, using RWF_NOWAIT, that covers the
75 # non-shared and the shared extents, should fail.
76 $XFS_IO_PROG -d -c "pwrite -N -V 1 -S 0xff -b 64K 32K 64K" $SCRATCH_MNT/f2
78 # Check no data was written.
79 echo "File data after write attempt:"
80 od -A d -t x1 $SCRATCH_MNT/f2
82 # Create a file that has an extent shared with file f2. Attempting to write
83 # into a range that covers the shared extent should fail with -EAGAIN.
85 echo "Testing write against shared extent through reflink"
87 $CHATTR_PROG +C $SCRATCH_MNT/f3
88 $XFS_IO_PROG -s -c "pwrite -S 0xab -b 64K 0 64K" \
89 -c "reflink $SCRATCH_MNT/f2 64K 64K 64K" \
90 $SCRATCH_MNT/f3 | _filter_xfs_io
92 # Should fail, range 64K to 96K has a shared extent.
93 $XFS_IO_PROG -d -c "pwrite -N -V 1 -S 0xff -b 64K 32K 64K" $SCRATCH_MNT/f3
95 # Check no data was written.
96 echo "File data after write attempt:"
97 od -A d -t x1 $SCRATCH_MNT/f3
99 # Create a file with a prealloc extent at eof and attempt to write to it, it
102 echo "Testing write against prealloc extent at eof"
103 $XFS_IO_PROG -f -s -c "pwrite -S 0xab 0 64K" \
104 -c "falloc -k 64K 64K" \
105 $SCRATCH_MNT/f4 | _filter_xfs_io
108 $XFS_IO_PROG -d -c "pwrite -N -V 1 -S 0xcd -b 64K 64K 64K" $SCRATCH_MNT/f4 \
111 # Check the file has the expected data.
112 echo "File after write:"
113 od -A d -t x1 $SCRATCH_MNT/f4
115 # Attempts to write to ranges that have a hole, should fail with -EAGAIN.
117 echo "Testing writes against ranges with holes"
118 touch $SCRATCH_MNT/f5
119 $CHATTR_PROG +C $SCRATCH_MNT/f5
120 # 3 64Kb extents, with a 64K hole at offset 128K.
121 $XFS_IO_PROG -s -d -c "pwrite -S 0xab -b 64K 0 64K" \
122 -s -d -c "pwrite -S 0xcd -b 64K 64K 64K" \
123 -s -d -c "pwrite -S 0xef -b 64K 192K 64K" \
124 $SCRATCH_MNT/f5 | _filter_xfs_io
126 # Should fail, second half of the range maps to a hole.
127 $XFS_IO_PROG -d -c "pwrite -N -V 1 -S 0x11 -b 128K 64K 128K" $SCRATCH_MNT/f5
129 # Now try with a range that starts with a hole and ends with an extent, should
131 $XFS_IO_PROG -c "fpunch 0 64K" \
132 -d -c "pwrite -N -V 1 -S 0x22 -b 128K 0 128K" \
135 # Check no data was written.
136 echo "File data after write attempt:"
137 od -A d -t x1 $SCRATCH_MNT/f5