generic: add test to verify xattr replace operations are atomic

This test verifies that replacing a xattr's value is an atomic
operation. This is motivated by an issue in btrfs where replacing
a xattr's value wasn't an atomic operation, it consisted of
removing the old value and then inserting the new value in a
btree. This made readers (getxattr and listxattrs) not getting
neither the old nor the new value during a short time window.

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-11-10 18:06:23 +11:00
committed by Dave Chinner
parent e62dbeae4b
commit 66769056ba
3 changed files with 1104 additions and 0 deletions
+102
View File
@@ -0,0 +1,102 @@
#! /bin/bash
# FSQA Test No. 037
#
# Verify that replacing a xattr's value is an atomic operation.
# This is motivated by an issue in btrfs where replacing a xattr's value
# wasn't an atomic operation, it consisted of removing the old value and
# then inserting the new value in a btree. This made readers (getxattr
# and listxattrs) not getting neither the old nor the new value during
# a short time window.
#
# The btrfs issue was fixed by the following linux kernel patch:
#
# Btrfs: make xattr replace operations atomic
#
#-----------------------------------------------------------------------
#
# 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"
tmp=/tmp/$$
status=1 # failure is the default!
trap "_cleanup; exit \$status" 0 1 2 3 15
_cleanup()
{
kill $setter_pid
rm -f $tmp.*
}
# get standard environment, filters and checks
. ./common/rc
. ./common/filter
. ./common/attr
# real QA test starts here
_need_to_be_root
_supported_fs generic
_supported_os Linux
_require_scratch
_require_attrs
rm -f $seqres.full
xattr_name="user.something"
xattr_value1="foobar"
xattr_value2="rabbit_hole"
set_xattr_loop()
{
local name=$1
local cur_val=$xattr_value1
while true; do
$SETFATTR_PROG -n $xattr_name -v $cur_val $SCRATCH_MNT/$name
if [ "$cur_val" == "$xattr_value1" ]; then
cur_val=$xattr_value2
else
cur_val=$xattr_value1
fi
done
}
value_filter()
{
grep "$xattr_name=" | cut -d '=' -f 2 | \
sed -e "s/$xattr_value1/GOOD/" -e "s/$xattr_value2/GOOD/"
}
_scratch_mkfs >>$seqres.full 2>&1
_scratch_mount
test_file="test_xattr_replace"
touch $SCRATCH_MNT/$test_file
$SETFATTR_PROG -n $xattr_name -v $xattr_value1 $SCRATCH_MNT/$test_file
set_xattr_loop $test_file &
setter_pid=$!
for ((i = 0; i < 1000; i++)); do
$GETFATTR_PROG --absolute-names -n $xattr_name \
$SCRATCH_MNT/$test_file | value_filter
done
status=0
exit
File diff suppressed because it is too large Load Diff
+1
View File
@@ -39,6 +39,7 @@
034 auto quick metadata log
035 auto quick
036 auto aio rw stress
037 metadata auto quick
053 acl repair auto quick
062 attr udf auto quick
068 other auto freeze dangerous stress