2b4ca735365d94433cc6b0c54a6a98d8908a6238
[xfstests-dev.git] / tests / overlay / 034
1 #! /bin/bash
2 # FS QA Test 034
3 #
4 # Test overlay nlink when adding lower hardlinks.
5 #
6 # nlink of overlay inode could be dropped indefinitely by adding
7 # unaccounted lower hardlinks underneath a mounted overlay and
8 # trying to remove them.
9 #
10 # The simplest way to understand this test is this:
11 # Imagine that you have a tool (e.g. xfs_db) with which you can add
12 # hardlinks, without changing the value of nlink stored on-disk for the
13 # inode. This is exactly what this test does when it adds lower hardlinks
14 # underneath a mounted overlay.
15 #
16 # Commit 5f8415d6b87e ("ovl: persistent overlay inode nlink for indexed
17 # inodes") fixes this issue, although the issue was never exposed in any
18 # released kernel.
19 #
20 # With overlayfs indexed copy up and without the fix, the test triggers
21 # WARN_ON(inode->i_nlink == 0) in drop_link().
22 #
23 #-----------------------------------------------------------------------
24 # Copyright (C) 2017 CTERA Networks. All Rights Reserved.
25 # Author: Amir Goldstein <amir73il@gmail.com>
26 #
27 # This program is free software; you can redistribute it and/or
28 # modify it under the terms of the GNU General Public License as
29 # published by the Free Software Foundation.
30 #
31 # This program is distributed in the hope that it would be useful,
32 # but WITHOUT ANY WARRANTY; without even the implied warranty of
33 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
34 # GNU General Public License for more details.
35 #
36 # You should have received a copy of the GNU General Public License
37 # along with this program; if not, write the Free Software Foundation,
38 # Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
39 #-----------------------------------------------------------------------
40 #
41
42 seq=`basename $0`
43 seqres=$RESULT_DIR/$seq
44 echo "QA output created by $seq"
45
46 tmp=/tmp/$$
47 status=1        # failure is the default!
48 trap "_cleanup; exit \$status" 0 1 2 3 15
49
50 _cleanup()
51 {
52         cd /
53         rm -f $tmp.*
54 }
55
56 # get standard environment, filters and checks
57 . ./common/rc
58 . ./common/filter
59
60 # remove previous $seqres.full before test
61 rm -f $seqres.full
62
63 # real QA test starts here
64 _supported_fs overlay
65 _supported_os Linux
66 _require_scratch
67
68 # Remove all files from previous tests
69 _scratch_mkfs
70
71 # Create lower hardlink
72 lowerdir=$OVL_BASE_SCRATCH_MNT/$OVL_LOWER
73 mkdir -p $lowerdir
74 touch $lowerdir/0
75 ln $lowerdir/0 $lowerdir/1
76
77 _scratch_mount
78
79 # Copy up lower hardlink - overlay inode nlink 2 is copied from lower
80 touch $SCRATCH_MNT/0
81
82 # Add lower hardlinks while overlay is mounted - overlay inode nlink
83 # is not being updated
84 ln $lowerdir/0 $lowerdir/2
85 ln $lowerdir/0 $lowerdir/3
86
87 # Unlink the 2 un-accounted lower hardlinks - overlay inode nlinks
88 # drops 2 and may reach 0 if the situation is not detected
89 rm $SCRATCH_MNT/2
90 rm $SCRATCH_MNT/3
91
92 # Check if getting ENOENT when trying to link !I_LINKABLE with nlink 0
93 ln $SCRATCH_MNT/0 $SCRATCH_MNT/4
94
95 # Unlink all hardlinks - if overlay inode nlink is 0, this will trigger
96 # WARN_ON() in drop_nlink()
97 rm $SCRATCH_MNT/0
98 rm $SCRATCH_MNT/1
99 rm $SCRATCH_MNT/4
100
101 # Verify that orphan index is cleaned on mount
102 _scratch_cycle_mount
103 ls $OVL_BASE_SCRATCH_MNT/$OVL_WORK/index 2>/dev/null
104
105 echo "Silence is golden"
106 status=0
107 exit