fstests: don't _require_metadata_journaling before _scratch_mkfs
[xfstests-dev.git] / tests / generic / 065
1 #! /bin/bash
2 # FS QA Test No. 065
3 #
4 # Test fsync on directories that got new hardlinks added to them and that point
5 # to existing inodes. The goal is to verify that after the fsync log is replayed
6 # the new hardlinks exist and the inodes have a correct link count.
7 # Also test that new hardlinks pointing to new inodes are logged and exist as
8 # well after the fsync log is replayed.
9 #
10 # This test is motivated by an issue discovered in btrfs, where the inode link
11 # counts were incorrect after the fsync log was replayed and the hardlinks for
12 # new inodes were not logged.
13 #
14 #-----------------------------------------------------------------------
15 # Copyright (C) 2015 SUSE Linux Products GmbH. All Rights Reserved.
16 # Author: Filipe Manana <fdmanana@suse.com>
17 #
18 # This program is free software; you can redistribute it and/or
19 # modify it under the terms of the GNU General Public License as
20 # published by the Free Software Foundation.
21 #
22 # This program is distributed in the hope that it would be useful,
23 # but WITHOUT ANY WARRANTY; without even the implied warranty of
24 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 # GNU General Public License for more details.
26 #
27 # You should have received a copy of the GNU General Public License
28 # along with this program; if not, write the Free Software Foundation,
29 # Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
30 #-----------------------------------------------------------------------
31 #
32
33 seq=`basename $0`
34 seqres=$RESULT_DIR/$seq
35 echo "QA output created by $seq"
36
37 here=`pwd`
38 tmp=/tmp/$$
39 status=1        # failure is the default!
40
41 _cleanup()
42 {
43         _cleanup_flakey
44         rm -f $tmp.*
45 }
46 trap "_cleanup; exit \$status" 0 1 2 3 15
47
48 # get standard environment, filters and checks
49 . ./common/rc
50 . ./common/filter
51 . ./common/dmflakey
52
53 # real QA test starts here
54 _supported_fs generic
55 _supported_os Linux
56 _require_scratch
57 _require_dm_target flakey
58
59 rm -f $seqres.full
60
61 _scratch_mkfs >> $seqres.full 2>&1
62 _require_metadata_journaling $SCRATCH_DEV
63 _init_flakey
64 _mount_flakey
65
66 # Create our main test file and directory.
67 $XFS_IO_PROG -f -c "pwrite -S 0xaa 0 8K" $SCRATCH_MNT/foo | _filter_xfs_io
68 mkdir $SCRATCH_MNT/mydir
69
70 # Make sure all metadata and data are durably persisted.
71 sync
72
73 # Add a hard link to 'foo' inside our test directory and fsync only the
74 # directory. The btrfs fsync implementation had a bug that caused the new
75 # directory entry to be visible after the fsync log replay but, the inode
76 # of our file remained with a link count of 1.
77 ln $SCRATCH_MNT/foo $SCRATCH_MNT/mydir/foo_2
78
79 # Add a few more links and new files.
80 # This is just to verify nothing breaks or gives incorrect results after the
81 # fsync log is replayed.
82 ln $SCRATCH_MNT/foo $SCRATCH_MNT/mydir/foo_3
83 $XFS_IO_PROG -f -c "pwrite -S 0xff 0 64K" $SCRATCH_MNT/hello | _filter_xfs_io
84 ln $SCRATCH_MNT/hello $SCRATCH_MNT/mydir/hello_2
85
86 # Add some subdirectories and new files and links to them. This is to verify
87 # that after fsyncing our top level directory 'mydir', all the subdirectories
88 # and their files/links are registered in the fsync log and exist after the
89 # fsync log is replayed.
90 mkdir -p $SCRATCH_MNT/mydir/x/y/z
91 ln $SCRATCH_MNT/foo $SCRATCH_MNT/mydir/x/y/foo_y_link
92 ln $SCRATCH_MNT/foo $SCRATCH_MNT/mydir/x/y/z/foo_z_link
93 touch $SCRATCH_MNT/mydir/x/y/z/qwerty
94
95 # Now fsync only our top directory.
96 $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/mydir
97
98 # And fsync now our new file named 'hello', just to verify later that it has
99 # the expected content and that the previous fsync on the directory 'mydir' had
100 # no bad influence on this fsync.
101 $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/hello
102
103 _flakey_drop_and_remount
104
105 # Verify the content of our file 'foo' remains the same as before, 8192 bytes,
106 # all with the value 0xaa.
107 echo "File 'foo' content after log replay:"
108 od -t x1 $SCRATCH_MNT/foo
109
110 # Remove the first name of our inode. Because of the directory fsync bug, the
111 # inode's link count was 1 instead of 5, so removing the 'foo' name ended up
112 # deleting the inode and the other names became stale directory entries (still
113 # visible to applications). Attempting to remove or access the remaining
114 # dentries pointing to that inode resulted in stale file handle errors and
115 # made it impossible to remove the parent directories since it was impossible
116 # for them to become empty.
117 echo "file 'foo' link count after log replay: $(stat -c %h $SCRATCH_MNT/foo)"
118 rm -f $SCRATCH_MNT/foo
119
120 # Now verify that all files, links and directories created before fsyncing our
121 # directory exist after the fsync log was replayed.
122 [ -f $SCRATCH_MNT/mydir/foo_2 ] || echo "Link mydir/foo_2 is missing"
123 [ -f $SCRATCH_MNT/mydir/foo_3 ] || echo "Link mydir/foo_3 is missing"
124 [ -f $SCRATCH_MNT/hello ] || echo "File hello is missing"
125 [ -f $SCRATCH_MNT/mydir/hello_2 ] || echo "Link mydir/hello_2 is missing"
126 [ -f $SCRATCH_MNT/mydir/x/y/foo_y_link ] || \
127         echo "Link mydir/x/y/foo_y_link is missing"
128 [ -f $SCRATCH_MNT/mydir/x/y/z/foo_z_link ] || \
129         echo "Link mydir/x/y/z/foo_z_link is missing"
130 [ -f $SCRATCH_MNT/mydir/x/y/z/qwerty ] || \
131         echo "File mydir/x/y/z/qwerty is missing"
132
133 # We expect our file here to have a size of 64Kb and all the bytes having the
134 # value 0xff.
135 echo "file 'hello' content after log replay:"
136 od -t x1 $SCRATCH_MNT/hello
137
138 # Now remove all files/links, under our test directory 'mydir', and verify we
139 # can remove all the directories.
140 rm -f $SCRATCH_MNT/mydir/x/y/z/*
141 rmdir $SCRATCH_MNT/mydir/x/y/z
142 rm -f $SCRATCH_MNT/mydir/x/y/*
143 rmdir $SCRATCH_MNT/mydir/x/y
144 rmdir $SCRATCH_MNT/mydir/x
145 rm -f $SCRATCH_MNT/mydir/*
146 rmdir $SCRATCH_MNT/mydir
147
148 # An fsck, run by the fstests framework everytime a test finishes, also detected
149 # the inconsistency and printed the following error message:
150 #
151 # root 5 inode 257 errors 2001, no inode item, link count wrong
152 #    unresolved ref dir 258 index 2 namelen 5 name foo_2 filetype 1 errors 4, no inode ref
153 #    unresolved ref dir 258 index 3 namelen 5 name foo_3 filetype 1 errors 4, no inode ref
154
155 status=0
156 exit