1065c702a28ac78d1ec9b5b6b846cca339f37287
[xfstests-dev.git] / tests / generic / 034
1 #! /bin/bash
2 # FS QA Test No. 034
3 #
4 # This test is motivated by a bug found in btrfs when replaying a directory
5 # from the fsync log. The issue was that if a directory entry is both found
6 # in the persisted metadata and in the fsync log, at log replay time the
7 # directory got set with a wrong i_size. This had the consequence of not being
8 # able to rmdir empty directories (failed with errno ENOTEMPTY).
9 # This was fixed in btrfs with the following linux kernel patch:
10 #
11 #     Btrfs: fix directory recovery from fsync log
12 #
13 #-----------------------------------------------------------------------
14 # Copyright (C) 2014 SUSE Linux Products GmbH. All Rights Reserved.
15 # Author: Filipe Manana <fdmanana@suse.com>
16 #
17 # This program is free software; you can redistribute it and/or
18 # modify it under the terms of the GNU General Public License as
19 # published by the Free Software Foundation.
20 #
21 # This program is distributed in the hope that it would be useful,
22 # but WITHOUT ANY WARRANTY; without even the implied warranty of
23 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 # GNU General Public License for more details.
25 #
26 # You should have received a copy of the GNU General Public License
27 # along with this program; if not, write the Free Software Foundation,
28 # Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
29 #-----------------------------------------------------------------------
30 #
31
32 seq=`basename $0`
33 seqres=$RESULT_DIR/$seq
34 echo "QA output created by $seq"
35
36 here=`pwd`
37 status=1        # failure is the default!
38
39 _cleanup()
40 {
41         _cleanup_flakey
42 }
43 trap "_cleanup; exit \$status" 0 1 2 3 15
44
45 # get standard environment, filters and checks
46 . ./common/rc
47 . ./common/filter
48 . ./common/dmflakey
49
50 # real QA test starts here
51 _supported_fs generic
52 _supported_os Linux
53 _need_to_be_root
54 _require_scratch
55 _require_dm_target flakey
56 _require_metadata_journaling $SCRATCH_DEV
57
58 rm -f $seqres.full
59
60 _scratch_mkfs >> $seqres.full 2>&1
61
62 _init_flakey
63 _mount_flakey
64
65 mkdir $SCRATCH_MNT/test_dir
66 touch $SCRATCH_MNT/test_dir/foo
67
68 # Invoke sync here because it's necessary to trigger the original bug in btrfs.
69 # The intention is that at log recovery time we have a dir entry for 'foo' both
70 # in the fs/subvol tree and in the log tree - this is necessary to trigger the
71 # bug on btrfs.
72 sync
73
74 touch $SCRATCH_MNT/test_dir/bar
75 $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/test_dir
76 $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/test_dir/bar
77
78 # In the original btrfs bug, log replay would update the directory's inode
79 # i_size incorrectly - it would sum again the size of dentry 'foo' (3) to
80 # the inode's i_size, which is incorrect because the dentry was already
81 # persisted before (in the fs/subvol tree).
82 _flakey_drop_and_remount
83
84 [ -f $SCRATCH_MNT/test_dir/foo ] || echo "file foo is missing"
85 [ -f $SCRATCH_MNT/test_dir/bar ] || echo "file bar is missing"
86
87 rm -f $SCRATCH_MNT/test_dir/foo
88 rm -f $SCRATCH_MNT/test_dir/bar
89
90 # In btrfs removing all entries from a directory should set the directory's
91 # inode i_size to 0, but with this bug that didn't happen and this made
92 # an rmdir fail with errno ENOTEMPTY (even though the directory had no more
93 # entries in it).
94 rmdir $SCRATCH_MNT/test_dir
95 [ -d $SCRATCH_MNT/test_dir ] && echo "rmdir didn't succeed"
96
97 _unmount_flakey
98
99 echo "Silence is golden"
100
101 status=0
102 exit