diff mbox series

[1/8,v2] fstests: Add Log Attribute Replay test

Message ID 20220603014112.GO227878@dread.disaster.area (mailing list archive)
State New, archived
Headers show
Series [1/8,v2] fstests: Add Log Attribute Replay test | expand

Commit Message

Dave Chinner June 3, 2022, 1:41 a.m. UTC
From: Allison Henderson <allison.henderson@oracle.com>

This patch adds tests to exercise the log attribute error
inject and log replay. These tests aim to cover cases where attributes
are added, removed, and overwritten in each format (shortform, leaf,
node). Error inject is used to replay these operations from the log.

dchinner: sanitise md5sum input to just attr values.
dchinner: correct md5sums.
dchinner: ensure replace tests use different values so recovery can
          determine the replace was replayed correctly.
dchinner: don't remove corpse in _cleanup - scratch devices don't
	  require cleanup, and if the test fails we want to leave
	  the broken state for post-mortem analysis.
dchinner: only run on v5 filesystems.

Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
V2:
- redirected attr get failure messages to /dev/null rather than
  have to filter them. The md5sum tells us that the attr didn't
  exist.

 tests/xfs/600     | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/xfs/600.out | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 347 insertions(+)

Comments

Darrick J. Wong June 3, 2022, 2:43 a.m. UTC | #1
On Fri, Jun 03, 2022 at 11:41:12AM +1000, Dave Chinner wrote:
> From: Allison Henderson <allison.henderson@oracle.com>
> 
> This patch adds tests to exercise the log attribute error
> inject and log replay. These tests aim to cover cases where attributes
> are added, removed, and overwritten in each format (shortform, leaf,
> node). Error inject is used to replay these operations from the log.
> 
> dchinner: sanitise md5sum input to just attr values.
> dchinner: correct md5sums.
> dchinner: ensure replace tests use different values so recovery can
>           determine the replace was replayed correctly.
> dchinner: don't remove corpse in _cleanup - scratch devices don't
> 	  require cleanup, and if the test fails we want to leave
> 	  the broken state for post-mortem analysis.
> dchinner: only run on v5 filesystems.
> 
> Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
> Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
> Signed-off-by: Dave Chinner <dchinner@redhat.com>
> ---
> V2:
> - redirected attr get failure messages to /dev/null rather than
>   have to filter them. The md5sum tells us that the attr didn't
>   exist.
> 
>  tests/xfs/600     | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  tests/xfs/600.out | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 347 insertions(+)
> 
> diff --git a/tests/xfs/600 b/tests/xfs/600
> new file mode 100755
> index 00000000..bc9415ec
> --- /dev/null
> +++ b/tests/xfs/600
> @@ -0,0 +1,179 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2022, Oracle and/or its affiliates.  All Rights Reserved.
> +#
> +# FS QA Test 600
> +#
> +# Log attribute replay test
> +#
> +. ./common/preamble
> +_begin_fstest auto quick attr
> +
> +# get standard environment, filters and checks
> +. ./common/filter
> +. ./common/attr
> +. ./common/inject
> +
> +_cleanup()
> +{
> +	rm -rf $tmp.*
> +	test -w /sys/fs/xfs/debug/larp && \
> +		echo 0 > /sys/fs/xfs/debug/larp

Probably ought to restore the old value, but otherwise the logic in here
looks solid enough.

Reviewed-by: Darrick J. Wong <djwong@kernel.org>

--D

> +}
> +
> +test_attr_replay()
> +{
> +	testfile=$testdir/$1
> +	attr_name=$2
> +	attr_value=$3
> +	flag=$4
> +	error_tag=$5
> +
> +	# Inject error
> +	_scratch_inject_error $error_tag
> +
> +	# Set attribute
> +	echo "$attr_value" | ${ATTR_PROG} -$flag "$attr_name" $testfile 2>&1 | \
> +			    _filter_scratch
> +
> +	# FS should be shut down, touch will fail
> +	touch $testfile 2>&1 | _filter_scratch
> +
> +	# Remount to replay log
> +	_scratch_remount_dump_log >> $seqres.full
> +
> +	# FS should be online, touch should succeed
> +	touch $testfile
> +
> +	# Verify attr recovery
> +	$ATTR_PROG -l $testfile | _filter_scratch
> +	echo -n "$attr_name: "
> +	$ATTR_PROG -q -g $attr_name $testfile 2> /dev/null | md5sum;
> +
> +	echo ""
> +}
> +
> +create_test_file()
> +{
> +	filename=$testdir/$1
> +	count=$2
> +	attr_value=$3
> +
> +	touch $filename
> +
> +	for i in `seq $count`
> +	do
> +		$ATTR_PROG -s "attr_name$i" -V $attr_value $filename >> \
> +			$seqres.full
> +	done
> +}
> +
> +# real QA test starts here
> +_supported_fs xfs
> +
> +_require_scratch
> +_require_scratch_xfs_crc
> +_require_attrs
> +_require_xfs_io_error_injection "larp"
> +_require_xfs_io_error_injection "da_leaf_split"
> +_require_xfs_io_error_injection "attr_leaf_to_node"
> +_require_xfs_sysfs debug/larp
> +test -w /sys/fs/xfs/debug/larp || _notrun "larp knob not writable"
> +
> +# turn on log attributes
> +echo 1 > /sys/fs/xfs/debug/larp
> +
> +attr16="0123456789ABCDEF"
> +attr64="$attr16$attr16$attr16$attr16"
> +attr256="$attr64$attr64$attr64$attr64"
> +attr1k="$attr256$attr256$attr256$attr256"
> +attr4k="$attr1k$attr1k$attr1k$attr1k"
> +attr8k="$attr4k$attr4k"
> +attr16k="$attr8k$attr8k"
> +attr32k="$attr16k$attr16k"
> +attr64k="$attr32k$attr32k"
> +
> +echo "*** mkfs"
> +_scratch_mkfs >/dev/null
> +
> +echo "*** mount FS"
> +_scratch_mount
> +
> +testdir=$SCRATCH_MNT/testdir
> +mkdir $testdir
> +
> +# empty, inline
> +create_test_file empty_file1 0
> +test_attr_replay empty_file1 "attr_name" $attr64 "s" "larp"
> +test_attr_replay empty_file1 "attr_name" $attr64 "r" "larp"
> +
> +# empty, internal
> +create_test_file empty_file2 0
> +test_attr_replay empty_file2 "attr_name" $attr1k "s" "larp"
> +test_attr_replay empty_file2 "attr_name" $attr1k "r" "larp"
> +
> +# empty, remote
> +create_test_file empty_file3 0
> +test_attr_replay empty_file3 "attr_name" $attr64k "s" "larp"
> +test_attr_replay empty_file3 "attr_name" $attr64k "r" "larp"
> +
> +# inline, inline
> +create_test_file inline_file1 1 $attr16
> +test_attr_replay inline_file1 "attr_name2" $attr64 "s" "larp"
> +test_attr_replay inline_file1 "attr_name2" $attr64 "r" "larp"
> +
> +# inline, internal
> +create_test_file inline_file2 1 $attr16
> +test_attr_replay inline_file2 "attr_name2" $attr1k "s" "larp"
> +test_attr_replay inline_file2 "attr_name2" $attr1k "r" "larp"
> +
> +# inline, remote
> +create_test_file inline_file3 1 $attr16
> +test_attr_replay inline_file3 "attr_name2" $attr64k "s" "larp"
> +test_attr_replay inline_file3 "attr_name2" $attr64k "r" "larp"
> +
> +# extent, internal
> +create_test_file extent_file1 1 $attr1k
> +test_attr_replay extent_file1 "attr_name2" $attr1k "s" "larp"
> +test_attr_replay extent_file1 "attr_name2" $attr1k "r" "larp"
> +
> +# extent, inject error on split
> +create_test_file extent_file2 3 $attr1k
> +test_attr_replay extent_file2 "attr_name4" $attr1k "s" "da_leaf_split"
> +
> +# extent, inject error on fork transition
> +create_test_file extent_file3 3 $attr1k
> +test_attr_replay extent_file3 "attr_name4" $attr1k "s" "attr_leaf_to_node"
> +
> +# extent, remote
> +create_test_file extent_file4 1 $attr1k
> +test_attr_replay extent_file4 "attr_name2" $attr64k "s" "larp"
> +test_attr_replay extent_file4 "attr_name2" $attr64k "r" "larp"
> +
> +# remote, internal
> +create_test_file remote_file1 1 $attr64k
> +test_attr_replay remote_file1 "attr_name2" $attr1k "s" "larp"
> +test_attr_replay remote_file1 "attr_name2" $attr1k "r" "larp"
> +
> +# remote, remote
> +create_test_file remote_file2 1 $attr64k
> +test_attr_replay remote_file2 "attr_name2" $attr64k "s" "larp"
> +test_attr_replay remote_file2 "attr_name2" $attr64k "r" "larp"
> +
> +# replace shortform with different value
> +create_test_file sf_file 2 $attr64
> +test_attr_replay sf_file "attr_name2" $attr16 "s" "larp"
> +
> +# replace leaf with different value
> +create_test_file leaf_file 3 $attr1k
> +test_attr_replay leaf_file "attr_name2" $attr256 "s" "larp"
> +
> +# replace node with a different value
> +create_test_file node_file 1 $attr64k
> +$ATTR_PROG -s "attr_name2" -V $attr1k $testdir/node_file \
> +		>> $seqres.full
> +test_attr_replay node_file "attr_name2" $attr256 "s" "larp"
> +
> +echo "*** done"
> +status=0
> +exit
> diff --git a/tests/xfs/600.out b/tests/xfs/600.out
> new file mode 100644
> index 00000000..259b05ee
> --- /dev/null
> +++ b/tests/xfs/600.out
> @@ -0,0 +1,168 @@
> +QA output created by 600
> +*** mkfs
> +*** mount FS
> +attr_set: Input/output error
> +Could not set "attr_name" for SCRATCH_MNT/testdir/empty_file1
> +touch: cannot touch 'SCRATCH_MNT/testdir/empty_file1': Input/output error
> +Attribute "attr_name" has a 65 byte value for SCRATCH_MNT/testdir/empty_file1
> +attr_name: cfbe2a33be4601d2b655d099a18378fc  -
> +
> +attr_remove: Input/output error
> +Could not remove "attr_name" for SCRATCH_MNT/testdir/empty_file1
> +touch: cannot touch 'SCRATCH_MNT/testdir/empty_file1': Input/output error
> +attr_name: d41d8cd98f00b204e9800998ecf8427e  -
> +
> +attr_set: Input/output error
> +Could not set "attr_name" for SCRATCH_MNT/testdir/empty_file2
> +touch: cannot touch 'SCRATCH_MNT/testdir/empty_file2': Input/output error
> +Attribute "attr_name" has a 1025 byte value for SCRATCH_MNT/testdir/empty_file2
> +attr_name: 9fd415c49d67afc4b78fad4055a3a376  -
> +
> +attr_remove: Input/output error
> +Could not remove "attr_name" for SCRATCH_MNT/testdir/empty_file2
> +touch: cannot touch 'SCRATCH_MNT/testdir/empty_file2': Input/output error
> +attr_name: d41d8cd98f00b204e9800998ecf8427e  -
> +
> +attr_set: Input/output error
> +Could not set "attr_name" for SCRATCH_MNT/testdir/empty_file3
> +touch: cannot touch 'SCRATCH_MNT/testdir/empty_file3': Input/output error
> +Attribute "attr_name" has a 65536 byte value for SCRATCH_MNT/testdir/empty_file3
> +attr_name: 7f6fd1b6d872108bd44bd143cbcdfa19  -
> +
> +attr_remove: Input/output error
> +Could not remove "attr_name" for SCRATCH_MNT/testdir/empty_file3
> +touch: cannot touch 'SCRATCH_MNT/testdir/empty_file3': Input/output error
> +attr_name: d41d8cd98f00b204e9800998ecf8427e  -
> +
> +attr_set: Input/output error
> +Could not set "attr_name2" for SCRATCH_MNT/testdir/inline_file1
> +touch: cannot touch 'SCRATCH_MNT/testdir/inline_file1': Input/output error
> +Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file1
> +Attribute "attr_name2" has a 65 byte value for SCRATCH_MNT/testdir/inline_file1
> +attr_name2: cfbe2a33be4601d2b655d099a18378fc  -
> +
> +attr_remove: Input/output error
> +Could not remove "attr_name2" for SCRATCH_MNT/testdir/inline_file1
> +touch: cannot touch 'SCRATCH_MNT/testdir/inline_file1': Input/output error
> +Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file1
> +attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
> +
> +attr_set: Input/output error
> +Could not set "attr_name2" for SCRATCH_MNT/testdir/inline_file2
> +touch: cannot touch 'SCRATCH_MNT/testdir/inline_file2': Input/output error
> +Attribute "attr_name2" has a 1025 byte value for SCRATCH_MNT/testdir/inline_file2
> +Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file2
> +attr_name2: 9fd415c49d67afc4b78fad4055a3a376  -
> +
> +attr_remove: Input/output error
> +Could not remove "attr_name2" for SCRATCH_MNT/testdir/inline_file2
> +touch: cannot touch 'SCRATCH_MNT/testdir/inline_file2': Input/output error
> +Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file2
> +attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
> +
> +attr_set: Input/output error
> +Could not set "attr_name2" for SCRATCH_MNT/testdir/inline_file3
> +touch: cannot touch 'SCRATCH_MNT/testdir/inline_file3': Input/output error
> +Attribute "attr_name2" has a 65536 byte value for SCRATCH_MNT/testdir/inline_file3
> +Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file3
> +attr_name2: 7f6fd1b6d872108bd44bd143cbcdfa19  -
> +
> +attr_remove: Input/output error
> +Could not remove "attr_name2" for SCRATCH_MNT/testdir/inline_file3
> +touch: cannot touch 'SCRATCH_MNT/testdir/inline_file3': Input/output error
> +Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file3
> +attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
> +
> +attr_set: Input/output error
> +Could not set "attr_name2" for SCRATCH_MNT/testdir/extent_file1
> +touch: cannot touch 'SCRATCH_MNT/testdir/extent_file1': Input/output error
> +Attribute "attr_name2" has a 1025 byte value for SCRATCH_MNT/testdir/extent_file1
> +Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file1
> +attr_name2: 9fd415c49d67afc4b78fad4055a3a376  -
> +
> +attr_remove: Input/output error
> +Could not remove "attr_name2" for SCRATCH_MNT/testdir/extent_file1
> +touch: cannot touch 'SCRATCH_MNT/testdir/extent_file1': Input/output error
> +Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file1
> +attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
> +
> +attr_set: Input/output error
> +Could not set "attr_name4" for SCRATCH_MNT/testdir/extent_file2
> +touch: cannot touch 'SCRATCH_MNT/testdir/extent_file2': Input/output error
> +Attribute "attr_name4" has a 1025 byte value for SCRATCH_MNT/testdir/extent_file2
> +Attribute "attr_name2" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file2
> +Attribute "attr_name3" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file2
> +Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file2
> +attr_name4: 9fd415c49d67afc4b78fad4055a3a376  -
> +
> +attr_set: Input/output error
> +Could not set "attr_name4" for SCRATCH_MNT/testdir/extent_file3
> +touch: cannot touch 'SCRATCH_MNT/testdir/extent_file3': Input/output error
> +Attribute "attr_name4" has a 1025 byte value for SCRATCH_MNT/testdir/extent_file3
> +Attribute "attr_name2" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file3
> +Attribute "attr_name3" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file3
> +Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file3
> +attr_name4: 9fd415c49d67afc4b78fad4055a3a376  -
> +
> +attr_set: Input/output error
> +Could not set "attr_name2" for SCRATCH_MNT/testdir/extent_file4
> +touch: cannot touch 'SCRATCH_MNT/testdir/extent_file4': Input/output error
> +Attribute "attr_name2" has a 65536 byte value for SCRATCH_MNT/testdir/extent_file4
> +Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file4
> +attr_name2: 7f6fd1b6d872108bd44bd143cbcdfa19  -
> +
> +attr_remove: Input/output error
> +Could not remove "attr_name2" for SCRATCH_MNT/testdir/extent_file4
> +touch: cannot touch 'SCRATCH_MNT/testdir/extent_file4': Input/output error
> +Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file4
> +attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
> +
> +attr_set: Input/output error
> +Could not set "attr_name2" for SCRATCH_MNT/testdir/remote_file1
> +touch: cannot touch 'SCRATCH_MNT/testdir/remote_file1': Input/output error
> +Attribute "attr_name2" has a 1025 byte value for SCRATCH_MNT/testdir/remote_file1
> +Attribute "attr_name1" has a 65536 byte value for SCRATCH_MNT/testdir/remote_file1
> +attr_name2: 9fd415c49d67afc4b78fad4055a3a376  -
> +
> +attr_remove: Input/output error
> +Could not remove "attr_name2" for SCRATCH_MNT/testdir/remote_file1
> +touch: cannot touch 'SCRATCH_MNT/testdir/remote_file1': Input/output error
> +Attribute "attr_name1" has a 65536 byte value for SCRATCH_MNT/testdir/remote_file1
> +attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
> +
> +attr_set: Input/output error
> +Could not set "attr_name2" for SCRATCH_MNT/testdir/remote_file2
> +touch: cannot touch 'SCRATCH_MNT/testdir/remote_file2': Input/output error
> +Attribute "attr_name2" has a 65536 byte value for SCRATCH_MNT/testdir/remote_file2
> +Attribute "attr_name1" has a 65536 byte value for SCRATCH_MNT/testdir/remote_file2
> +attr_name2: 7f6fd1b6d872108bd44bd143cbcdfa19  -
> +
> +attr_remove: Input/output error
> +Could not remove "attr_name2" for SCRATCH_MNT/testdir/remote_file2
> +touch: cannot touch 'SCRATCH_MNT/testdir/remote_file2': Input/output error
> +Attribute "attr_name1" has a 65536 byte value for SCRATCH_MNT/testdir/remote_file2
> +attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
> +
> +attr_set: Input/output error
> +Could not set "attr_name2" for SCRATCH_MNT/testdir/sf_file
> +touch: cannot touch 'SCRATCH_MNT/testdir/sf_file': Input/output error
> +Attribute "attr_name1" has a 64 byte value for SCRATCH_MNT/testdir/sf_file
> +Attribute "attr_name2" has a 17 byte value for SCRATCH_MNT/testdir/sf_file
> +attr_name2: 9a6eb1bc9da3c66a9b495dfe2fe8a756  -
> +
> +attr_set: Input/output error
> +Could not set "attr_name2" for SCRATCH_MNT/testdir/leaf_file
> +touch: cannot touch 'SCRATCH_MNT/testdir/leaf_file': Input/output error
> +Attribute "attr_name2" has a 257 byte value for SCRATCH_MNT/testdir/leaf_file
> +Attribute "attr_name3" has a 1024 byte value for SCRATCH_MNT/testdir/leaf_file
> +Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/leaf_file
> +attr_name2: f4ea5799d72a0a9bf2d56a685c9cba7a  -
> +
> +attr_set: Input/output error
> +Could not set "attr_name2" for SCRATCH_MNT/testdir/node_file
> +touch: cannot touch 'SCRATCH_MNT/testdir/node_file': Input/output error
> +Attribute "attr_name2" has a 257 byte value for SCRATCH_MNT/testdir/node_file
> +Attribute "attr_name1" has a 65536 byte value for SCRATCH_MNT/testdir/node_file
> +attr_name2: f4ea5799d72a0a9bf2d56a685c9cba7a  -
> +
> +*** done
> -- 
> Dave Chinner
> david@fromorbit.com
Zorro Lang June 3, 2022, 4:55 a.m. UTC | #2
On Thu, Jun 02, 2022 at 07:43:21PM -0700, Darrick J. Wong wrote:
> On Fri, Jun 03, 2022 at 11:41:12AM +1000, Dave Chinner wrote:
> > From: Allison Henderson <allison.henderson@oracle.com>
> > 
> > This patch adds tests to exercise the log attribute error
> > inject and log replay. These tests aim to cover cases where attributes
> > are added, removed, and overwritten in each format (shortform, leaf,
> > node). Error inject is used to replay these operations from the log.
> > 
> > dchinner: sanitise md5sum input to just attr values.
> > dchinner: correct md5sums.
> > dchinner: ensure replace tests use different values so recovery can
> >           determine the replace was replayed correctly.
> > dchinner: don't remove corpse in _cleanup - scratch devices don't
> > 	  require cleanup, and if the test fails we want to leave
> > 	  the broken state for post-mortem analysis.
> > dchinner: only run on v5 filesystems.
> > 
> > Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
> > Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
> > Signed-off-by: Dave Chinner <dchinner@redhat.com>
> > ---
> > V2:
> > - redirected attr get failure messages to /dev/null rather than
> >   have to filter them. The md5sum tells us that the attr didn't
> >   exist.
> > 
> >  tests/xfs/600     | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  tests/xfs/600.out | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 347 insertions(+)
> > 
> > diff --git a/tests/xfs/600 b/tests/xfs/600
> > new file mode 100755
> > index 00000000..bc9415ec
> > --- /dev/null
> > +++ b/tests/xfs/600
> > @@ -0,0 +1,179 @@
> > +#! /bin/bash
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright (c) 2022, Oracle and/or its affiliates.  All Rights Reserved.
> > +#
> > +# FS QA Test 600
> > +#
> > +# Log attribute replay test
> > +#
> > +. ./common/preamble
> > +_begin_fstest auto quick attr
> > +
> > +# get standard environment, filters and checks
> > +. ./common/filter
> > +. ./common/attr
> > +. ./common/inject
> > +
> > +_cleanup()
> > +{
> > +	rm -rf $tmp.*
> > +	test -w /sys/fs/xfs/debug/larp && \
> > +		echo 0 > /sys/fs/xfs/debug/larp
> 
> Probably ought to restore the old value, but otherwise the logic in here
> looks solid enough.

I can help that when I merge it this week.

BTW, I saw the "[PATCH 00/15] xfs: Log Attribute Replay" patchset has been
merged by mainline linux. So I suspose it's time to merge this patch. Please
tell me if it's still not the time. As I know there's not only one patchset
is related with this.

And I'll really appreciate that, if any of you would like to list all related
patchset titles (from kernel and userspace) to help this case test pass :)

Thanks,
Zorro

> 
> Reviewed-by: Darrick J. Wong <djwong@kernel.org>
> 
> --D
> 
> > +}
> > +
> > +test_attr_replay()
> > +{
> > +	testfile=$testdir/$1
> > +	attr_name=$2
> > +	attr_value=$3
> > +	flag=$4
> > +	error_tag=$5
> > +
> > +	# Inject error
> > +	_scratch_inject_error $error_tag
> > +
> > +	# Set attribute
> > +	echo "$attr_value" | ${ATTR_PROG} -$flag "$attr_name" $testfile 2>&1 | \
> > +			    _filter_scratch
> > +
> > +	# FS should be shut down, touch will fail
> > +	touch $testfile 2>&1 | _filter_scratch
> > +
> > +	# Remount to replay log
> > +	_scratch_remount_dump_log >> $seqres.full
> > +
> > +	# FS should be online, touch should succeed
> > +	touch $testfile
> > +
> > +	# Verify attr recovery
> > +	$ATTR_PROG -l $testfile | _filter_scratch
> > +	echo -n "$attr_name: "
> > +	$ATTR_PROG -q -g $attr_name $testfile 2> /dev/null | md5sum;
> > +
> > +	echo ""
> > +}
> > +
> > +create_test_file()
> > +{
> > +	filename=$testdir/$1
> > +	count=$2
> > +	attr_value=$3
> > +
> > +	touch $filename
> > +
> > +	for i in `seq $count`
> > +	do
> > +		$ATTR_PROG -s "attr_name$i" -V $attr_value $filename >> \
> > +			$seqres.full
> > +	done
> > +}
> > +
> > +# real QA test starts here
> > +_supported_fs xfs
> > +
> > +_require_scratch
> > +_require_scratch_xfs_crc
> > +_require_attrs
> > +_require_xfs_io_error_injection "larp"
> > +_require_xfs_io_error_injection "da_leaf_split"
> > +_require_xfs_io_error_injection "attr_leaf_to_node"
> > +_require_xfs_sysfs debug/larp
> > +test -w /sys/fs/xfs/debug/larp || _notrun "larp knob not writable"
> > +
> > +# turn on log attributes
> > +echo 1 > /sys/fs/xfs/debug/larp
> > +
> > +attr16="0123456789ABCDEF"
> > +attr64="$attr16$attr16$attr16$attr16"
> > +attr256="$attr64$attr64$attr64$attr64"
> > +attr1k="$attr256$attr256$attr256$attr256"
> > +attr4k="$attr1k$attr1k$attr1k$attr1k"
> > +attr8k="$attr4k$attr4k"
> > +attr16k="$attr8k$attr8k"
> > +attr32k="$attr16k$attr16k"
> > +attr64k="$attr32k$attr32k"
> > +
> > +echo "*** mkfs"
> > +_scratch_mkfs >/dev/null
> > +
> > +echo "*** mount FS"
> > +_scratch_mount
> > +
> > +testdir=$SCRATCH_MNT/testdir
> > +mkdir $testdir
> > +
> > +# empty, inline
> > +create_test_file empty_file1 0
> > +test_attr_replay empty_file1 "attr_name" $attr64 "s" "larp"
> > +test_attr_replay empty_file1 "attr_name" $attr64 "r" "larp"
> > +
> > +# empty, internal
> > +create_test_file empty_file2 0
> > +test_attr_replay empty_file2 "attr_name" $attr1k "s" "larp"
> > +test_attr_replay empty_file2 "attr_name" $attr1k "r" "larp"
> > +
> > +# empty, remote
> > +create_test_file empty_file3 0
> > +test_attr_replay empty_file3 "attr_name" $attr64k "s" "larp"
> > +test_attr_replay empty_file3 "attr_name" $attr64k "r" "larp"
> > +
> > +# inline, inline
> > +create_test_file inline_file1 1 $attr16
> > +test_attr_replay inline_file1 "attr_name2" $attr64 "s" "larp"
> > +test_attr_replay inline_file1 "attr_name2" $attr64 "r" "larp"
> > +
> > +# inline, internal
> > +create_test_file inline_file2 1 $attr16
> > +test_attr_replay inline_file2 "attr_name2" $attr1k "s" "larp"
> > +test_attr_replay inline_file2 "attr_name2" $attr1k "r" "larp"
> > +
> > +# inline, remote
> > +create_test_file inline_file3 1 $attr16
> > +test_attr_replay inline_file3 "attr_name2" $attr64k "s" "larp"
> > +test_attr_replay inline_file3 "attr_name2" $attr64k "r" "larp"
> > +
> > +# extent, internal
> > +create_test_file extent_file1 1 $attr1k
> > +test_attr_replay extent_file1 "attr_name2" $attr1k "s" "larp"
> > +test_attr_replay extent_file1 "attr_name2" $attr1k "r" "larp"
> > +
> > +# extent, inject error on split
> > +create_test_file extent_file2 3 $attr1k
> > +test_attr_replay extent_file2 "attr_name4" $attr1k "s" "da_leaf_split"
> > +
> > +# extent, inject error on fork transition
> > +create_test_file extent_file3 3 $attr1k
> > +test_attr_replay extent_file3 "attr_name4" $attr1k "s" "attr_leaf_to_node"
> > +
> > +# extent, remote
> > +create_test_file extent_file4 1 $attr1k
> > +test_attr_replay extent_file4 "attr_name2" $attr64k "s" "larp"
> > +test_attr_replay extent_file4 "attr_name2" $attr64k "r" "larp"
> > +
> > +# remote, internal
> > +create_test_file remote_file1 1 $attr64k
> > +test_attr_replay remote_file1 "attr_name2" $attr1k "s" "larp"
> > +test_attr_replay remote_file1 "attr_name2" $attr1k "r" "larp"
> > +
> > +# remote, remote
> > +create_test_file remote_file2 1 $attr64k
> > +test_attr_replay remote_file2 "attr_name2" $attr64k "s" "larp"
> > +test_attr_replay remote_file2 "attr_name2" $attr64k "r" "larp"
> > +
> > +# replace shortform with different value
> > +create_test_file sf_file 2 $attr64
> > +test_attr_replay sf_file "attr_name2" $attr16 "s" "larp"
> > +
> > +# replace leaf with different value
> > +create_test_file leaf_file 3 $attr1k
> > +test_attr_replay leaf_file "attr_name2" $attr256 "s" "larp"
> > +
> > +# replace node with a different value
> > +create_test_file node_file 1 $attr64k
> > +$ATTR_PROG -s "attr_name2" -V $attr1k $testdir/node_file \
> > +		>> $seqres.full
> > +test_attr_replay node_file "attr_name2" $attr256 "s" "larp"
> > +
> > +echo "*** done"
> > +status=0
> > +exit
> > diff --git a/tests/xfs/600.out b/tests/xfs/600.out
> > new file mode 100644
> > index 00000000..259b05ee
> > --- /dev/null
> > +++ b/tests/xfs/600.out
> > @@ -0,0 +1,168 @@
> > +QA output created by 600
> > +*** mkfs
> > +*** mount FS
> > +attr_set: Input/output error
> > +Could not set "attr_name" for SCRATCH_MNT/testdir/empty_file1
> > +touch: cannot touch 'SCRATCH_MNT/testdir/empty_file1': Input/output error
> > +Attribute "attr_name" has a 65 byte value for SCRATCH_MNT/testdir/empty_file1
> > +attr_name: cfbe2a33be4601d2b655d099a18378fc  -
> > +
> > +attr_remove: Input/output error
> > +Could not remove "attr_name" for SCRATCH_MNT/testdir/empty_file1
> > +touch: cannot touch 'SCRATCH_MNT/testdir/empty_file1': Input/output error
> > +attr_name: d41d8cd98f00b204e9800998ecf8427e  -
> > +
> > +attr_set: Input/output error
> > +Could not set "attr_name" for SCRATCH_MNT/testdir/empty_file2
> > +touch: cannot touch 'SCRATCH_MNT/testdir/empty_file2': Input/output error
> > +Attribute "attr_name" has a 1025 byte value for SCRATCH_MNT/testdir/empty_file2
> > +attr_name: 9fd415c49d67afc4b78fad4055a3a376  -
> > +
> > +attr_remove: Input/output error
> > +Could not remove "attr_name" for SCRATCH_MNT/testdir/empty_file2
> > +touch: cannot touch 'SCRATCH_MNT/testdir/empty_file2': Input/output error
> > +attr_name: d41d8cd98f00b204e9800998ecf8427e  -
> > +
> > +attr_set: Input/output error
> > +Could not set "attr_name" for SCRATCH_MNT/testdir/empty_file3
> > +touch: cannot touch 'SCRATCH_MNT/testdir/empty_file3': Input/output error
> > +Attribute "attr_name" has a 65536 byte value for SCRATCH_MNT/testdir/empty_file3
> > +attr_name: 7f6fd1b6d872108bd44bd143cbcdfa19  -
> > +
> > +attr_remove: Input/output error
> > +Could not remove "attr_name" for SCRATCH_MNT/testdir/empty_file3
> > +touch: cannot touch 'SCRATCH_MNT/testdir/empty_file3': Input/output error
> > +attr_name: d41d8cd98f00b204e9800998ecf8427e  -
> > +
> > +attr_set: Input/output error
> > +Could not set "attr_name2" for SCRATCH_MNT/testdir/inline_file1
> > +touch: cannot touch 'SCRATCH_MNT/testdir/inline_file1': Input/output error
> > +Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file1
> > +Attribute "attr_name2" has a 65 byte value for SCRATCH_MNT/testdir/inline_file1
> > +attr_name2: cfbe2a33be4601d2b655d099a18378fc  -
> > +
> > +attr_remove: Input/output error
> > +Could not remove "attr_name2" for SCRATCH_MNT/testdir/inline_file1
> > +touch: cannot touch 'SCRATCH_MNT/testdir/inline_file1': Input/output error
> > +Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file1
> > +attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
> > +
> > +attr_set: Input/output error
> > +Could not set "attr_name2" for SCRATCH_MNT/testdir/inline_file2
> > +touch: cannot touch 'SCRATCH_MNT/testdir/inline_file2': Input/output error
> > +Attribute "attr_name2" has a 1025 byte value for SCRATCH_MNT/testdir/inline_file2
> > +Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file2
> > +attr_name2: 9fd415c49d67afc4b78fad4055a3a376  -
> > +
> > +attr_remove: Input/output error
> > +Could not remove "attr_name2" for SCRATCH_MNT/testdir/inline_file2
> > +touch: cannot touch 'SCRATCH_MNT/testdir/inline_file2': Input/output error
> > +Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file2
> > +attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
> > +
> > +attr_set: Input/output error
> > +Could not set "attr_name2" for SCRATCH_MNT/testdir/inline_file3
> > +touch: cannot touch 'SCRATCH_MNT/testdir/inline_file3': Input/output error
> > +Attribute "attr_name2" has a 65536 byte value for SCRATCH_MNT/testdir/inline_file3
> > +Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file3
> > +attr_name2: 7f6fd1b6d872108bd44bd143cbcdfa19  -
> > +
> > +attr_remove: Input/output error
> > +Could not remove "attr_name2" for SCRATCH_MNT/testdir/inline_file3
> > +touch: cannot touch 'SCRATCH_MNT/testdir/inline_file3': Input/output error
> > +Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file3
> > +attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
> > +
> > +attr_set: Input/output error
> > +Could not set "attr_name2" for SCRATCH_MNT/testdir/extent_file1
> > +touch: cannot touch 'SCRATCH_MNT/testdir/extent_file1': Input/output error
> > +Attribute "attr_name2" has a 1025 byte value for SCRATCH_MNT/testdir/extent_file1
> > +Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file1
> > +attr_name2: 9fd415c49d67afc4b78fad4055a3a376  -
> > +
> > +attr_remove: Input/output error
> > +Could not remove "attr_name2" for SCRATCH_MNT/testdir/extent_file1
> > +touch: cannot touch 'SCRATCH_MNT/testdir/extent_file1': Input/output error
> > +Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file1
> > +attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
> > +
> > +attr_set: Input/output error
> > +Could not set "attr_name4" for SCRATCH_MNT/testdir/extent_file2
> > +touch: cannot touch 'SCRATCH_MNT/testdir/extent_file2': Input/output error
> > +Attribute "attr_name4" has a 1025 byte value for SCRATCH_MNT/testdir/extent_file2
> > +Attribute "attr_name2" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file2
> > +Attribute "attr_name3" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file2
> > +Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file2
> > +attr_name4: 9fd415c49d67afc4b78fad4055a3a376  -
> > +
> > +attr_set: Input/output error
> > +Could not set "attr_name4" for SCRATCH_MNT/testdir/extent_file3
> > +touch: cannot touch 'SCRATCH_MNT/testdir/extent_file3': Input/output error
> > +Attribute "attr_name4" has a 1025 byte value for SCRATCH_MNT/testdir/extent_file3
> > +Attribute "attr_name2" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file3
> > +Attribute "attr_name3" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file3
> > +Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file3
> > +attr_name4: 9fd415c49d67afc4b78fad4055a3a376  -
> > +
> > +attr_set: Input/output error
> > +Could not set "attr_name2" for SCRATCH_MNT/testdir/extent_file4
> > +touch: cannot touch 'SCRATCH_MNT/testdir/extent_file4': Input/output error
> > +Attribute "attr_name2" has a 65536 byte value for SCRATCH_MNT/testdir/extent_file4
> > +Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file4
> > +attr_name2: 7f6fd1b6d872108bd44bd143cbcdfa19  -
> > +
> > +attr_remove: Input/output error
> > +Could not remove "attr_name2" for SCRATCH_MNT/testdir/extent_file4
> > +touch: cannot touch 'SCRATCH_MNT/testdir/extent_file4': Input/output error
> > +Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file4
> > +attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
> > +
> > +attr_set: Input/output error
> > +Could not set "attr_name2" for SCRATCH_MNT/testdir/remote_file1
> > +touch: cannot touch 'SCRATCH_MNT/testdir/remote_file1': Input/output error
> > +Attribute "attr_name2" has a 1025 byte value for SCRATCH_MNT/testdir/remote_file1
> > +Attribute "attr_name1" has a 65536 byte value for SCRATCH_MNT/testdir/remote_file1
> > +attr_name2: 9fd415c49d67afc4b78fad4055a3a376  -
> > +
> > +attr_remove: Input/output error
> > +Could not remove "attr_name2" for SCRATCH_MNT/testdir/remote_file1
> > +touch: cannot touch 'SCRATCH_MNT/testdir/remote_file1': Input/output error
> > +Attribute "attr_name1" has a 65536 byte value for SCRATCH_MNT/testdir/remote_file1
> > +attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
> > +
> > +attr_set: Input/output error
> > +Could not set "attr_name2" for SCRATCH_MNT/testdir/remote_file2
> > +touch: cannot touch 'SCRATCH_MNT/testdir/remote_file2': Input/output error
> > +Attribute "attr_name2" has a 65536 byte value for SCRATCH_MNT/testdir/remote_file2
> > +Attribute "attr_name1" has a 65536 byte value for SCRATCH_MNT/testdir/remote_file2
> > +attr_name2: 7f6fd1b6d872108bd44bd143cbcdfa19  -
> > +
> > +attr_remove: Input/output error
> > +Could not remove "attr_name2" for SCRATCH_MNT/testdir/remote_file2
> > +touch: cannot touch 'SCRATCH_MNT/testdir/remote_file2': Input/output error
> > +Attribute "attr_name1" has a 65536 byte value for SCRATCH_MNT/testdir/remote_file2
> > +attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
> > +
> > +attr_set: Input/output error
> > +Could not set "attr_name2" for SCRATCH_MNT/testdir/sf_file
> > +touch: cannot touch 'SCRATCH_MNT/testdir/sf_file': Input/output error
> > +Attribute "attr_name1" has a 64 byte value for SCRATCH_MNT/testdir/sf_file
> > +Attribute "attr_name2" has a 17 byte value for SCRATCH_MNT/testdir/sf_file
> > +attr_name2: 9a6eb1bc9da3c66a9b495dfe2fe8a756  -
> > +
> > +attr_set: Input/output error
> > +Could not set "attr_name2" for SCRATCH_MNT/testdir/leaf_file
> > +touch: cannot touch 'SCRATCH_MNT/testdir/leaf_file': Input/output error
> > +Attribute "attr_name2" has a 257 byte value for SCRATCH_MNT/testdir/leaf_file
> > +Attribute "attr_name3" has a 1024 byte value for SCRATCH_MNT/testdir/leaf_file
> > +Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/leaf_file
> > +attr_name2: f4ea5799d72a0a9bf2d56a685c9cba7a  -
> > +
> > +attr_set: Input/output error
> > +Could not set "attr_name2" for SCRATCH_MNT/testdir/node_file
> > +touch: cannot touch 'SCRATCH_MNT/testdir/node_file': Input/output error
> > +Attribute "attr_name2" has a 257 byte value for SCRATCH_MNT/testdir/node_file
> > +Attribute "attr_name1" has a 65536 byte value for SCRATCH_MNT/testdir/node_file
> > +attr_name2: f4ea5799d72a0a9bf2d56a685c9cba7a  -
> > +
> > +*** done
> > -- 
> > Dave Chinner
> > david@fromorbit.com
>
Dave Chinner June 3, 2022, 5:29 a.m. UTC | #3
On Fri, Jun 03, 2022 at 12:55:04PM +0800, Zorro Lang wrote:
> On Thu, Jun 02, 2022 at 07:43:21PM -0700, Darrick J. Wong wrote:
> > On Fri, Jun 03, 2022 at 11:41:12AM +1000, Dave Chinner wrote:
> > > From: Allison Henderson <allison.henderson@oracle.com>
> > > 
> > > This patch adds tests to exercise the log attribute error
> > > inject and log replay. These tests aim to cover cases where attributes
> > > are added, removed, and overwritten in each format (shortform, leaf,
> > > node). Error inject is used to replay these operations from the log.
> > > 
> > > dchinner: sanitise md5sum input to just attr values.
> > > dchinner: correct md5sums.
> > > dchinner: ensure replace tests use different values so recovery can
> > >           determine the replace was replayed correctly.
> > > dchinner: don't remove corpse in _cleanup - scratch devices don't
> > > 	  require cleanup, and if the test fails we want to leave
> > > 	  the broken state for post-mortem analysis.
> > > dchinner: only run on v5 filesystems.
> > > 
> > > Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
> > > Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
> > > Signed-off-by: Dave Chinner <dchinner@redhat.com>
> > > ---
> > > V2:
> > > - redirected attr get failure messages to /dev/null rather than
> > >   have to filter them. The md5sum tells us that the attr didn't
> > >   exist.
> > > 
> > >  tests/xfs/600     | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> > >  tests/xfs/600.out | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++
> > >  2 files changed, 347 insertions(+)
> > > 
> > > diff --git a/tests/xfs/600 b/tests/xfs/600
> > > new file mode 100755
> > > index 00000000..bc9415ec
> > > --- /dev/null
> > > +++ b/tests/xfs/600
> > > @@ -0,0 +1,179 @@
> > > +#! /bin/bash
> > > +# SPDX-License-Identifier: GPL-2.0
> > > +# Copyright (c) 2022, Oracle and/or its affiliates.  All Rights Reserved.
> > > +#
> > > +# FS QA Test 600
> > > +#
> > > +# Log attribute replay test
> > > +#
> > > +. ./common/preamble
> > > +_begin_fstest auto quick attr
> > > +
> > > +# get standard environment, filters and checks
> > > +. ./common/filter
> > > +. ./common/attr
> > > +. ./common/inject
> > > +
> > > +_cleanup()
> > > +{
> > > +	rm -rf $tmp.*
> > > +	test -w /sys/fs/xfs/debug/larp && \
> > > +		echo 0 > /sys/fs/xfs/debug/larp
> > 
> > Probably ought to restore the old value, but otherwise the logic in here
> > looks solid enough.
> 
> I can help that when I merge it this week.
> 
> BTW, I saw the "[PATCH 00/15] xfs: Log Attribute Replay" patchset has been
> merged by mainline linux. So I suspose it's time to merge this patch. Please
> tell me if it's still not the time. As I know there's not only one patchset
> is related with this.

I wanted it merged two weeks ago because we merged LARP into the XFS
for-next tree a month ago. We need tests merged when the changes go
into the for-next tree, not when the for-next tree gets merged into
Linus's tree weeks later....

> And I'll really appreciate that, if any of you would like to list all related
> patchset titles (from kernel and userspace) to help this case test pass :)

I'm not going to attempt to find the 6 or 7 patchset and list them.
They are all merged into 5.19, so use that kernel. For userspace,
use the libxfs-5.19-sync branch I pushed out earlier in the week:

https://lore.kernel.org/linux-xfs/20220601010636.GC227878@dread.disaster.area/T/#u

That contains all the 5.19 kernel changes and the userspace support
for large extent counters and LARP, including all the error
injection stuff that the various tests use.

Cheers,

Dave.
diff mbox series

Patch

diff --git a/tests/xfs/600 b/tests/xfs/600
new file mode 100755
index 00000000..bc9415ec
--- /dev/null
+++ b/tests/xfs/600
@@ -0,0 +1,179 @@ 
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2022, Oracle and/or its affiliates.  All Rights Reserved.
+#
+# FS QA Test 600
+#
+# Log attribute replay test
+#
+. ./common/preamble
+_begin_fstest auto quick attr
+
+# get standard environment, filters and checks
+. ./common/filter
+. ./common/attr
+. ./common/inject
+
+_cleanup()
+{
+	rm -rf $tmp.*
+	test -w /sys/fs/xfs/debug/larp && \
+		echo 0 > /sys/fs/xfs/debug/larp
+}
+
+test_attr_replay()
+{
+	testfile=$testdir/$1
+	attr_name=$2
+	attr_value=$3
+	flag=$4
+	error_tag=$5
+
+	# Inject error
+	_scratch_inject_error $error_tag
+
+	# Set attribute
+	echo "$attr_value" | ${ATTR_PROG} -$flag "$attr_name" $testfile 2>&1 | \
+			    _filter_scratch
+
+	# FS should be shut down, touch will fail
+	touch $testfile 2>&1 | _filter_scratch
+
+	# Remount to replay log
+	_scratch_remount_dump_log >> $seqres.full
+
+	# FS should be online, touch should succeed
+	touch $testfile
+
+	# Verify attr recovery
+	$ATTR_PROG -l $testfile | _filter_scratch
+	echo -n "$attr_name: "
+	$ATTR_PROG -q -g $attr_name $testfile 2> /dev/null | md5sum;
+
+	echo ""
+}
+
+create_test_file()
+{
+	filename=$testdir/$1
+	count=$2
+	attr_value=$3
+
+	touch $filename
+
+	for i in `seq $count`
+	do
+		$ATTR_PROG -s "attr_name$i" -V $attr_value $filename >> \
+			$seqres.full
+	done
+}
+
+# real QA test starts here
+_supported_fs xfs
+
+_require_scratch
+_require_scratch_xfs_crc
+_require_attrs
+_require_xfs_io_error_injection "larp"
+_require_xfs_io_error_injection "da_leaf_split"
+_require_xfs_io_error_injection "attr_leaf_to_node"
+_require_xfs_sysfs debug/larp
+test -w /sys/fs/xfs/debug/larp || _notrun "larp knob not writable"
+
+# turn on log attributes
+echo 1 > /sys/fs/xfs/debug/larp
+
+attr16="0123456789ABCDEF"
+attr64="$attr16$attr16$attr16$attr16"
+attr256="$attr64$attr64$attr64$attr64"
+attr1k="$attr256$attr256$attr256$attr256"
+attr4k="$attr1k$attr1k$attr1k$attr1k"
+attr8k="$attr4k$attr4k"
+attr16k="$attr8k$attr8k"
+attr32k="$attr16k$attr16k"
+attr64k="$attr32k$attr32k"
+
+echo "*** mkfs"
+_scratch_mkfs >/dev/null
+
+echo "*** mount FS"
+_scratch_mount
+
+testdir=$SCRATCH_MNT/testdir
+mkdir $testdir
+
+# empty, inline
+create_test_file empty_file1 0
+test_attr_replay empty_file1 "attr_name" $attr64 "s" "larp"
+test_attr_replay empty_file1 "attr_name" $attr64 "r" "larp"
+
+# empty, internal
+create_test_file empty_file2 0
+test_attr_replay empty_file2 "attr_name" $attr1k "s" "larp"
+test_attr_replay empty_file2 "attr_name" $attr1k "r" "larp"
+
+# empty, remote
+create_test_file empty_file3 0
+test_attr_replay empty_file3 "attr_name" $attr64k "s" "larp"
+test_attr_replay empty_file3 "attr_name" $attr64k "r" "larp"
+
+# inline, inline
+create_test_file inline_file1 1 $attr16
+test_attr_replay inline_file1 "attr_name2" $attr64 "s" "larp"
+test_attr_replay inline_file1 "attr_name2" $attr64 "r" "larp"
+
+# inline, internal
+create_test_file inline_file2 1 $attr16
+test_attr_replay inline_file2 "attr_name2" $attr1k "s" "larp"
+test_attr_replay inline_file2 "attr_name2" $attr1k "r" "larp"
+
+# inline, remote
+create_test_file inline_file3 1 $attr16
+test_attr_replay inline_file3 "attr_name2" $attr64k "s" "larp"
+test_attr_replay inline_file3 "attr_name2" $attr64k "r" "larp"
+
+# extent, internal
+create_test_file extent_file1 1 $attr1k
+test_attr_replay extent_file1 "attr_name2" $attr1k "s" "larp"
+test_attr_replay extent_file1 "attr_name2" $attr1k "r" "larp"
+
+# extent, inject error on split
+create_test_file extent_file2 3 $attr1k
+test_attr_replay extent_file2 "attr_name4" $attr1k "s" "da_leaf_split"
+
+# extent, inject error on fork transition
+create_test_file extent_file3 3 $attr1k
+test_attr_replay extent_file3 "attr_name4" $attr1k "s" "attr_leaf_to_node"
+
+# extent, remote
+create_test_file extent_file4 1 $attr1k
+test_attr_replay extent_file4 "attr_name2" $attr64k "s" "larp"
+test_attr_replay extent_file4 "attr_name2" $attr64k "r" "larp"
+
+# remote, internal
+create_test_file remote_file1 1 $attr64k
+test_attr_replay remote_file1 "attr_name2" $attr1k "s" "larp"
+test_attr_replay remote_file1 "attr_name2" $attr1k "r" "larp"
+
+# remote, remote
+create_test_file remote_file2 1 $attr64k
+test_attr_replay remote_file2 "attr_name2" $attr64k "s" "larp"
+test_attr_replay remote_file2 "attr_name2" $attr64k "r" "larp"
+
+# replace shortform with different value
+create_test_file sf_file 2 $attr64
+test_attr_replay sf_file "attr_name2" $attr16 "s" "larp"
+
+# replace leaf with different value
+create_test_file leaf_file 3 $attr1k
+test_attr_replay leaf_file "attr_name2" $attr256 "s" "larp"
+
+# replace node with a different value
+create_test_file node_file 1 $attr64k
+$ATTR_PROG -s "attr_name2" -V $attr1k $testdir/node_file \
+		>> $seqres.full
+test_attr_replay node_file "attr_name2" $attr256 "s" "larp"
+
+echo "*** done"
+status=0
+exit
diff --git a/tests/xfs/600.out b/tests/xfs/600.out
new file mode 100644
index 00000000..259b05ee
--- /dev/null
+++ b/tests/xfs/600.out
@@ -0,0 +1,168 @@ 
+QA output created by 600
+*** mkfs
+*** mount FS
+attr_set: Input/output error
+Could not set "attr_name" for SCRATCH_MNT/testdir/empty_file1
+touch: cannot touch 'SCRATCH_MNT/testdir/empty_file1': Input/output error
+Attribute "attr_name" has a 65 byte value for SCRATCH_MNT/testdir/empty_file1
+attr_name: cfbe2a33be4601d2b655d099a18378fc  -
+
+attr_remove: Input/output error
+Could not remove "attr_name" for SCRATCH_MNT/testdir/empty_file1
+touch: cannot touch 'SCRATCH_MNT/testdir/empty_file1': Input/output error
+attr_name: d41d8cd98f00b204e9800998ecf8427e  -
+
+attr_set: Input/output error
+Could not set "attr_name" for SCRATCH_MNT/testdir/empty_file2
+touch: cannot touch 'SCRATCH_MNT/testdir/empty_file2': Input/output error
+Attribute "attr_name" has a 1025 byte value for SCRATCH_MNT/testdir/empty_file2
+attr_name: 9fd415c49d67afc4b78fad4055a3a376  -
+
+attr_remove: Input/output error
+Could not remove "attr_name" for SCRATCH_MNT/testdir/empty_file2
+touch: cannot touch 'SCRATCH_MNT/testdir/empty_file2': Input/output error
+attr_name: d41d8cd98f00b204e9800998ecf8427e  -
+
+attr_set: Input/output error
+Could not set "attr_name" for SCRATCH_MNT/testdir/empty_file3
+touch: cannot touch 'SCRATCH_MNT/testdir/empty_file3': Input/output error
+Attribute "attr_name" has a 65536 byte value for SCRATCH_MNT/testdir/empty_file3
+attr_name: 7f6fd1b6d872108bd44bd143cbcdfa19  -
+
+attr_remove: Input/output error
+Could not remove "attr_name" for SCRATCH_MNT/testdir/empty_file3
+touch: cannot touch 'SCRATCH_MNT/testdir/empty_file3': Input/output error
+attr_name: d41d8cd98f00b204e9800998ecf8427e  -
+
+attr_set: Input/output error
+Could not set "attr_name2" for SCRATCH_MNT/testdir/inline_file1
+touch: cannot touch 'SCRATCH_MNT/testdir/inline_file1': Input/output error
+Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file1
+Attribute "attr_name2" has a 65 byte value for SCRATCH_MNT/testdir/inline_file1
+attr_name2: cfbe2a33be4601d2b655d099a18378fc  -
+
+attr_remove: Input/output error
+Could not remove "attr_name2" for SCRATCH_MNT/testdir/inline_file1
+touch: cannot touch 'SCRATCH_MNT/testdir/inline_file1': Input/output error
+Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file1
+attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
+
+attr_set: Input/output error
+Could not set "attr_name2" for SCRATCH_MNT/testdir/inline_file2
+touch: cannot touch 'SCRATCH_MNT/testdir/inline_file2': Input/output error
+Attribute "attr_name2" has a 1025 byte value for SCRATCH_MNT/testdir/inline_file2
+Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file2
+attr_name2: 9fd415c49d67afc4b78fad4055a3a376  -
+
+attr_remove: Input/output error
+Could not remove "attr_name2" for SCRATCH_MNT/testdir/inline_file2
+touch: cannot touch 'SCRATCH_MNT/testdir/inline_file2': Input/output error
+Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file2
+attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
+
+attr_set: Input/output error
+Could not set "attr_name2" for SCRATCH_MNT/testdir/inline_file3
+touch: cannot touch 'SCRATCH_MNT/testdir/inline_file3': Input/output error
+Attribute "attr_name2" has a 65536 byte value for SCRATCH_MNT/testdir/inline_file3
+Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file3
+attr_name2: 7f6fd1b6d872108bd44bd143cbcdfa19  -
+
+attr_remove: Input/output error
+Could not remove "attr_name2" for SCRATCH_MNT/testdir/inline_file3
+touch: cannot touch 'SCRATCH_MNT/testdir/inline_file3': Input/output error
+Attribute "attr_name1" has a 16 byte value for SCRATCH_MNT/testdir/inline_file3
+attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
+
+attr_set: Input/output error
+Could not set "attr_name2" for SCRATCH_MNT/testdir/extent_file1
+touch: cannot touch 'SCRATCH_MNT/testdir/extent_file1': Input/output error
+Attribute "attr_name2" has a 1025 byte value for SCRATCH_MNT/testdir/extent_file1
+Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file1
+attr_name2: 9fd415c49d67afc4b78fad4055a3a376  -
+
+attr_remove: Input/output error
+Could not remove "attr_name2" for SCRATCH_MNT/testdir/extent_file1
+touch: cannot touch 'SCRATCH_MNT/testdir/extent_file1': Input/output error
+Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file1
+attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
+
+attr_set: Input/output error
+Could not set "attr_name4" for SCRATCH_MNT/testdir/extent_file2
+touch: cannot touch 'SCRATCH_MNT/testdir/extent_file2': Input/output error
+Attribute "attr_name4" has a 1025 byte value for SCRATCH_MNT/testdir/extent_file2
+Attribute "attr_name2" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file2
+Attribute "attr_name3" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file2
+Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file2
+attr_name4: 9fd415c49d67afc4b78fad4055a3a376  -
+
+attr_set: Input/output error
+Could not set "attr_name4" for SCRATCH_MNT/testdir/extent_file3
+touch: cannot touch 'SCRATCH_MNT/testdir/extent_file3': Input/output error
+Attribute "attr_name4" has a 1025 byte value for SCRATCH_MNT/testdir/extent_file3
+Attribute "attr_name2" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file3
+Attribute "attr_name3" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file3
+Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file3
+attr_name4: 9fd415c49d67afc4b78fad4055a3a376  -
+
+attr_set: Input/output error
+Could not set "attr_name2" for SCRATCH_MNT/testdir/extent_file4
+touch: cannot touch 'SCRATCH_MNT/testdir/extent_file4': Input/output error
+Attribute "attr_name2" has a 65536 byte value for SCRATCH_MNT/testdir/extent_file4
+Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file4
+attr_name2: 7f6fd1b6d872108bd44bd143cbcdfa19  -
+
+attr_remove: Input/output error
+Could not remove "attr_name2" for SCRATCH_MNT/testdir/extent_file4
+touch: cannot touch 'SCRATCH_MNT/testdir/extent_file4': Input/output error
+Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/extent_file4
+attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
+
+attr_set: Input/output error
+Could not set "attr_name2" for SCRATCH_MNT/testdir/remote_file1
+touch: cannot touch 'SCRATCH_MNT/testdir/remote_file1': Input/output error
+Attribute "attr_name2" has a 1025 byte value for SCRATCH_MNT/testdir/remote_file1
+Attribute "attr_name1" has a 65536 byte value for SCRATCH_MNT/testdir/remote_file1
+attr_name2: 9fd415c49d67afc4b78fad4055a3a376  -
+
+attr_remove: Input/output error
+Could not remove "attr_name2" for SCRATCH_MNT/testdir/remote_file1
+touch: cannot touch 'SCRATCH_MNT/testdir/remote_file1': Input/output error
+Attribute "attr_name1" has a 65536 byte value for SCRATCH_MNT/testdir/remote_file1
+attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
+
+attr_set: Input/output error
+Could not set "attr_name2" for SCRATCH_MNT/testdir/remote_file2
+touch: cannot touch 'SCRATCH_MNT/testdir/remote_file2': Input/output error
+Attribute "attr_name2" has a 65536 byte value for SCRATCH_MNT/testdir/remote_file2
+Attribute "attr_name1" has a 65536 byte value for SCRATCH_MNT/testdir/remote_file2
+attr_name2: 7f6fd1b6d872108bd44bd143cbcdfa19  -
+
+attr_remove: Input/output error
+Could not remove "attr_name2" for SCRATCH_MNT/testdir/remote_file2
+touch: cannot touch 'SCRATCH_MNT/testdir/remote_file2': Input/output error
+Attribute "attr_name1" has a 65536 byte value for SCRATCH_MNT/testdir/remote_file2
+attr_name2: d41d8cd98f00b204e9800998ecf8427e  -
+
+attr_set: Input/output error
+Could not set "attr_name2" for SCRATCH_MNT/testdir/sf_file
+touch: cannot touch 'SCRATCH_MNT/testdir/sf_file': Input/output error
+Attribute "attr_name1" has a 64 byte value for SCRATCH_MNT/testdir/sf_file
+Attribute "attr_name2" has a 17 byte value for SCRATCH_MNT/testdir/sf_file
+attr_name2: 9a6eb1bc9da3c66a9b495dfe2fe8a756  -
+
+attr_set: Input/output error
+Could not set "attr_name2" for SCRATCH_MNT/testdir/leaf_file
+touch: cannot touch 'SCRATCH_MNT/testdir/leaf_file': Input/output error
+Attribute "attr_name2" has a 257 byte value for SCRATCH_MNT/testdir/leaf_file
+Attribute "attr_name3" has a 1024 byte value for SCRATCH_MNT/testdir/leaf_file
+Attribute "attr_name1" has a 1024 byte value for SCRATCH_MNT/testdir/leaf_file
+attr_name2: f4ea5799d72a0a9bf2d56a685c9cba7a  -
+
+attr_set: Input/output error
+Could not set "attr_name2" for SCRATCH_MNT/testdir/node_file
+touch: cannot touch 'SCRATCH_MNT/testdir/node_file': Input/output error
+Attribute "attr_name2" has a 257 byte value for SCRATCH_MNT/testdir/node_file
+Attribute "attr_name1" has a 65536 byte value for SCRATCH_MNT/testdir/node_file
+attr_name2: f4ea5799d72a0a9bf2d56a685c9cba7a  -
+
+*** done