public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
* Bug when attempting to active swap file that used to be cloned/shared
@ 2024-12-11 14:49 Filipe Manana
  2024-12-11 18:24 ` Darrick J. Wong
  0 siblings, 1 reply; 3+ messages in thread
From: Filipe Manana @ 2024-12-11 14:49 UTC (permalink / raw)
  To: xfs; +Cc: linux-btrfs

Hello,

While looking at a btrfs bug where we fail to active a swap file that
used to have shared extents, I noticed xfs has the same bug, however
the test fails intermittently, suggesting some sort of race.

The test is this:

root 11:03:31 /home/fdmanana/scripts/btrfs-bugs > cat swap-all-tests.sh
#!/bin/bash

DEV=/dev/sdi
MNT=/mnt/sdi
NUM_CLONES=50

run_test()
{
    local sync_after_add_reflinks=$1
    local sync_after_remove_reflinks=$2

   # mkfs.btrfs -f $DEV > /dev/null
   mkfs.xfs -f $DEV > /dev/null
   mount $DEV $MNT

   touch $MNT/foo
   chmod 0600 $MNT/foo
   # On btrfs the file must be NOCOW.
   chattr +C $MNT/foo &> /dev/null
   xfs_io -s -c "pwrite -b 1M 0 1M" $MNT/foo
   mkswap $MNT/foo

   for ((i = 1; i <= $NUM_CLONES; i++)); do
       touch $MNT/foo_clone_$i
       chmod 0600 $MNT/foo_clone_$i
      # On btrfs the file must be NOCOW.
      chattr +C $MNT/foo_clone_$i &> /dev/null
      cp --reflink=always $MNT/foo $MNT/foo_clone_$i
   done

   if [ $sync_after_add_reflinks -ne 0 ]; then
      # Flush delayed refs and commit current transaction.
      sync -f $MNT
   fi

   # Remove the original file and all clones except the last.
   rm -f $MNT/foo
   for ((i = 1; i < $NUM_CLONES; i++)); do
      rm -f $MNT/foo_clone_$i
   done

   if [ $sync_after_remove_reflinks -ne 0 ]; then
      # Flush delayed refs and commit current transaction.
      sync -f $MNT
   fi

   # Now use the last clone as a swap file. It should work since
   # its extent are not shared anymore.
   swapon $MNT/foo_clone_${NUM_CLONES}
   swapoff $MNT/foo_clone_${NUM_CLONES}

   umount $MNT
}

echo -e "\nTest without sync after creating and removing clones"
run_test 0 0

echo -e "\nTest with sync after creating clones"
run_test 1 0

echo -e "\nTest with sync after removing clones"
run_test 0 1

echo -e "\nTest with sync after creating and removing clones"
run_test 1 1


Running the test, it fails most of the time, but not always:

root 11:04:25 /home/fdmanana/scripts/btrfs-bugs > ./swap-all-tests.sh

Test without sync after creating and removing clones
wrote 1048576/1048576 bytes at offset 0
1 MiB, 1 ops; 0.0013 sec (756.430 MiB/sec and 756.4297 ops/sec)
Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
no label, UUID=5613cb28-3f3d-4530-a152-c98184e58e63

Test with sync after creating clones
wrote 1048576/1048576 bytes at offset 0
1 MiB, 1 ops; 0.0028 sec (354.862 MiB/sec and 354.8616 ops/sec)
Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
no label, UUID=da7932b0-0428-4318-82b1-d7a536daa066

Test with sync after removing clones
wrote 1048576/1048576 bytes at offset 0
1 MiB, 1 ops; 0.0017 sec (586.510 MiB/sec and 586.5103 ops/sec)
Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
no label, UUID=2ef8212c-64df-4bca-89fd-9ddadb7a824d

Test with sync after creating and removing clones
wrote 1048576/1048576 bytes at offset 0
1 MiB, 1 ops; 0.0014 sec (672.495 MiB/sec and 672.4950 ops/sec)
Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
no label, UUID=0d7a0bf3-081b-4069-a346-81f1a10ebdda
root 11:04:29 /home/fdmanana/scripts/btrfs-bugs >

No failures above, great.

Running it again:

root 11:04:31 /home/fdmanana/scripts/btrfs-bugs > ./swap-all-tests.sh

Test without sync after creating and removing clones
wrote 1048576/1048576 bytes at offset 0
1 MiB, 1 ops; 0.0019 sec (513.611 MiB/sec and 513.6107 ops/sec)
Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
no label, UUID=9dbafcff-1270-419a-9677-f30f8ea78b18
swapon: /mnt/sdi/foo_clone_50: swapon failed: Invalid argument
swapoff: /mnt/sdi/foo_clone_50: swapoff failed: Invalid argument

Test with sync after creating clones
wrote 1048576/1048576 bytes at offset 0
1 MiB, 1 ops; 0.0010 sec (969.932 MiB/sec and 969.9321 ops/sec)
Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
no label, UUID=dae60c3d-524f-4be5-9d1c-4cfd6a968beb

Test with sync after removing clones
wrote 1048576/1048576 bytes at offset 0
1 MiB, 1 ops; 0.0018 sec (548.847 MiB/sec and 548.8474 ops/sec)
Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
no label, UUID=9d99061e-5675-414d-9067-c591eb6e3528

Test with sync after creating and removing clones
wrote 1048576/1048576 bytes at offset 0
1 MiB, 1 ops; 0.0020 sec (488.520 MiB/sec and 488.5198 ops/sec)
Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
no label, UUID=ff225f28-7e54-4045-8ba6-2c99df02eded
root 11:04:34 /home/fdmanana/scripts/btrfs-bugs >

Only the first sub-test failed.

Running it once again:

root 11:04:35 /home/fdmanana/scripts/btrfs-bugs > ./swap-all-tests.sh

Test without sync after creating and removing clones
wrote 1048576/1048576 bytes at offset 0
1 MiB, 1 ops; 0.0012 sec (803.859 MiB/sec and 803.8585 ops/sec)
Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
no label, UUID=aeb8d730-f2c4-4adc-a59d-8047df74b75c

Test with sync after creating clones
wrote 1048576/1048576 bytes at offset 0
1 MiB, 1 ops; 0.0018 sec (550.055 MiB/sec and 550.0550 ops/sec)
Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
no label, UUID=d5b7d7eb-327c-4df8-a63f-c8d556d3a083
swapon: /mnt/sdi/foo_clone_50: swapon failed: Invalid argument
swapoff: /mnt/sdi/foo_clone_50: swapoff failed: Invalid argument

Test with sync after removing clones
wrote 1048576/1048576 bytes at offset 0
1 MiB, 1 ops; 0.0017 sec (567.859 MiB/sec and 567.8592 ops/sec)
Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
no label, UUID=22b26e8b-c1db-4e86-a39c-82df9b4f324c
swapon: /mnt/sdi/foo_clone_50: swapon failed: Invalid argument
swapoff: /mnt/sdi/foo_clone_50: swapoff failed: Invalid argument

Test with sync after creating and removing clones
wrote 1048576/1048576 bytes at offset 0
1 MiB, 1 ops; 0.0019 sec (514.139 MiB/sec and 514.1388 ops/sec)
Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
no label, UUID=1becd3ea-a6a5-4245-92b9-f4ef4ad23afd
swapon: /mnt/sdi/foo_clone_50: swapon failed: Invalid argument
swapoff: /mnt/sdi/foo_clone_50: swapoff failed: Invalid argument
root 11:04:39 /home/fdmanana/scripts/btrfs-bugs >

This time all sub-tests failed except the first one.

So just to let you know, as I was integrating the test into a generic
test case for fstests.

Thanks.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Bug when attempting to active swap file that used to be cloned/shared
  2024-12-11 14:49 Bug when attempting to active swap file that used to be cloned/shared Filipe Manana
@ 2024-12-11 18:24 ` Darrick J. Wong
  2024-12-11 22:49   ` Dave Chinner
  0 siblings, 1 reply; 3+ messages in thread
From: Darrick J. Wong @ 2024-12-11 18:24 UTC (permalink / raw)
  To: Filipe Manana; +Cc: xfs, linux-btrfs

On Wed, Dec 11, 2024 at 02:49:08PM +0000, Filipe Manana wrote:
> Hello,
> 
> While looking at a btrfs bug where we fail to active a swap file that
> used to have shared extents, I noticed xfs has the same bug, however
> the test fails intermittently, suggesting some sort of race.

I bet swapon is racing with inodegc unmapping the extents from the
previously rm'd files.  The fix for this is (probably?) to call
xfs_inodegc_flush from xfs_iomap_swapfile_activate... though that might
be involved, since iirc at that point we hold the swapfile's IOLOCK.

--D

> The test is this:
> 
> root 11:03:31 /home/fdmanana/scripts/btrfs-bugs > cat swap-all-tests.sh
> #!/bin/bash
> 
> DEV=/dev/sdi
> MNT=/mnt/sdi
> NUM_CLONES=50
> 
> run_test()
> {
>     local sync_after_add_reflinks=$1
>     local sync_after_remove_reflinks=$2
> 
>    # mkfs.btrfs -f $DEV > /dev/null
>    mkfs.xfs -f $DEV > /dev/null
>    mount $DEV $MNT
> 
>    touch $MNT/foo
>    chmod 0600 $MNT/foo
>    # On btrfs the file must be NOCOW.
>    chattr +C $MNT/foo &> /dev/null
>    xfs_io -s -c "pwrite -b 1M 0 1M" $MNT/foo
>    mkswap $MNT/foo
> 
>    for ((i = 1; i <= $NUM_CLONES; i++)); do
>        touch $MNT/foo_clone_$i
>        chmod 0600 $MNT/foo_clone_$i
>       # On btrfs the file must be NOCOW.
>       chattr +C $MNT/foo_clone_$i &> /dev/null
>       cp --reflink=always $MNT/foo $MNT/foo_clone_$i
>    done
> 
>    if [ $sync_after_add_reflinks -ne 0 ]; then
>       # Flush delayed refs and commit current transaction.
>       sync -f $MNT
>    fi
> 
>    # Remove the original file and all clones except the last.
>    rm -f $MNT/foo
>    for ((i = 1; i < $NUM_CLONES; i++)); do
>       rm -f $MNT/foo_clone_$i
>    done
> 
>    if [ $sync_after_remove_reflinks -ne 0 ]; then
>       # Flush delayed refs and commit current transaction.
>       sync -f $MNT
>    fi
> 
>    # Now use the last clone as a swap file. It should work since
>    # its extent are not shared anymore.
>    swapon $MNT/foo_clone_${NUM_CLONES}
>    swapoff $MNT/foo_clone_${NUM_CLONES}
> 
>    umount $MNT
> }
> 
> echo -e "\nTest without sync after creating and removing clones"
> run_test 0 0
> 
> echo -e "\nTest with sync after creating clones"
> run_test 1 0
> 
> echo -e "\nTest with sync after removing clones"
> run_test 0 1
> 
> echo -e "\nTest with sync after creating and removing clones"
> run_test 1 1
> 
> 
> Running the test, it fails most of the time, but not always:
> 
> root 11:04:25 /home/fdmanana/scripts/btrfs-bugs > ./swap-all-tests.sh
> 
> Test without sync after creating and removing clones
> wrote 1048576/1048576 bytes at offset 0
> 1 MiB, 1 ops; 0.0013 sec (756.430 MiB/sec and 756.4297 ops/sec)
> Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
> no label, UUID=5613cb28-3f3d-4530-a152-c98184e58e63
> 
> Test with sync after creating clones
> wrote 1048576/1048576 bytes at offset 0
> 1 MiB, 1 ops; 0.0028 sec (354.862 MiB/sec and 354.8616 ops/sec)
> Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
> no label, UUID=da7932b0-0428-4318-82b1-d7a536daa066
> 
> Test with sync after removing clones
> wrote 1048576/1048576 bytes at offset 0
> 1 MiB, 1 ops; 0.0017 sec (586.510 MiB/sec and 586.5103 ops/sec)
> Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
> no label, UUID=2ef8212c-64df-4bca-89fd-9ddadb7a824d
> 
> Test with sync after creating and removing clones
> wrote 1048576/1048576 bytes at offset 0
> 1 MiB, 1 ops; 0.0014 sec (672.495 MiB/sec and 672.4950 ops/sec)
> Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
> no label, UUID=0d7a0bf3-081b-4069-a346-81f1a10ebdda
> root 11:04:29 /home/fdmanana/scripts/btrfs-bugs >
> 
> No failures above, great.
> 
> Running it again:
> 
> root 11:04:31 /home/fdmanana/scripts/btrfs-bugs > ./swap-all-tests.sh
> 
> Test without sync after creating and removing clones
> wrote 1048576/1048576 bytes at offset 0
> 1 MiB, 1 ops; 0.0019 sec (513.611 MiB/sec and 513.6107 ops/sec)
> Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
> no label, UUID=9dbafcff-1270-419a-9677-f30f8ea78b18
> swapon: /mnt/sdi/foo_clone_50: swapon failed: Invalid argument
> swapoff: /mnt/sdi/foo_clone_50: swapoff failed: Invalid argument
> 
> Test with sync after creating clones
> wrote 1048576/1048576 bytes at offset 0
> 1 MiB, 1 ops; 0.0010 sec (969.932 MiB/sec and 969.9321 ops/sec)
> Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
> no label, UUID=dae60c3d-524f-4be5-9d1c-4cfd6a968beb
> 
> Test with sync after removing clones
> wrote 1048576/1048576 bytes at offset 0
> 1 MiB, 1 ops; 0.0018 sec (548.847 MiB/sec and 548.8474 ops/sec)
> Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
> no label, UUID=9d99061e-5675-414d-9067-c591eb6e3528
> 
> Test with sync after creating and removing clones
> wrote 1048576/1048576 bytes at offset 0
> 1 MiB, 1 ops; 0.0020 sec (488.520 MiB/sec and 488.5198 ops/sec)
> Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
> no label, UUID=ff225f28-7e54-4045-8ba6-2c99df02eded
> root 11:04:34 /home/fdmanana/scripts/btrfs-bugs >
> 
> Only the first sub-test failed.
> 
> Running it once again:
> 
> root 11:04:35 /home/fdmanana/scripts/btrfs-bugs > ./swap-all-tests.sh
> 
> Test without sync after creating and removing clones
> wrote 1048576/1048576 bytes at offset 0
> 1 MiB, 1 ops; 0.0012 sec (803.859 MiB/sec and 803.8585 ops/sec)
> Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
> no label, UUID=aeb8d730-f2c4-4adc-a59d-8047df74b75c
> 
> Test with sync after creating clones
> wrote 1048576/1048576 bytes at offset 0
> 1 MiB, 1 ops; 0.0018 sec (550.055 MiB/sec and 550.0550 ops/sec)
> Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
> no label, UUID=d5b7d7eb-327c-4df8-a63f-c8d556d3a083
> swapon: /mnt/sdi/foo_clone_50: swapon failed: Invalid argument
> swapoff: /mnt/sdi/foo_clone_50: swapoff failed: Invalid argument
> 
> Test with sync after removing clones
> wrote 1048576/1048576 bytes at offset 0
> 1 MiB, 1 ops; 0.0017 sec (567.859 MiB/sec and 567.8592 ops/sec)
> Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
> no label, UUID=22b26e8b-c1db-4e86-a39c-82df9b4f324c
> swapon: /mnt/sdi/foo_clone_50: swapon failed: Invalid argument
> swapoff: /mnt/sdi/foo_clone_50: swapoff failed: Invalid argument
> 
> Test with sync after creating and removing clones
> wrote 1048576/1048576 bytes at offset 0
> 1 MiB, 1 ops; 0.0019 sec (514.139 MiB/sec and 514.1388 ops/sec)
> Setting up swapspace version 1, size = 1020 KiB (1044480 bytes)
> no label, UUID=1becd3ea-a6a5-4245-92b9-f4ef4ad23afd
> swapon: /mnt/sdi/foo_clone_50: swapon failed: Invalid argument
> swapoff: /mnt/sdi/foo_clone_50: swapoff failed: Invalid argument
> root 11:04:39 /home/fdmanana/scripts/btrfs-bugs >
> 
> This time all sub-tests failed except the first one.
> 
> So just to let you know, as I was integrating the test into a generic
> test case for fstests.
> 
> Thanks.
> 

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Bug when attempting to active swap file that used to be cloned/shared
  2024-12-11 18:24 ` Darrick J. Wong
