FS/XFS testing framework
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <djwong@kernel.org>
To: Andrea Parri <parri.andrea@gmail.com>,
	fstests@vger.kernel.org, Christoph Hellwig <hch@infradead.org>,
	linux-xfs@vger.kernel.org, Christoph Hellwig <hch@lst.de>
Subject: Re: [PATCH v2] xfs: exercise a failed CoW conversion during writeback
Date: Mon, 28 Sep 2026 08:41:49 -0700	[thread overview]
Message-ID: <20260928154149.GA6253@frogsfrogsfrogs> (raw)
In-Reply-To: <arprh9oyZEXs25CQ@zlang-mailbox>

On Mon, Sep 28, 2026 at 09:53:29PM +0800, Zorro Lang wrote:
> On Mon, Sep 28, 2026 at 10:50:46AM +0200, Andrea Parri wrote:
> > iomap_add_to_ioend() submits the pending ioend through
> > ->writeback_submit() before allocating a new one for the current
> > range.  For XFS, xfs_writeback_submit() converts the ioend's CoW
> > extents via xfs_reflink_convert_cow() before submitting the bio; if
> > that conversion fails, ->writeback_submit() completes the ioend with
> > an error and returns it.  A kernel bug left the stale ioend behind in
> > wpc->wb_ctx, which iomap_writepages() then submitted a second time,
> > corrupting XFS's ip->i_ioend_list.
> > 
> > Exercise this path with the wb_cow_convert_error error tag: reflink a
> > file, dirty several widely separated ranges of the shared extent so
> > that a single writepages() call has to build and submit more than one
> > ioend, inject the error, and let writeback run.  On a kernel without
> > the fix this reliably hits a "list_add double add" WARN from
> > xfs_end_bio(); on a fixed kernel writeback just fails cleanly.
> > 
> > This requires the wb_cow_convert_error XFS error tag; the test cleanly
> > not-runs on kernels without it.
> > 
> > Reviewed-by: Christoph Hellwig <hch@lst.de>
> > Signed-off-by: Andrea Parri <parri.andrea@gmail.com>
> > ---
> > The kernel fix and the wb_cow_convert_error error tag this test relies
> > on are part of the series at:
> > 
> >   https://lore.kernel.org/all/cover.1790342457.git.parri.andrea@gmail.com/
> > 
> > Changes since v1:
> >  - Cite the kernel fix with _fixed_by_kernel_commit (Darrick).
> >  - Don't reset the error tag before the remount; the unmount clears it
> >    anyway (Darrick).
> >  - Picked up Christoph's Reviewed-by.
> > 
> > v1: https://lore.kernel.org/all/20260924091338.198407-1-parri.andrea@gmail.com/
> 
> Overall the patch looks good to me, but I have one minor comment below ...
> 
> > 
> >  tests/xfs/842     | 71 +++++++++++++++++++++++++++++++++++++++++++++++
> >  tests/xfs/842.out |  7 +++++
> >  2 files changed, 78 insertions(+)
> >  create mode 100755 tests/xfs/842
> >  create mode 100644 tests/xfs/842.out
> > 
> > diff --git a/tests/xfs/842 b/tests/xfs/842
> > new file mode 100755
> > index 0000000000000..4495e9bdfa530
> > --- /dev/null
> > +++ b/tests/xfs/842
> > @@ -0,0 +1,71 @@
> > +#! /bin/bash
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright (c) 2026 Andrea Parri.  All Rights Reserved.
> > +#
> > +# FS QA Test No. 842
> > +#
> > +# Regression test for a failed ->writeback_submit() call leaving a stale
> > +# wpc->wb_ctx behind.  iomap_writepages() then resubmits whatever
> > +# wpc->wb_ctx points to, i.e. the ioend that ->writeback_submit() already
> > +# completed with an error.  For XFS the second bio_endio() lands back in
> > +# xfs_end_bio(), which list_add_tail()s the already-linked ioend into
> > +# ip->i_ioend_list a second time, corrupting the list.
> > +#
> > +# The only in-tree way for XFS's ->writeback_submit() to fail is a
> > +# failing xfs_reflink_convert_cow(), so this uses the
> > +# wb_cow_convert_error error tag to force that on a reflinked file whose
> > +# CoW extents are dirtied in several widely separated ranges, so that a
> > +# single writepages() call has to submit more than one ioend.
> > +#
> > +. ./common/preamble
> > +_begin_fstest auto quick clone
> > +
> > +# Import common functions.
> > +. ./common/filter
> > +. ./common/reflink
> > +. ./common/inject
> > +
> > +_fixed_by_kernel_commit XXXXXXXXXXXX \
> > +	"iomap: don't resubmit an ioend after ->writeback_submit() failed"
> > +
> > +_require_cp_reflink
> > +_require_scratch_reflink
> > +_require_xfs_io_error_injection "wb_cow_convert_error"
> > +_require_kernel_config CONFIG_LIST_HARDENED
> > +
> > +blksz=65536
> > +nr=8
> > +sz=$((blksz * nr * 2))
> > +
> > +echo "Format and mount"
> > +_scratch_mkfs >> $seqres.full 2>&1
> > +_scratch_mount
> > +
> > +echo "Create reflinked file with several CoW extents"
> > +_pwrite_byte 0x58 0 $sz $SCRATCH_MNT/file1 >> $seqres.full
> > +_scratch_sync
> > +_cp_reflink $SCRATCH_MNT/file1 $SCRATCH_MNT/file2
> > +
> > +# Dirty several widely separated ranges of file2's CoW extents so that a
> > +# single writepages() call has to submit more than one ioend.
> > +seq=0
> 
> In fstests, $seq is a core global variable representing the test sequence
> number. Overwriting it here might lead to unexpected side effects with
> framework helpers or cleanup logic. Could we rename this loop variable to
> something else to avoid trouble? If you need, I can help that when I merge
> it.
> 
> Thanks,
> Zorro
> 
> > +while [ $seq -lt $nr ]; do
> > +	off=$((seq * blksz * 2))
> > +	_pwrite_byte 0x59 $off $blksz $SCRATCH_MNT/file2 >> $seqres.full
> > +	seq=$((seq + 1))
> > +done

