All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eryu Guan <guaneryu@gmail.com>
To: Filipe Manana <fdmanana@kernel.org>
Cc: fstests <fstests@vger.kernel.org>,
	linux-btrfs <linux-btrfs@vger.kernel.org>,
	Filipe Manana <fdmanana@suse.com>
Subject: Re: [PATCH v2] generic: test cloning large exents to a file with many small extents
Date: Sun, 7 Jul 2019 20:41:58 +0800	[thread overview]
Message-ID: <20190707124158.GH7943@desktop> (raw)
In-Reply-To: <CAL3q7H4co58OcST+qZpB1mz_EQb=jOouDd+g+Ykmkx1dB01m0g@mail.gmail.com>

On Fri, Jul 05, 2019 at 11:09:38AM +0100, Filipe Manana wrote:
> On Fri, Jul 5, 2019 at 8:43 AM Eryu Guan <guaneryu@gmail.com> wrote:
> >
> > On Fri, Jun 28, 2019 at 11:08:36PM +0100, fdmanana@kernel.org wrote:
> > > From: Filipe Manana <fdmanana@suse.com>
> > >
> > > Test that if we clone a file with some large extents into a file that has
> > > many small extents, when the fs is nearly full, the clone operation does
> > > not fail and produces the correct result.
> > >
> > > This is motivated by a bug found in btrfs wich is fixed by the following
> > > patches for the linux kernel:
> > >
> > >  [PATCH 1/2] Btrfs: factor out extent dropping code from hole punch handler
> > >  [PATCH 2/2] Btrfs: fix ENOSPC errors, leading to transaction aborts, when
> > >              cloning extents
> > >
> > > The test currently passes on xfs.
> > >
> > > Signed-off-by: Filipe Manana <fdmanana@suse.com>
> > > ---
> > >
> > > V2: Use _scratch_cycle_mount instead of _scratch_remount, as we want to see
> > >     if the operation was durably persisted (otherwise we are seeing content
> > >     from the page cache).
> > >     Use _reflink instead of calling xfs_io with the reflink command.
> > >     Make the comment before filling the filesystem more clear about why it
> > >     is done the way it is instead of using _fill_fs.
> > >
> > >  tests/generic/558     | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++
> > >  tests/generic/558.out |  5 ++++
> > >  tests/generic/group   |  1 +
> > >  3 files changed, 86 insertions(+)
> > >  create mode 100755 tests/generic/558
> > >  create mode 100644 tests/generic/558.out
> > >
> > > diff --git a/tests/generic/558 b/tests/generic/558
> > > new file mode 100755
> > > index 00000000..f982930d
> > > --- /dev/null
> > > +++ b/tests/generic/558
> > > @@ -0,0 +1,80 @@
> > > +#! /bin/bash
> > > +# SPDX-License-Identifier: GPL-2.0
> > > +# Copyright (C) 2019 SUSE Linux Products GmbH. All Rights Reserved.
> > > +#
> > > +# FSQA Test No. 558
> > > +#
> > > +# Test that if we clone a file with some large extents into a file that has
> > > +# many small extents, when the fs is nearly full, the clone operation does
> > > +# not fail and produces the correct result.
> > > +#
> > > +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()
> > > +{
> > > +     cd /
> > > +     rm -f $tmp.*
> > > +}
> > > +
> > > +# get standard environment, filters and checks
> > > +. ./common/rc
> > > +. ./common/filter
> > > +. ./common/reflink
> > > +
> > > +# real QA test starts here
> > > +_supported_fs generic
> > > +_supported_os Linux
> > > +_require_scratch_reflink
> > > +
> > > +rm -f $seqres.full
> > > +
> > > +_scratch_mkfs_sized $((512 * 1024 * 1024)) >>$seqres.full 2>&1
> > > +_scratch_mount
> > > +
> > > +file_size=$(( 128 * 1024 * 1024 )) # 128Mb
> > > +extent_size=4096
> > > +num_extents=$(( $file_size / $extent_size ))
> > > +
> > > +# Create a file with many small extents.
> > > +for ((i = 0; i < $num_extents; i++)); do
> > > +     offset=$(( $i * $extent_size ))
> > > +     $XFS_IO_PROG -f -s -c "pwrite -S 0xe5 $offset $extent_size" \
> > > +             $SCRATCH_MNT/foo >>/dev/null
> > > +done
> >
> > This is taking too long time (1000+s) to finish when testing on XFS.
> 
> Hum, for on 5.2-rc, debug kernel (lockdep, plenty of other debug stuff
> enabled that slows things down), it takes about 350 seconds for me.
> 
> > I'm
> > wondering if we could take use of src/punch-alternating to punch out
> > every other block to create a file with many small extents.
> 
> That's fine, I didn't remember about that.
> 
> >
> > i.e. with the following diffs, test runs & passes with XFS within 90s
> > while still reproduces the btrfs bug (note that I have to increase the
> > file_size to 200M to reproduce the btrfs bug, while 256M seems bring
> > test time back to 1000+s). Would you please check if this works for you?
> 
> It does, thanks!
> And, because of the holes, it uncovered a bug in my fix (second patch).

That's great :)

> 
> Now it takes ~15 seconds on btrfs instead of ~300s and ~100s on xfs for me.

Sounds good!

