mirror of
https://github.com/linux-apfs/apfstests.git
synced 2026-05-01 15:01:44 -07:00
56ff01f471
The check script requires that it be run as root, so adding individualized checks for this in each teat is not needed. Signed-off-by: Theodore Ts'o <tytso@mit.edu> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Dave Chinner <david@fromorbit.com>
157 lines
5.8 KiB
Bash
Executable File
157 lines
5.8 KiB
Bash
Executable File
#! /bin/bash
|
|
# FS QA Test No. 065
|
|
#
|
|
# Test fsync on directories that got new hardlinks added to them and that point
|
|
# to existing inodes. The goal is to verify that after the fsync log is replayed
|
|
# the new hardlinks exist and the inodes have a correct link count.
|
|
# Also test that new hardlinks pointing to new inodes are logged and exist as
|
|
# well after the fsync log is replayed.
|
|
#
|
|
# This test is motivated by an issue discovered in btrfs, where the inode link
|
|
# counts were incorrect after the fsync log was replayed and the hardlinks for
|
|
# new inodes were not logged.
|
|
#
|
|
#-----------------------------------------------------------------------
|
|
# Copyright (C) 2015 SUSE Linux Products GmbH. All Rights Reserved.
|
|
# Author: Filipe Manana <fdmanana@suse.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"
|
|
|
|
here=`pwd`
|
|
tmp=/tmp/$$
|
|
status=1 # failure is the default!
|
|
|
|
_cleanup()
|
|
{
|
|
_cleanup_flakey
|
|
rm -f $tmp.*
|
|
}
|
|
trap "_cleanup; exit \$status" 0 1 2 3 15
|
|
|
|
# get standard environment, filters and checks
|
|
. ./common/rc
|
|
. ./common/filter
|
|
. ./common/dmflakey
|
|
|
|
# real QA test starts here
|
|
_supported_fs generic
|
|
_supported_os Linux
|
|
_require_scratch
|
|
_require_dm_target flakey
|
|
_require_metadata_journaling $SCRATCH_DEV
|
|
|
|
rm -f $seqres.full
|
|
|
|
_scratch_mkfs >> $seqres.full 2>&1
|
|
_init_flakey
|
|
_mount_flakey
|
|
|
|
# Create our main test file and directory.
|
|
$XFS_IO_PROG -f -c "pwrite -S 0xaa 0 8K" $SCRATCH_MNT/foo | _filter_xfs_io
|
|
mkdir $SCRATCH_MNT/mydir
|
|
|
|
# Make sure all metadata and data are durably persisted.
|
|
sync
|
|
|
|
# Add a hard link to 'foo' inside our test directory and fsync only the
|
|
# directory. The btrfs fsync implementation had a bug that caused the new
|
|
# directory entry to be visible after the fsync log replay but, the inode
|
|
# of our file remained with a link count of 1.
|
|
ln $SCRATCH_MNT/foo $SCRATCH_MNT/mydir/foo_2
|
|
|
|
# Add a few more links and new files.
|
|
# This is just to verify nothing breaks or gives incorrect results after the
|
|
# fsync log is replayed.
|
|
ln $SCRATCH_MNT/foo $SCRATCH_MNT/mydir/foo_3
|
|
$XFS_IO_PROG -f -c "pwrite -S 0xff 0 64K" $SCRATCH_MNT/hello | _filter_xfs_io
|
|
ln $SCRATCH_MNT/hello $SCRATCH_MNT/mydir/hello_2
|
|
|
|
# Add some subdirectories and new files and links to them. This is to verify
|
|
# that after fsyncing our top level directory 'mydir', all the subdirectories
|
|
# and their files/links are registered in the fsync log and exist after the
|
|
# fsync log is replayed.
|
|
mkdir -p $SCRATCH_MNT/mydir/x/y/z
|
|
ln $SCRATCH_MNT/foo $SCRATCH_MNT/mydir/x/y/foo_y_link
|
|
ln $SCRATCH_MNT/foo $SCRATCH_MNT/mydir/x/y/z/foo_z_link
|
|
touch $SCRATCH_MNT/mydir/x/y/z/qwerty
|
|
|
|
# Now fsync only our top directory.
|
|
$XFS_IO_PROG -c "fsync" $SCRATCH_MNT/mydir
|
|
|
|
# And fsync now our new file named 'hello', just to verify later that it has
|
|
# the expected content and that the previous fsync on the directory 'mydir' had
|
|
# no bad influence on this fsync.
|
|
$XFS_IO_PROG -c "fsync" $SCRATCH_MNT/hello
|
|
|
|
_flakey_drop_and_remount
|
|
|
|
# Verify the content of our file 'foo' remains the same as before, 8192 bytes,
|
|
# all with the value 0xaa.
|
|
echo "File 'foo' content after log replay:"
|
|
od -t x1 $SCRATCH_MNT/foo
|
|
|
|
# Remove the first name of our inode. Because of the directory fsync bug, the
|
|
# inode's link count was 1 instead of 5, so removing the 'foo' name ended up
|
|
# deleting the inode and the other names became stale directory entries (still
|
|
# visible to applications). Attempting to remove or access the remaining
|
|
# dentries pointing to that inode resulted in stale file handle errors and
|
|
# made it impossible to remove the parent directories since it was impossible
|
|
# for them to become empty.
|
|
echo "file 'foo' link count after log replay: $(stat -c %h $SCRATCH_MNT/foo)"
|
|
rm -f $SCRATCH_MNT/foo
|
|
|
|
# Now verify that all files, links and directories created before fsyncing our
|
|
# directory exist after the fsync log was replayed.
|
|
[ -f $SCRATCH_MNT/mydir/foo_2 ] || echo "Link mydir/foo_2 is missing"
|
|
[ -f $SCRATCH_MNT/mydir/foo_3 ] || echo "Link mydir/foo_3 is missing"
|
|
[ -f $SCRATCH_MNT/hello ] || echo "File hello is missing"
|
|
[ -f $SCRATCH_MNT/mydir/hello_2 ] || echo "Link mydir/hello_2 is missing"
|
|
[ -f $SCRATCH_MNT/mydir/x/y/foo_y_link ] || \
|
|
echo "Link mydir/x/y/foo_y_link is missing"
|
|
[ -f $SCRATCH_MNT/mydir/x/y/z/foo_z_link ] || \
|
|
echo "Link mydir/x/y/z/foo_z_link is missing"
|
|
[ -f $SCRATCH_MNT/mydir/x/y/z/qwerty ] || \
|
|
echo "File mydir/x/y/z/qwerty is missing"
|
|
|
|
# We expect our file here to have a size of 64Kb and all the bytes having the
|
|
# value 0xff.
|
|
echo "file 'hello' content after log replay:"
|
|
od -t x1 $SCRATCH_MNT/hello
|
|
|
|
# Now remove all files/links, under our test directory 'mydir', and verify we
|
|
# can remove all the directories.
|
|
rm -f $SCRATCH_MNT/mydir/x/y/z/*
|
|
rmdir $SCRATCH_MNT/mydir/x/y/z
|
|
rm -f $SCRATCH_MNT/mydir/x/y/*
|
|
rmdir $SCRATCH_MNT/mydir/x/y
|
|
rmdir $SCRATCH_MNT/mydir/x
|
|
rm -f $SCRATCH_MNT/mydir/*
|
|
rmdir $SCRATCH_MNT/mydir
|
|
|
|
# An fsck, run by the fstests framework everytime a test finishes, also detected
|
|
# the inconsistency and printed the following error message:
|
|
#
|
|
# root 5 inode 257 errors 2001, no inode item, link count wrong
|
|
# unresolved ref dir 258 index 2 namelen 5 name foo_2 filetype 1 errors 4, no inode ref
|
|
# unresolved ref dir 258 index 3 namelen 5 name foo_3 filetype 1 errors 4, no inode ref
|
|
|
|
status=0
|
|
exit
|