#! /bin/bash # SPDX-License-Identifier: GPL-2.0 # Copyright (C) 2017 CTERA Networks. All Rights Reserved. # # FS QA Test 042 # # Test creating lower hardlinks for copied up files. # # kernel v4.13 introduced the index=on feature for not breaking hardlinks # on copy-up. With the index feature enabled a regression was introduced - # lower files that are hardlined while overlay is offline can result in # lookup error after overlay in mounted. # # The regression was fixed by upstream commit # 6eaf011144af ovl: fix EIO from lookup of non-indexed upper # that was merged to v4.14-rc7. # # This test verifies that behavior is sane after creating lower hardlinks # for copied up files while overlayfs is offline. # . ./common/preamble _begin_fstest auto quick copyup hardlink # Import common functions. . ./common/filter # real QA test starts here _supported_fs overlay _fixed_by_kernel_commit 6eaf011144af \ "ovl: fix EIO from lookup of non-indexed upper" _require_scratch # Without overlay index feature hardlinks are broken on copy up _require_scratch_feature index # Remove all files from previous tests _scratch_mkfs # Create lower file lowerdir=$OVL_BASE_SCRATCH_MNT/$OVL_LOWER mkdir -p $lowerdir touch $lowerdir/0 # Disable overlay index feature to copy up with no index _scratch_mount -o index=off # Copy up lower and create upper hardlink with no index ln $SCRATCH_MNT/0 $SCRATCH_MNT/1 $UMOUNT_PROG $SCRATCH_MNT # Add lower hardlinks while overlay is offline ln $lowerdir/0 $lowerdir/2 ln $lowerdir/0 $lowerdir/3 # Enable overlay index feature to lookup copied up upper aliases _scratch_mount -o index=on # Stat upper hardlink that were created with no index and whose copy up # origin is now an hardlink - expect same st_ino ino0=$(stat -c '%i' $SCRATCH_MNT/0) ino1=$(stat -c '%i' $SCRATCH_MNT/1) [[ $ino0 == $ino1 ]] || \ echo "Mismatch inode number for non-indexed upper hardlinks" # Copy up lower and create new upper hardlink with index, because # lower is a hardlink and index is enabled. The new hardlinks are not # associated with the hardlinks that were created when lower was not # a hardlink. ln $SCRATCH_MNT/2 $SCRATCH_MNT/4 # Mount cycle to reset inode/dentry cache _scratch_cycle_mount index=on # Stat files that were copied up with index and whose copy up origin # is now an hardlink - expect same st_ino as lower aliases and different # st_ino from non-indexed upper aliases. ino0=$(stat -c '%i' $SCRATCH_MNT/0) ino1=$(stat -c '%i' $SCRATCH_MNT/1) ino2=$(stat -c '%i' $SCRATCH_MNT/2) ino3=$(stat -c '%i' $SCRATCH_MNT/3) ino4=$(stat -c '%i' $SCRATCH_MNT/4) [[ $ino0 == $ino1 ]] || \ echo "Mismatch inode number for non-indexed upper hardlinks" [[ $ino2 == $ino4 ]] || \ echo "Mismatch inode number for indexed upper hardlinks" [[ $ino2 == $ino3 ]] || \ echo "Mismatch inode number for indexed upper and lower hardlinks" [[ $ino2 != $ino0 ]] || \ echo "Unexpected matching inode number for indexed and non-indexed upper hardlinks" # Mount cycle to reset inode/dentry cache _scratch_cycle_mount index=on # Unlink all hardlinks - if overlay inode nlink is 0, this will trigger # WARN_ON() in drop_nlink() rm $SCRATCH_MNT/0 rm $SCRATCH_MNT/1 rm $SCRATCH_MNT/2 rm $SCRATCH_MNT/3 rm $SCRATCH_MNT/4 echo "Silence is golden" status=0 exit