> 
> >
> > Thanks,
> > Eryu
> >
> >
> > diff --git a/tests/generic/558 b/tests/generic/558
> > index f982930d65a2..40f8a7a98d3f 100755
> > --- a/tests/generic/558
> > +++ b/tests/generic/558
> > @@ -30,22 +30,22 @@ _cleanup()
> >  _supported_fs generic
> >  _supported_os Linux
> >  _require_scratch_reflink
> > +_require_test_program "punch-alternating"
> > +_require_xfs_io_command "fpunch"
> >
> >  rm -f $seqres.full
> >
> >  _scratch_mkfs_sized $((512 * 1024 * 1024)) >>$seqres.full 2>&1
> >  _scratch_mount
> >
> > -file_size=$(( 128 * 1024 * 1024 )) # 128Mb
> > +file_size=$(( 200 * 1024 * 1024 )) # 200MB
> >  extent_size=4096
> >  num_extents=$(( $file_size / $extent_size ))
> 
> These two variables, extent_size and num_extents, are no longer needed.
> 
> Do you want me to send another version of the patch or can you apply
> this patch on top of it?

I can fix the patch on commit. Thanks for the confirmation!

Eryu

> 
> Thanks.
> 
> >
> >  # Create a file with many small extents.
> > -for ((i = 0; i < $num_extents; i++)); do
> > -       offset=$(( $i * $extent_size ))
> > -       $XFS_IO_PROG -f -s -c "pwrite -S 0xe5 $offset $extent_size" \
> > -               $SCRATCH_MNT/foo >>/dev/null
> > -done
> > +$XFS_IO_PROG -f -c "pwrite -S 0xe5 -b $file_size 0 $file_size" \
> > +       $SCRATCH_MNT/foo >>/dev/null
> > +$here/src/punch-alternating $SCRATCH_MNT/foo >> $seqres.full
> >
> >  # Create file bar with the same size that file foo has but with large extents.
> >  $XFS_IO_PROG -f -c "pwrite -S 0xc7 -b $file_size 0 $file_size" \
> > diff --git a/tests/generic/558.out b/tests/generic/558.out
> > index d1e8e70f5b79..00cb5a9744aa 100644
> > --- a/tests/generic/558.out
> > +++ b/tests/generic/558.out
> > @@ -2,4 +2,4 @@ QA output created by 558
> >  File foo data after cloning and remount:
> >  0000000 c7 c7 c7 c7 c7 c7 c7 c7 c7 c7 c7 c7 c7 c7 c7 c7
> >  *
> > -134217728
> > +209715200
> >
> > > +
> > > +# Create file bar with the same size that file foo has but with large extents.
> > > +$XFS_IO_PROG -f -c "pwrite -S 0xc7 -b $file_size 0 $file_size" \
> > > +     $SCRATCH_MNT/bar >>/dev/null
> > > +
> > > +# Fill the fs (For btrfs we are interested in filling all unallocated space
> > > +# and most of the existing metadata block group(s), so that after this there
> > > +# will be no unallocated space and metadata space will be mostly full but with
> > > +# more than enough free space for the clone operation below to succeed, we
> > > +# create files with 2Kb because that results in extents inlined in the metadata
> > > +# (btree leafs) and it's the fastest way to fill metadata space on btrfs, by
> > > +# default btrfs inlines up to 2Kb of data).
> > > +i=1
> > > +while true; do
> > > +     $XFS_IO_PROG -f -c "pwrite 0 2K" $SCRATCH_MNT/filler_$i &> /dev/null
> > > +     [ $? -ne 0 ] && break
> > > +     i=$(( i + 1 ))
> > > +done
> > > +
> > > +# Now clone file bar into file foo. This is supposed to succeed and not fail
> > > +# with ENOSPC for example.
> > > +_reflink $SCRATCH_MNT/bar $SCRATCH_MNT/foo >>$seqres.full
> > > +
> > > +# Unmount and mount the filesystem again to verify the operation was durably
> > > +# persisted.
> > > +_scratch_cycle_mount
> > > +
> > > +echo "File foo data after cloning and remount:"
> > > +od -A d -t x1 $SCRATCH_MNT/foo
> > > +
> > > +status=0
> > > +exit
> > > diff --git a/tests/generic/558.out b/tests/generic/558.out
> > > new file mode 100644
> > > index 00000000..d1e8e70f
> > > --- /dev/null
> > > +++ b/tests/generic/558.out
> > > @@ -0,0 +1,5 @@
> > > +QA output created by 558
> > > +File foo data after cloning and remount:
> > > +0000000 c7 c7 c7 c7 c7 c7 c7 c7 c7 c7 c7 c7 c7 c7 c7 c7
> > > +*
> > > +134217728
> > > diff --git a/tests/generic/group b/tests/generic/group
> > > index 543c0627..c06c1cd1 100644
> > > --- a/tests/generic/group
> > > +++ b/tests/generic/group
> > > @@ -560,3 +560,4 @@
> > >  555 auto quick cap
> > >  556 auto quick casefold
> > >  557 auto quick log
> > > +558 auto clone
> > > --
> > > 2.11.0
> > >

      reply	other threads:[~2019-07-07 12:42 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-27 17:00 [PATCH] generic: test cloning large exents to a file with many small extents fdmanana
2019-06-27 20:28 ` Darrick J. Wong
2019-06-27 21:47   ` Filipe Manana
2019-06-28  3:32     ` Darrick J. Wong
2019-06-28 22:08 ` [PATCH v2] " fdmanana
2019-07-05  7:43   ` Eryu Guan
2019-07-05 10:09     ` Filipe Manana
2019-07-07 12:41       ` Eryu Guan [this message]

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=20190707124158.GH7943@desktop \
    --to=guaneryu@gmail.com \
    --cc=fdmanana@kernel.org \
    --cc=fdmanana@suse.com \
    --cc=fstests@vger.kernel.org \
    --cc=linux-btrfs@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.