@ 2024-12-11 22:49   ` Dave Chinner
  0 siblings, 0 replies; 3+ messages in thread
From: Dave Chinner @ 2024-12-11 22:49 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Filipe Manana, xfs, linux-btrfs

On Wed, Dec 11, 2024 at 10:24:56AM -0800, Darrick J. Wong wrote:
> On Wed, Dec 11, 2024 at 02:49:08PM +0000, Filipe Manana wrote:
> > Hello,
> > 
> > While looking at a btrfs bug where we fail to active a swap file that
> > used to have shared extents, I noticed xfs has the same bug, however
> > the test fails intermittently, suggesting some sort of race.
> 
> I bet swapon is racing with inodegc unmapping the extents from the
> previously rm'd files.

Almost certainly the case.  All sync does is stabilise the unlinked
lists so recovery will see the unlinked inodes; it has no effect on
expediting background inodegc, nor should it.

> The fix for this is (probably?) to call
> xfs_inodegc_flush from xfs_iomap_swapfile_activate... though that might
> be involved, since iirc at that point we hold the swapfile's IOLOCK.

For this sort of artificial test, freeze and unfreeze to ensure that
the background inodegc is drained before the swapon command is run.
It's not clear to me that there is a real world use case where this
is actually a problem, so for testing purposes a freeze before
swapon seems like the right way to go here...

-Dave.
-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-12-11 22:49 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-11 14:49 Bug when attempting to active swap file that used to be cloned/shared Filipe Manana
2024-12-11 18:24 ` Darrick J. Wong
2024-12-11 22:49   ` Dave Chinner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox