generic: test MADV_POPULATE_READ with IO errors
[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 . ./common/preamble
11 _begin_fstest auto quick rw snapshot clone prealloc punch
12
13 # Import common functions.
14 . ./common/filter
15 . ./common/reflink
16
17 # real QA test starts here
18 _supported_fs btrfs
19 _require_scratch_reflink
20 _require_chattr C
21 _require_odirect
22 _require_xfs_io_command pwrite -N
23 _require_xfs_io_command falloc -k
24 _require_xfs_io_command fpunch
25
26 _scratch_mkfs >>$seqres.full 2>&1
27 _scratch_mount
28
29 # Test a write against COW file/extent - should fail with -EAGAIN. Disable the
30 # NOCOW attribute of the file just in case MOUNT_OPTIONS has "-o nodatacow".
31 echo "Testing write against COW file"
32 touch $SCRATCH_MNT/f1
33 $CHATTR_PROG -C $SCRATCH_MNT/f1
34 $XFS_IO_PROG -s -c "pwrite -S 0xab 0 128K" $SCRATCH_MNT/f1 | _filter_xfs_io
35 $XFS_IO_PROG -d -c "pwrite -N -V 1 -S 0xff 32K 64K" $SCRATCH_MNT/f1
36
37 # Check no data was written.
38 echo "File data after write attempt:"
39 od -A d -t x1 $SCRATCH_MNT/f1
40
41 # Create a file with two extents (NOCOW), then create a snapshot, unshare the
42 # first extent by writing to it without RWF_NOWAIT, and then attempt to write
43 # to a file range that includes both the non-shared and the shared extent -
44 # should fail with -EAGAIN.
45 echo
46 echo "Testing write against extent shared across snapshots"
47 touch $SCRATCH_MNT/f2
48 $CHATTR_PROG +C $SCRATCH_MNT/f2
49 $XFS_IO_PROG -s -c "pwrite -S 0xab 0 64K" \
50              -c "pwrite -S 0xcd 64K 64K" \
51              $SCRATCH_MNT/f2 | _filter_xfs_io
52
53 $BTRFS_UTIL_PROG subvolume snapshot $SCRATCH_MNT $SCRATCH_MNT/snap \
54     | _filter_scratch
55
56 # Write into the range of the first extent so that that range no longer has a
57 # shared extent.
58 $XFS_IO_PROG -s -c "pwrite -S 0xab 0 64K" $SCRATCH_MNT/f2 | _filter_xfs_io
59
60 # Attempt to write into the file range, using RWF_NOWAIT, that covers the
61 # non-shared and the shared extents, should fail.
62 $XFS_IO_PROG -d -c "pwrite -N -V 1 -S 0xff -b 64K 32K 64K" $SCRATCH_MNT/f2
63
64 # Check no data was written.
65 echo "File data after write attempt:"
66 od -A d -t x1 $SCRATCH_MNT/f2
67
68 # Create a file that has an extent shared with file f2. Attempting to write
69 # into a range that covers the shared extent should fail with -EAGAIN.
70 echo
71 echo "Testing write against shared extent through reflink"
72 touch $SCRATCH_MNT/f3
73 $CHATTR_PROG +C $SCRATCH_MNT/f3
74 $XFS_IO_PROG -s -c "pwrite -S 0xab -b 64K 0 64K" \
75              -c "reflink $SCRATCH_MNT/f2 64K 64K 64K" \
76              $SCRATCH_MNT/f3 | _filter_xfs_io
77
78 # Should fail, range 64K to 96K has a shared extent.
79 $XFS_IO_PROG -d -c "pwrite -N -V 1 -S 0xff -b 64K 32K 64K" $SCRATCH_MNT/f3
80
81 # Check no data was written.
82 echo "File data after write attempt:"
83 od -A d -t x1 $SCRATCH_MNT/f3
84
85 # Create a file with a prealloc extent at eof and attempt to write to it, it
86 # should succeed.
87 echo
88 echo "Testing write against prealloc extent at eof"
89 $XFS_IO_PROG -f -s -c "pwrite -S 0xab 0 64K" \
90              -c "falloc -k 64K 64K" \
91              $SCRATCH_MNT/f4 | _filter_xfs_io
92
93 # Should succeed.
94 $XFS_IO_PROG -d -c "pwrite -N -V 1 -S 0xcd -b 64K 64K 64K" $SCRATCH_MNT/f4 \
95     | _filter_xfs_io
96
97 # Check the file has the expected data.
98 echo "File after write:"
99 od -A d -t x1 $SCRATCH_MNT/f4
100
101 # Attempts to write to ranges that have a hole, should fail with -EAGAIN.
102 echo
103 echo "Testing writes against ranges with holes"
104 touch $SCRATCH_MNT/f5
105 $CHATTR_PROG +C $SCRATCH_MNT/f5
106 # 3 64Kb extents, with a 64K hole at offset 128K.
107 $XFS_IO_PROG -s -d -c "pwrite -S 0xab -b 64K 0 64K" \
108              -s -d -c "pwrite -S 0xcd -b 64K 64K 64K" \
109              -s -d -c "pwrite -S 0xef -b 64K 192K 64K" \
110              $SCRATCH_MNT/f5 | _filter_xfs_io
111
112 # Should fail, second half of the range maps to a hole.
113 $XFS_IO_PROG -d -c "pwrite -N -V 1 -S 0x11 -b 128K 64K 128K" $SCRATCH_MNT/f5
114
115 # Now try with a range that starts with a hole and ends with an extent, should
116 # fail as well.
117 $XFS_IO_PROG -c "fpunch 0 64K" \
118              -d -c "pwrite -N -V 1 -S 0x22 -b 128K 0 128K" \
119              $SCRATCH_MNT/f5
120
121 # Check no data was written.
122 echo "File data after write attempt:"
123 od -A d -t x1 $SCRATCH_MNT/f5
124
125 status=0
126 exit