4 # Test hardlink breakage on non-samefs setup
5 # This is a variant of overlay/018 to test.
7 # This simple test demonstrates a known issue with overlayfs:
8 # - file A and B are hardlinked in lower
9 # - modify A to trigger copy up
10 # - file A is no longer a hardlink of file B
12 #-----------------------------------------------------------------------
14 # Copyright (C) 2017 IBM Corporation. All Rights Reserved.
15 # Author: Chandan Rajendra <chandan@linux.vnet.ibm.com>
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.
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.
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 #-----------------------------------------------------------------------
33 seqres=$RESULT_DIR/$seq
34 echo "QA output created by $seq"
37 status=1 # failure is the default!
38 trap "_cleanup; exit \$status" 0 1 2 3 15
45 # get standard environment, filters and checks
49 # real QA test starts here
54 _require_scratch_feature index
55 _require_test_program "t_dir_type"
59 # Record inode numbers in format <ino> <nlink>
60 function record_ino_nlink()
62 ls -li $FILES | awk '{ print $1, $3, $10}' > $1
65 # Check inode numbers match recorded inode numbers
66 function check_ino_nlink()
72 record_ino_nlink $after
74 # Test constant stat(2) st_ino/st_nlink -
75 # Compare before..after - expect silence
76 # We use diff -u so out.bad will tell us which stage failed
77 diff -u $before $after
79 # Test constant readdir(3)/getdents(2) d_ino -
80 # Expect to find file by inode number
81 cat $before | while read ino nlink f; do
82 $here/src/t_dir_type $dir $ino | grep -q $(basename $f) || \
83 echo "$(basename $f) not found by ino $ino (from $before)"
87 lowerdir=$OVL_BASE_TEST_DIR/$seq-ovl-lower
91 # Create 2 hardlinked files in lower
92 echo "zero" >> $lowerdir/foo
93 ln $lowerdir/foo $lowerdir/bar
95 _scratch_mkfs >>$seqres.full 2>&1
97 upperdir=$OVL_BASE_SCRATCH_MNT/$OVL_UPPER
98 workdir=$OVL_BASE_SCRATCH_MNT/$OVL_WORK
100 # Enable overlay index feature to prevent breaking hardlinks on copy up
101 _overlay_scratch_mount_dirs $lowerdir $upperdir $workdir -o index=on
110 echo "== Before copy up =="
112 record_ino_nlink $tmp.before
114 # Modify content of one of the hardlinks
115 # Intentionally modify the last hardlink in $FILES, so after mount cycle
116 # when reading the first file in $FILES, last file won't be in inode/dcache
119 echo "== After write one =="
121 check_ino_nlink $SCRATCH_MNT $tmp.before $tmp.after_one
123 # Verify that the hardlinks survive a mount cycle
124 $UMOUNT_PROG $SCRATCH_MNT
125 _overlay_scratch_mount_dirs $lowerdir $upperdir $workdir -o index=on
127 echo "== After mount cycle =="
129 check_ino_nlink $SCRATCH_MNT $tmp.after_one $tmp.after_cycle
131 # Drop caches to get the copied up hardlink out of cache
132 echo 3 > /proc/sys/vm/drop_caches
134 # Modify content of the other hardlink
137 echo "== After write two =="
139 check_ino_nlink $SCRATCH_MNT $tmp.after_one $tmp.after_two