btrfs: add test case for rwf_nowait writes
[xfstests-dev.git] / tests / btrfs / 226
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (C) 2020 SUSE Linux Products GmbH. All Rights Reserved.
4 #
5 # FS QA Test No. btrfs/226
6 #
7 # Test several (btrfs specific) scenarios with RWF_NOWAIT writes, cases where
8 # they should fail and cases where they should succeed.
9 #
10 seq=`basename $0`
11 seqres=$RESULT_DIR/$seq
12 echo "QA output created by $seq"
13
14 tmp=/tmp/$$
15 status=1        # failure is the default!
16 trap "_cleanup; exit \$status" 0 1 2 3 15
17
18 _cleanup()
19 {
20         cd /
21         rm -f $tmp.*
22 }
23
24 # get standard environment, filters and checks
25 . ./common/rc
26 . ./common/filter
27 . ./common/reflink
28
29 # real QA test starts here
30 _supported_fs btrfs
31 _require_scratch_reflink
32 _require_chattr C
33 _require_odirect
34 _require_xfs_io_command pwrite -N
35 _require_xfs_io_command falloc -k
36 _require_xfs_io_command fpunch
37
38 rm -f $seqres.full
39
40 _scratch_mkfs >>$seqres.full 2>&1
41 _scratch_mount
42
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"
46 touch $SCRATCH_MNT/f1
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
50
51 # Check no data was written.
52 echo "File data after write attempt:"
53 od -A d -t x1 $SCRATCH_MNT/f1
54
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.
59 echo
60 echo "Testing write against extent shared across snapshots"
61 touch $SCRATCH_MNT/f2
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
66
67 $BTRFS_UTIL_PROG subvolume snapshot $SCRATCH_MNT $SCRATCH_MNT/snap \
68     | _filter_scratch
69
70 # Write into the range of the first extent so that that range no longer has a
71 # shared extent.
72 $XFS_IO_PROG -s -c "pwrite -S 0xab 0 64K" $SCRATCH_MNT/f2 | _filter_xfs_io
73
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
77
78 # Check no data was written.
79 echo "File data after write attempt:"
80 od -A d -t x1 $SCRATCH_MNT/f2
81
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.
84 echo
85 echo "Testing write against shared extent through reflink"
86 touch $SCRATCH_MNT/f3
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
91
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
94
95 # Check no data was written.
96 echo "File data after write attempt:"
97 od -A d -t x1 $SCRATCH_MNT/f3
98
99 # Create a file with a prealloc extent at eof and attempt to write to it, it
100 # should succeed.
101 echo
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
106
107 # Should succeed.
108 $XFS_IO_PROG -d -c "pwrite -N -V 1 -S 0xcd -b 64K 64K 64K" $SCRATCH_MNT/f4 \
109     | _filter_xfs_io
110
111 # Check the file has the expected data.
112 echo "File after write:"
113 od -A d -t x1 $SCRATCH_MNT/f4
114
115 # Attempts to write to ranges that have a hole, should fail with -EAGAIN.
116 echo
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
125
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
128
129 # Now try with a range that starts with a hole and ends with an extent, should
130 # fail as well.
131 $XFS_IO_PROG -c "fpunch 0 64K" \
132              -d -c "pwrite -N -V 1 -S 0x22 -b 128K 0 128K" \
133              $SCRATCH_MNT/f5
134
135 # Check no data was written.
136 echo "File data after write attempt:"
137 od -A d -t x1 $SCRATCH_MNT/f5
138
139 status=0
140 exit