Files
apfstests/tests/overlay/018
T
Amir Goldstein 004a78036e overlay/018: test lower hardlinks re-unite on copy up
Test that when two lower hardlinks are copied up, they end up
as two upper hardlinks of the same upper inode.

Drop caches before copy up so there is no knowledge of the
copied up hardlink in inode/dcache.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Reviewed-by: Eryu Guan <eguan@redhat.com>
Signed-off-by: Eryu Guan <eguan@redhat.com>
2017-07-06 13:38:59 +08:00

126 lines
2.9 KiB
Bash
Executable File

#! /bin/bash
# FSQA Test No. 018
#
# Test hardlink breakage
#
# This simple test demonstrates a known issue with overlayfs:
# - file A and B are hardlinked in lower
# - modify A to trigger copy up
# - file A is no longer a hardlink of file B
#
#-----------------------------------------------------------------------
#
# Copyright (C) 2016 CTERA Networks. All Rights Reserved.
# Author: Amir Goldstein <amir73il@gmail.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it would be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#-----------------------------------------------------------------------
#
seq=`basename $0`
seqres=$RESULT_DIR/$seq
echo "QA output created by $seq"
tmp=/tmp/$$
status=1 # failure is the default!
trap "_cleanup; exit \$status" 0 1 2 3 15
_cleanup()
{
rm -f $tmp.*
}
# get standard environment, filters and checks
. ./common/rc
. ./common/filter
# real QA test starts here
_supported_fs overlay
_supported_os Linux
_require_scratch
rm -f $seqres.full
_scratch_mkfs >>$seqres.full 2>&1
# Create 2 hardlinked files in lower
lowerdir=$OVL_BASE_SCRATCH_MNT/$OVL_LOWER
mkdir -p $lowerdir
echo "zero" >> $lowerdir/foo
ln $lowerdir/foo $lowerdir/bar
# Record inode numbers in format <ino> <nlink>
function record_ino_nlink()
{
ls -li $FILES | awk '{ print $1, $3 }' > $1
}
# Check inode numbers match recorded inode numbers
function check_ino_nlink()
{
before=$1
after=$2
record_ino_nlink $after
# Test constant stat(2) st_ino/st_nlink -
# Compare before..after - expect silence
# We use diff -u so out.bad will tell us which stage failed
diff -u $before $after
}
_scratch_mount
rm -f $tmp.*
foo=$SCRATCH_MNT/foo
bar=$SCRATCH_MNT/bar
FILES="$foo $bar"
echo "== Before copy up =="
cat $FILES
record_ino_nlink $tmp.before
# Modify content of one of the hardlinks
# Intentionally modify the last hardlink in $FILES, so after mount cycle
# when reading the first file in $FILES, last file won't be in inode/dcache
echo "one" >> $bar
echo "== After write one =="
cat $FILES
check_ino_nlink $tmp.before $tmp.after_one
# Verify that the hardlinks survive a mount cycle
_scratch_cycle_mount
echo "== After mount cycle =="
cat $FILES
check_ino_nlink $tmp.after_one $tmp.after_cycle
# Drop caches to get the copied up hardlink out of cache
echo 3 > /proc/sys/vm/drop_caches
# Modify content of the other hardlink
echo "two" >> $foo
echo "== After write two =="
cat $FILES
check_ino_nlink $tmp.after_one $tmp.after_two
status=0
exit