mirror of
https://github.com/linux-apfs/apfstests.git
synced 2026-05-01 15:01:44 -07:00
004a78036e
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>
126 lines
2.9 KiB
Bash
Executable File
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
|