for ((off = 0; off < (blksz * nr * 2); off += (blksz * 2))); do
	_pwrite_byte 0x59 $off $blksz $SCRATCH_MNT/file2 >> $seqres.full
done

--D

> > +
> > +echo "Inject wb_cow_convert_error"
> > +_scratch_inject_error "wb_cow_convert_error"
> > +
> > +echo "Trigger writeback with CoW conversion forced to fail"
> > +_scratch_sync
> > +
> > +echo "Remount"
> > +_scratch_cycle_mount
> > +
> > +echo "Silence is golden"
> > +
> > +# success, all done
> > +status=0
> > +exit
> > diff --git a/tests/xfs/842.out b/tests/xfs/842.out
> > new file mode 100644
> > index 0000000000000..72c9c67e7d5fb
> > --- /dev/null
> > +++ b/tests/xfs/842.out
> > @@ -0,0 +1,7 @@
> > +QA output created by 842
> > +Format and mount
> > +Create reflinked file with several CoW extents
> > +Inject wb_cow_convert_error
> > +Trigger writeback with CoW conversion forced to fail
> > +Remount
> > +Silence is golden
> > -- 
> > 2.53.0
> > 
> 

  parent reply	other threads:[~2026-09-28 15:41 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-28  8:50 [PATCH v2] xfs: exercise a failed CoW conversion during writeback Andrea Parri
2026-09-28 13:53 ` Zorro Lang
2026-09-28 14:15   ` Andrea Parri
2026-09-28 15:41   ` Darrick J. Wong [this message]
2026-09-28 16:24     ` Andrea Parri
2026-09-28 21:47       ` Zorro Lang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260928154149.GA6253@frogsfrogsfrogs \
    --to=djwong@kernel.org \
    --cc=fstests@vger.kernel.org \
    --cc=hch@infradead.org \
    --cc=hch@lst.de \
    --cc=linux-xfs@vger.kernel.org \
    --cc=parri.andrea@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox