Re: [PATCH] xfs: test reflux with exchange-range

Zorro Lang <[email protected]>
Newsgroups org.kernel.vger.linux-xfs,org.kernel.vger.fstests
Message-ID <aolYPXE0VupxrUEO@zlang-mailbox>
On Wed, Aug 19, 2026 at 08:51:21AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <[email protected]>
> 
> Regression test for the XFS_IOC_EXCHRANGE flag INO1_WRITTEN clearing
> reflink flags when that shouldn't happen.
> 
> Signed-off-by: "Darrick J. Wong" <[email protected]>
> ---
>  tests/generic/1957     |   72 ++++++++++++++++++++++++++++++++++++++++++++++++
>  tests/generic/1957.out |   16 +++++++++++
>  2 files changed, 88 insertions(+)
>  create mode 100755 tests/generic/1957
>  create mode 100644 tests/generic/1957.out
> 
> diff --git a/tests/generic/1957 b/tests/generic/1957
> new file mode 100755
> index 00000000000000..bb039771970d15
> --- /dev/null
> +++ b/tests/generic/1957
> @@ -0,0 +1,72 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2026 Oracle.  All Rights Reserved.
> +#
> +# FS QA Test No. 1957
> +#
> +# Regression test for refluxfs, which is an exploit for a race condition in
> +# XFS' directio copy-on-write code that can be used to rewrite shared blocks
> +# to gain root privileges.
> +#
> +. ./common/preamble
> +_begin_fstest auto quick fiexchange
> +
> +_cleanup()
> +{
> +	cd /
> +	rm -r -f $tmp.*
> +	test -n "$dummydir" && rm -r -f "$dummydir"

Hmm... what's the $dummydir?

> +}
> +
> +. ./common/filter
> +. ./common/reflink
> +
> +_require_scratch_reflink
> +_require_xfs_io_command exchangerange

OK, if a filesystem supports reflink and exchange-range, it definitely
supports truncate I think.

This patch is good enough, just not sure what's that "$dummydir". With
the definition of dummydir clarified:

Reviewed-by: Zorro Lang <[email protected]>

> +_require_cp_reflink
> +
> +_fixed_by_fs_commit xfs XXXXXXXXXXXXXX \
> +	"xfs: fix exchange-range reflink flag clearing issue with  INO1_WRITTEN"
> +
> +_scratch_mkfs >> $seqres.full
> +_scratch_mount
> +
> +# Create file1 as a fully written file, and file2 as a sparse file with one
> +# written area.
> +$XFS_IO_PROG -f -c "pwrite -S 0x58 0 1m" $SCRATCH_MNT/file1 >> $seqres.full
> +$XFS_IO_PROG -f -c "truncate 1m" -c "pwrite -S 0x59 64k 64k" $SCRATCH_MNT/file2 >> $seqres.full
> +
> +_scratch_unmount
> +_scratch_xfs_db -c "path /file1" -c 'print' -c "path /file2" -c 'print' | grep reflink
> +_scratch_mount
> +
> +# Reflink file1 so that the reflink flag gets set
> +_cp_reflink $SCRATCH_MNT/file1 $SCRATCH_MNT/fileC
> +
> +md5sum $SCRATCH_MNT/file1 $SCRATCH_MNT/file2 $SCRATCH_MNT/fileC | _filter_scratch
> +
> +# Exchange the written parts of file2 with file1, but only file1 has the
> +# reflink flag set.
> +$XFS_IO_PROG -c "exchangerange -w $SCRATCH_MNT/file2" $SCRATCH_MNT/file1 >> $seqres.full
> +
> +# Check reflink flags
> +_scratch_unmount
> +_scratch_xfs_db -c "path /file1" -c 'print' -c "path /file2" -c 'print' | grep reflink
> +_scratch_mount
> +
> +# Record content and layout
> +md5sum $SCRATCH_MNT/file1 $SCRATCH_MNT/file2 $SCRATCH_MNT/fileC | _filter_scratch
> +$XFS_IO_PROG -c 'bmap -vvvvvvvv' $SCRATCH_MNT/file[12C] >> $seqres.full
> +
> +# Write a single byte to file1, does that get echoed in fileC?
> +$XFS_IO_PROG -c 'pwrite -S 0x59 0 1' $SCRATCH_MNT/file1 >> $seqres.full
> +#
> +# Check reflink flags
> +_scratch_unmount
> +_scratch_xfs_db -c "path /file1" -c 'print' -c "path /file2" -c 'print' | grep reflink
> +_scratch_mount
> +
> +md5sum $SCRATCH_MNT/file1 $SCRATCH_MNT/file2 $SCRATCH_MNT/fileC | _filter_scratch
> +$XFS_IO_PROG -c 'bmap -vvvvvvvv' $SCRATCH_MNT/file[12C] >> $seqres.full
> +
> +_exit 0
> diff --git a/tests/generic/1957.out b/tests/generic/1957.out
> new file mode 100644
> index 00000000000000..7d64ea0e2c372d
> --- /dev/null
> +++ b/tests/generic/1957.out
> @@ -0,0 +1,16 @@
> +QA output created by 1957
> +v3.reflink = 0
> +v3.reflink = 0
> +310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/file1
> +e6ee47dca6e786a44ae5b912be870d96  SCRATCH_MNT/file2
> +310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/fileC
> +v3.reflink = 1
> +v3.reflink = 1
> +b630c7de58afd0ba5b8dfa24d701b5b8  SCRATCH_MNT/file1
> +18cc9868973139a0bb558e09802a51b6  SCRATCH_MNT/file2
> +310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/fileC
> +v3.reflink = 1
> +v3.reflink = 1
> +82b27c6f1b1de8fba44a911af80d9a7a  SCRATCH_MNT/file1
> +18cc9868973139a0bb558e09802a51b6  SCRATCH_MNT/file2
> +310f146ce52077fcd3308dcbe7632bb2  SCRATCH_MNT/fileC
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.