tests: remove udf/101
[xfstests-dev.git] / tests / generic / 040
1 #! /bin/bash
2 # FS QA Test No. 040
3 #
4 # This test is motivated by an fsync issue discovered in btrfs.
5 # The issue in btrfs was that adding a new hard link to an inode that already
6 # had a large number of hardlinks and fsync the inode, would make the fsync
7 # log replay code update the inode with a wrong link count (smaller than the
8 # correct value). This resulted later in dangling directory index entries,
9 # after removing most of the hard links (correct_value - wrong_value), that
10 # were visible to user space but it was impossible to delete them or do
11 # any other operation on them (since they pointed to an inode that didn't
12 # exist anymore, resulting in -ESTALE errors).
13 #
14 # The btrfs issue was fixed by the following linux kernel patch:
15 #
16 #    Btrfs: fix fsync when extend references are added to an inode
17 #
18 # This issue was present in btrfs since the extrefs (extend references)
19 # feature was added (2012).
20 #
21 #-----------------------------------------------------------------------
22 # Copyright (C) 2015 SUSE Linux Products GmbH. All Rights Reserved.
23 # Author: Filipe Manana <fdmanana@suse.com>
24 #
25 # This program is free software; you can redistribute it and/or
26 # modify it under the terms of the GNU General Public License as
27 # published by the Free Software Foundation.
28 #
29 # This program is distributed in the hope that it would be useful,
30 # but WITHOUT ANY WARRANTY; without even the implied warranty of
31 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
32 # GNU General Public License for more details.
33 #
34 # You should have received a copy of the GNU General Public License
35 # along with this program; if not, write the Free Software Foundation,
36 # Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
37 #-----------------------------------------------------------------------
38 #
39
40 seq=`basename $0`
41 seqres=$RESULT_DIR/$seq
42 echo "QA output created by $seq"
43
44 here=`pwd`
45 tmp=/tmp/$$
46 status=1        # failure is the default!
47
48 _cleanup()
49 {
50         _cleanup_flakey
51 }
52 trap "_cleanup; exit \$status" 0 1 2 3 15
53
54 # get standard environment, filters and checks
55 . ./common/rc
56 . ./common/filter
57 . ./common/dmflakey
58
59 # real QA test starts here
60 _supported_fs generic
61 _supported_os Linux
62 _require_scratch
63 _require_dm_target flakey
64 _require_metadata_journaling $SCRATCH_DEV
65
66 rm -f $seqres.full
67
68 # If the test filesystem is btrfs, make sure we create a filesystem with
69 # the extend references (extrefs) feature enabled (it's enabled by default
70 # in recent versions of btrfs-progs).
71 if [ "$FSTYP" = "btrfs" ]; then
72         _scratch_mkfs "-O extref" >> $seqres.full 2>&1
73 else
74         _scratch_mkfs >> $seqres.full 2>&1
75 fi
76
77 _init_flakey
78 _mount_flakey
79
80 # Create a test file with 3001 hard links. This number is large enough to
81 # make btrfs start using extrefs at some point even if the fs has the maximum
82 # possible leaf/node size (64Kb).
83 echo "hello world" > $SCRATCH_MNT/foo
84 for i in `seq 1 3000`; do
85         ln $SCRATCH_MNT/foo $SCRATCH_MNT/foo_link_`printf "%04d" $i`
86 done
87
88 # Make sure all metadata and data are durably persisted.
89 sync
90
91 # Add one more link to the inode that ends up being a btrfs extref and fsync
92 # the inode.
93 ln $SCRATCH_MNT/foo $SCRATCH_MNT/foo_link_3001
94 $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/foo
95
96 _flakey_drop_and_remount
97
98 # Now after the fsync log replay btrfs left our inode with a wrong link count N,
99 # which was smaller than the correct link count M (N < M).
100 # So after removing N hard links, the remaining M - N directory entries were
101 # still visible to user space but it was impossible to do anything with them
102 # because they pointed to an inode that didn't exist anymore. This resulted in
103 # stale file handle errors (-ESTALE) when accessing those dentries for example.
104 #
105 # So remove all hard links except the first one and then attempt to read the
106 # file, to verify we don't get an -ESTALE error when accessing the inode.
107 #
108 # The btrfs fsck tool also detected the incorrect inode link count and it
109 # reported an error message like the following:
110 #
111 # root 5 inode 257 errors 2001, no inode item, link count wrong
112 #   unresolved ref dir 256 index 2978 namelen 13 name foo_link_2976 filetype 1 errors 4, no inode ref
113 #
114 # The fstests framework automatically calls fsck after a test is run, so we
115 # don't need to call fsck explicitly here.
116
117 echo "Link count before rm foo_link_*: $(stat -c %h $SCRATCH_MNT/foo)"
118 rm -f $SCRATCH_MNT/foo_link_*
119 echo "Link count after rm foo_link_*: $(stat -c %h $SCRATCH_MNT/foo)"
120 cat $SCRATCH_MNT/foo
121
122 status=0
123 exit