generic: test for file loss after mix of rename, fsync and inode eviction
[xfstests-dev.git] / tests / generic / 260
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright 2011 (C) Red Hat, Inc., Lukas Czerner <lczerner@redhat.com>
4 #
5 # FS QA Test No. 260
6 #
7 # Purpose of this test is to check FITRIM argument handling to make sure
8 # that the argument processing is right and that it does not overflow.
9 #
10 . ./common/preamble
11 _begin_fstest auto quick trim
12
13 status=0
14 chpid=0
15 mypid=$$
16
17 # Import common functions.
18 . ./common/filter
19
20 # real QA test starts here
21 _supported_fs generic
22 _require_math
23
24 _require_scratch
25 _scratch_mkfs >/dev/null 2>&1
26 _scratch_mount
27
28 _require_batched_discard $SCRATCH_MNT
29
30 fssize=$($DF_PROG -k | grep "$SCRATCH_MNT" | grep "$SCRATCH_DEV"  | awk '{print $3}')
31
32 beyond_eofs=$(_math "$fssize*2048")
33 max_64bit=$(_math "2^64 - 1")
34
35 # All these tests should return EINVAL
36 # since the start is beyond the end of
37 # the file system
38
39 echo "[+] Start beyond the end of fs (should fail)"
40 out=$($FSTRIM_PROG -o $beyond_eofs $SCRATCH_MNT 2>&1)
41 [ $? -eq 0 ] && status=1
42 echo $out | _filter_scratch
43
44 echo "[+] Start beyond the end of fs with len set (should fail)"
45 out=$($FSTRIM_PROG -o $beyond_eofs -l1M $SCRATCH_MNT 2>&1)
46 [ $? -eq 0 ] && status=1
47 echo $out | _filter_scratch
48
49 echo "[+] Start = 2^64-1 (should fail)"
50 out=$($FSTRIM_PROG -o $max_64bit $SCRATCH_MNT 2>&1)
51 [ $? -eq 0 ] && status=1
52 echo $out | _filter_scratch
53
54 echo "[+] Start = 2^64-1 and len is set (should fail)"
55 out=$($FSTRIM_PROG -o $max_64bit -l1M $SCRATCH_MNT 2>&1)
56 [ $? -eq 0 ] && status=1
57 echo $out | _filter_scratch
58
59 _scratch_unmount
60 _scratch_mkfs >/dev/null 2>&1
61 _scratch_mount
62
63 # All these tests should succeed
64 # since the length should be truncated
65
66 echo "[+] Default length (should succeed)"
67 $FSTRIM_PROG $SCRATCH_MNT
68 [ $? -ne 0 ] && status=1
69 echo "[+] Default length with start set (should succeed)"
70 $FSTRIM_PROG -o10M $SCRATCH_MNT
71 [ $? -ne 0 ] && status=1
72 echo "[+] Length beyond the end of fs (should succeed)"
73 $FSTRIM_PROG -l $beyond_eofs $SCRATCH_MNT
74 [ $? -ne 0 ] && status=1
75 echo "[+] Length beyond the end of fs with start set (should succeed)"
76 $FSTRIM_PROG -o10M -l $beyond_eofs $SCRATCH_MNT
77 [ $? -ne 0 ] && status=1
78
79 _scratch_unmount
80 _scratch_mkfs >/dev/null 2>&1
81 _scratch_mount
82
83 # This is a bit fuzzy, but since the file system is fresh
84 # there should be at least (fssize/2) free space to trim.
85 # This is supposed to catch wrong FITRIM argument handling
86 bytes=$($FSTRIM_PROG -v -o10M $SCRATCH_MNT | _filter_fstrim)
87
88 if [ $bytes -gt $(_math "$fssize*1024") ]; then
89         status=1
90         echo "After the full fs discard $bytes bytes were discarded"\
91              "however the file system is $(_math "$fssize*1024") bytes long."
92 fi
93
94 # Btrfs is special and this test does not apply to it
95 # It is because btrfs does not have not-yet-used parts of the device
96 # mapped and since we got here right after the mkfs, there is not
97 # enough free extents in the root tree.
98 # F2fs is also special. F2fs can tag a special flag TRIMMED_FLAG to
99 # indicate the whole filesystem is trimmed, so after mkfs/fstrim(),
100 # following fstrim() won't trim any block.
101 if [ $bytes -le $(_math "$fssize*512") ] && [ $FSTYP != "btrfs" ] && [ $FSTYP != "f2fs" ]; then
102         status=1
103         echo "After the full fs discard $bytes bytes were discarded"\
104              "however the file system is $(_math "$fssize*1024") bytes long."
105 fi
106
107 # Now to catch overflows due to fsblk->allocation group number conversion
108 # This is different for every file system and it also apply just to some of
109 # them. In order to add check specific for file system you're interested in
110 # compute the arguments as you need and make the file system with proper
111 # alignment
112
113 # (2^32-1) + 2 (this is set to overflow 32bit variable by 2)
114 base=$(_math "2^32+1")
115
116 case $FSTYP in
117         ext[34])
118                 agsize=32768
119                 bsize=4096
120                 start=$(_math "$base*$agsize*$bsize")
121                 len=$start
122                 export MKFS_OPTIONS="-F -b $bsize -g $agsize"
123                 ;;
124         xfs)
125                 agsize=65538
126                 bsize=4096
127                 start=$(_math "$base*$agsize*$bsize")
128                 len=$start
129                 export MKFS_OPTIONS="-f -d agsize=$(_math "$agsize*$bsize") -b size=$bsize"
130                 ;;
131         *)
132                 # (2^32-1) * 4096 * 65536 == 32bit max size * block size * ag size
133                 start=$(_math "(2^32 - 1) * 4096 * 65536")
134                 len=$start
135                 ;;
136 esac
137
138 _scratch_unmount
139 _scratch_mkfs >/dev/null 2>&1
140 _scratch_mount
141 # It should fail since $start is beyond the end of file system
142 $FSTRIM_PROG -o$start -l10M $SCRATCH_MNT &> /dev/null
143 if [ $? -eq 0 ]; then
144         status=1
145         echo "It seems that fs logic handling start"\
146              "argument overflows"
147 fi
148
149 _scratch_unmount
150 _scratch_mkfs >/dev/null 2>&1
151 _scratch_mount
152
153 # len should be big enough to cover the whole file system, so if the
154 # number of discarded bytes is smaller than file system size/2 then it
155 # most likely overflowed
156 # Btrfs is special and this test does not apply to it
157 # It is because btrfs does not have not-yet-used parts of the device
158 # mapped and since we got here right after the mkfs, there is not
159 # enough free extents in the root tree.
160 # F2fs is also special. F2fs can tag a special flag TRIMMED_FLAG to
161 # indicate the whole filesystem is trimmed, so after mkfs/fstrim(),
162 # following fstrim() won't trim any block.
163 bytes=$($FSTRIM_PROG -v -l$len $SCRATCH_MNT | _filter_fstrim)
164 if [ $bytes -le $(_math "$fssize*512") ] && [ $FSTYP != "btrfs" ] && [ $FSTYP != "f2fs" ]; then
165         status=1
166         echo "It seems that fs logic handling len argument overflows"
167 fi
168
169 echo "Test done"
170 exit