reflink: ensure that we can handle reflinking a lot of extents
[xfstests-dev.git] / tests / generic / 037
1 #! /bin/bash
2 # FSQA Test No. 037
3 #
4 # Verify that replacing a xattr's value is an atomic operation.
5 # This is motivated by an issue in btrfs where replacing a xattr's value
6 # wasn't an atomic operation, it consisted of removing the old value and
7 # then inserting the new value in a btree. This made readers (getxattr
8 # and listxattrs) not getting neither the old nor the new value during
9 # a short time window.
10 #
11 # The btrfs issue was fixed by the following linux kernel patch:
12 #
13 #    Btrfs: make xattr replace operations atomic
14 #
15 #-----------------------------------------------------------------------
16 #
17 # Copyright (C) 2014 SUSE Linux Products GmbH. All Rights Reserved.
18 # Author: Filipe Manana <fdmanana@suse.com>
19 #
20 # This program is free software; you can redistribute it and/or
21 # modify it under the terms of the GNU General Public License as
22 # published by the Free Software Foundation.
23 #
24 # This program is distributed in the hope that it would be useful,
25 # but WITHOUT ANY WARRANTY; without even the implied warranty of
26 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27 # GNU General Public License for more details.
28 #
29 # You should have received a copy of the GNU General Public License
30 # along with this program; if not, write the Free Software Foundation,
31 # Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
32 #-----------------------------------------------------------------------
33 #
34
35 seq=`basename $0`
36 seqres=$RESULT_DIR/$seq
37 echo "QA output created by $seq"
38 tmp=/tmp/$$
39 status=1        # failure is the default!
40 trap "_cleanup; exit \$status" 0 1 2 3 15
41
42 _cleanup()
43 {
44         kill $setter_pid
45         rm -f $tmp.*
46 }
47
48 # get standard environment, filters and checks
49 . ./common/rc
50 . ./common/filter
51 . ./common/attr
52
53 # real QA test starts here
54 _need_to_be_root
55 _supported_fs generic
56 _supported_os Linux
57 _require_scratch
58 _require_attrs
59
60 rm -f $seqres.full
61
62 xattr_name="user.something"
63 xattr_value1="foobar"
64 xattr_value2="rabbit_hole"
65
66 set_xattr_loop()
67 {
68         local name=$1
69         local cur_val=$xattr_value1
70         while true; do
71                 $SETFATTR_PROG -n $xattr_name -v $cur_val $SCRATCH_MNT/$name
72                 if [ "$cur_val" == "$xattr_value1" ]; then
73                         cur_val=$xattr_value2
74                 else
75                         cur_val=$xattr_value1
76                 fi
77         done
78 }
79
80 value_filter()
81 {
82         grep "$xattr_name=" | cut -d '=' -f 2 | \
83                 sed -e "s/$xattr_value1/GOOD/" -e "s/$xattr_value2/GOOD/"
84 }
85
86 _scratch_mkfs >>$seqres.full 2>&1
87 _scratch_mount
88
89 test_file="test_xattr_replace"
90 touch $SCRATCH_MNT/$test_file
91 $SETFATTR_PROG -n $xattr_name -v $xattr_value1 $SCRATCH_MNT/$test_file
92
93 set_xattr_loop $test_file &
94 setter_pid=$!
95
96 for ((i = 0; i < 1000; i++)); do
97         $GETFATTR_PROG --absolute-names -n $xattr_name \
98                 $SCRATCH_MNT/$test_file | value_filter
99 done
100
101 status=0
102 exit