generic: add dir fsync test

This test is motivated by a bug found in btrfs when replaying a
directory from the fsync log. The issue was that if a directory
entry is both found in the persisted metadata and in the fsync
log, at log replay time the directory got set with a wrong i_size.
This had the consequence of not being able to rmdir empty
directories (failed with errno ENOTEMPTY).
This was fixed in btrfs with the following linux kernel patch:

     Btrfs: fix directory recovery from fsync log

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
This commit is contained in:
Filipe Manana
2014-09-29 13:26:32 +10:00
committed by Dave Chinner
parent 108634504c
commit 48c45430ce
3 changed files with 108 additions and 0 deletions
+105
View File
@@ -0,0 +1,105 @@
#! /bin/bash
# FS QA Test No. 034
#
# This test is motivated by a bug found in btrfs when replaying a directory
# from the fsync log. The issue was that if a directory entry is both found
# in the persisted metadata and in the fsync log, at log replay time the
# directory got set with a wrong i_size. This had the consequence of not being
# able to rmdir empty directories (failed with errno ENOTEMPTY).
# This was fixed in btrfs with the following linux kernel patch:
#
# Btrfs: fix directory recovery from fsync log
#
#-----------------------------------------------------------------------
# Copyright (C) 2014 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`
status=1 # failure is the default!
_cleanup()
{
_cleanup_flakey
}
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
_need_to_be_root
_require_scratch
_require_dm_flakey
rm -f $seqres.full
_scratch_mkfs >> $seqres.full 2>&1
_init_flakey
_mount_flakey
mkdir $SCRATCH_MNT/test_dir
touch $SCRATCH_MNT/test_dir/foo
# Invoke sync here because it's necessary to trigger the original bug in btrfs.
# The intention is that at log recovery time we have a dir entry for 'foo' both
# in the fs/subvol tree and in the log tree - this is necessary to trigger the
# bug on btrfs.
sync
touch $SCRATCH_MNT/test_dir/bar
$XFS_IO_PROG -c "fsync" $SCRATCH_MNT/test_dir
$XFS_IO_PROG -c "fsync" $SCRATCH_MNT/test_dir/bar
_load_flakey_table $FLAKEY_DROP_WRITES
_unmount_flakey
_load_flakey_table $FLAKEY_ALLOW_WRITES
# In the original btrfs bug, log replay would update the directory's inode
# i_size incorrectly - it would sum again the size of dentry 'foo' (3) to
# the inode's i_size, which is incorrect because the dentry was already
# persisted before (in the fs/subvol tree).
_mount_flakey
[ -f $SCRATCH_MNT/test_dir/foo ] || echo "file foo is missing"
[ -f $SCRATCH_MNT/test_dir/bar ] || echo "file bar is missing"
rm -f $SCRATCH_MNT/test_dir/foo
rm -f $SCRATCH_MNT/test_dir/bar
# In btrfs removing all entries from a directory should set the directory's
# inode i_size to 0, but with this bug that didn't happen and this made
# an rmdir fail with errno ENOTEMPTY (even though the directory had no more
# entries in it).
rmdir $SCRATCH_MNT/test_dir
[ -d $SCRATCH_MNT/test_dir ] && echo "rmdir didn't succeed"
_unmount_flakey
echo "Silence is golden"
status=0
exit
+2
View File
@@ -0,0 +1,2 @@
QA output created by 034
Silence is golden
+1
View File
@@ -36,6 +36,7 @@
031 auto quick prealloc rw
032 auto quick rw
033 auto quick rw
034 auto quick metadata log
053 acl repair auto quick
062 attr udf auto quick
068 other auto freeze dangerous stress