btrfs/139: require 2GB scratch dev
[xfstests-dev.git] / tests / btrfs / 088
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (C) 2015 SUSE Linux Products GmbH. All Rights Reserved.
4 #
5 # FS QA Test No. btrfs/088
6 #
7 # Test that btrfs' transaction abortion does not corrupt a filesystem mounted
8 # with -o discard nor allows a subsequent fstrim to corrupt the filesystem
9 # (regardless of being mounted with or without -o discard).
10 #
11 # This issue was fixed by the following linux kernel patch:
12 #
13 #    Btrfs: fix fs corruption on transaction abort if device supports discard
14 #    (commit 678886bdc6378c1cbd5072da2c5a3035000214e3)
15 #
16 seq=`basename $0`
17 seqres=$RESULT_DIR/$seq
18 echo "QA output created by $seq"
19
20 tmp=/tmp/$$
21 status=1        # failure is the default!
22 trap "_cleanup; exit \$status" 0 1 2 3 15
23
24 _cleanup()
25 {
26         rm -f $tmp.*
27 }
28
29 # get standard environment, filters and checks
30 . ./common/rc
31 . ./common/filter
32
33 # real QA test starts here
34 _supported_fs btrfs
35 _supported_os Linux
36 _require_scratch
37 _require_fail_make_request
38
39 SYSFS_BDEV=`_sysfs_dev $SCRATCH_DEV`
40
41 enable_io_failure()
42 {
43         echo 100 > $DEBUGFS_MNT/fail_make_request/probability
44         echo 1000 > $DEBUGFS_MNT/fail_make_request/times
45         echo 0 > $DEBUGFS_MNT/fail_make_request/verbose
46         echo 1 > $SYSFS_BDEV/make-it-fail
47 }
48
49 disable_io_failure()
50 {
51         echo 0 > $SYSFS_BDEV/make-it-fail
52         echo 0 > $DEBUGFS_MNT/fail_make_request/probability
53         echo 0 > $DEBUGFS_MNT/fail_make_request/times
54 }
55
56 rm -f $seqres.full
57
58 # We will abort a btrfs transaction later, which always produces a warning in
59 # dmesg. We do not want the test to fail because of this.
60 _disable_dmesg_check
61
62 _scratch_mkfs >>$seqres.full 2>&1
63 _scratch_mount "-o discard"
64 _require_batched_discard $SCRATCH_MNT
65
66 # Create a file and call sync to commit our first transaction.
67 $XFS_IO_PROG -f -c "pwrite -S 0xaa 0 1M" $SCRATCH_MNT/foo | _filter_xfs_io
68 sync
69
70 # Create some other file, which forces a COW operation of the fs root, adding
71 # the old root location to the pinned extents list, and opens a new btrfs
72 # transaction.
73 touch $SCRATCH_MNT/bar
74
75 # Write to the first file to verify later that the original data extent was not
76 # a victim of a discard operation.
77 $XFS_IO_PROG -c "pwrite -S 0xbb 512K 1M" $SCRATCH_MNT/foo | _filter_xfs_io
78
79 # Now make sure the next transaction commit will abort and turn the fs readonly,
80 # unmount the fs, mount it again and verify we can open file foo and read its
81 # content, which should be what it had when the first transaction was committed
82 # (first call to sync), since btrfs is a COW filesystem and foo was not fsynced.
83 # Btrfs used to issue a discard operation on the extents in the pinned extents
84 # list, resulting in corruption of metadata and data, and used too to return the
85 # pinned extents to the free space caches, allowing future fstrim operations to
86 # perform a discard operation against the pinned exents. This made the fs
87 # unmountable because the btree roots that the superblock points at were written
88 # in place (by the discard operations).
89 enable_io_failure
90
91 # This sync will trigger a commit of the current transaction, which will be
92 # aborted because IO will fail for metadata extents (btree nodes/leafs).
93 sync
94 disable_io_failure
95
96 touch $SCRATCH_MNT/abc >>$seqres.full 2>&1 && \
97         echo "Transaction was not aborted, filesystem is not in readonly mode"
98
99 # This fstrim operation should not cause discard operations to be performed
100 # against extents that were COWed, otherwise the next mount will fail since
101 # the btree roots that the superblock points at have their physical areas
102 # on disk full of zeroes.
103 $FSTRIM_PROG $SCRATCH_MNT
104
105 # We expect to be able to mount the fs again and have available all metadata and
106 # data that got persisted in the first transaction.
107 _scratch_cycle_mount
108
109 # We now expect file's foo content to match what it had when the first
110 # transaction was committed because the second transaction was aborted and we
111 # did not fsync foo.
112 echo "File foo content after transaction abort + remount:"
113 od -t x1 $SCRATCH_MNT/foo
114
115 status=0
116 exit