[PATCH v2] fstests: btrfs: test snapshot creation with existing qgroup

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]



[BUG]
There is a sysbot regression report about transaction abort during
snapshot creation, which is caused by the new timing of qgroup creation
and too strict error check.

[FIX]
The proper fix is already submitted, with the title "btrfs: do not abort
transaction if there is already an existing qgroup".

[TEST]
The new test case would reproduce the regression by:

- Create a subvolume and a snapshot of it

- Record the subvolumeid of the snapshot

- Re-create the fs
  Since btrfs won't reuse the subvolume id, we have to re-create the fs.

- Enable quota and create a qgroup with the same subvolumeid

- Create a subvolume and a snapshot of it
  For unpatched and affected kernel (thankfully no release is affected),
  the snapshot creation would fail due to aborted transaction.

- Make sure the subvolume id doesn't change for the snapshot
  There is one very hacky attempt to fix it by avoiding using the
  subvolume id, which is completely wrong and would be caught by this
  extra check.

Signed-off-by: Qu Wenruo <wqu@xxxxxxxx>
---
Changelog:
v2:
- Add to 'snapshot' and 'subvol' groups

- Remove one unnecessary sync
  The sync after qgroup creation is not needed, the qgroup id conflicts
  doesn't need qgroup tree to be committed anyway.

- Remove one unnecessary unmount
  The final scratch unmount is not needed as the framework would unmount
  it automatically.
---
 tests/btrfs/303     | 77 +++++++++++++++++++++++++++++++++++++++++++++
 tests/btrfs/303.out |  2 ++
 2 files changed, 79 insertions(+)
 create mode 100755 tests/btrfs/303
 create mode 100644 tests/btrfs/303.out

diff --git a/tests/btrfs/303 b/tests/btrfs/303
new file mode 100755
index 00000000..b9d6c61d
--- /dev/null
+++ b/tests/btrfs/303
@@ -0,0 +1,77 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (C) 2023 SUSE Linux Products GmbH. All Rights Reserved.
+#
+# FS QA Test 303
+#
+# A regression test to make sure snapshot creation won't cause transaction
+# abort if there is already an existing qgroup.
+#
+. ./common/preamble
+_begin_fstest auto quick snapshot subvol qgroup
+
+. ./common/filter
+
+_supported_fs btrfs
+_require_scratch
+
+_fixed_by_kernel_commit xxxxxxxxxxxx \
+	"btrfs: do not abort transaction if there is already an existing qgroup"
+
+_scratch_mkfs >> $seqres.full 2>&1 || _fail "mkfs failed"
+_scratch_mount
+
+# Create the first subvolume and get its id.
+# This subvolume id should not change no matter if there is an existing
+# qgroup for it.
+$BTRFS_UTIL_PROG subvolume create "$SCRATCH_MNT/subvol" >> $seqres.full
+$BTRFS_UTIL_PROG subvolume snapshot "$SCRATCH_MNT/subvol" \
+	"$SCRATCH_MNT/snapshot">> $seqres.full
+
+init_subvolid=$(_btrfs_get_subvolid "$SCRATCH_MNT" "snapshot")
+
+if [ -z "$init_subvolid" ]; then
+	_fail "Unable to get the subvolid of the first snapshot"
+fi
+
+echo "Subvolumeid: ${init_subvolid}" >> $seqres.full
+
+_scratch_unmount
+
+# Re-create the fs, as btrfs won't reuse the subvolume id.
+_scratch_mkfs >> $seqres.full 2>&1 || _fail "2nd mkfs failed"
+_scratch_mount
+
+$BTRFS_UTIL_PROG quota enable "$SCRATCH_MNT" >> $seqres.full
+$BTRFS_UTIL_PROG quota rescan -w "$SCRATCH_MNT" >> $seqres.full
+
+# Create a qgroup for the first subvolume, this would make the later
+# subvolume creation to find an existing qgroup, and abort transaction.
+$BTRFS_UTIL_PROG qgroup create 0/"$init_subvolid" "$SCRATCH_MNT" >> $seqres.full
+
+# Now create the first snapshot, which should have the same subvolid no matter
+# if the quota is enabled.
+$BTRFS_UTIL_PROG subvolume create "$SCRATCH_MNT/subvol" >> $seqres.full
+$BTRFS_UTIL_PROG subvolume snapshot "$SCRATCH_MNT/subvol" \
+	"$SCRATCH_MNT/snapshot" >> $seqres.full
+
+# Either the snapshot create failed and transaction is aborted thus no
+# snapshot here, or we should be able to create the snapshot.
+new_subvolid=$(_btrfs_get_subvolid "$SCRATCH_MNT" "snapshot")
+
+echo "Subvolumeid: ${new_subvolid}" >> $seqres.full
+
+if [ -z "$new_subvolid" ]; then
+	_fail "Unable to get the subvolid of the first snapshot"
+fi
+
+# Make sure the subvolumeid for the first snapshot didn't change.
+if [ "$new_subvolid" -ne "$init_subvolid" ]; then
+	_fail "Subvolumeid for the first snapshot changed, has ${new_subvolid} expect ${init_subvolid}"
+fi
+
+echo "Silence is golden"
+
+# success, all done
+status=0
+exit
diff --git a/tests/btrfs/303.out b/tests/btrfs/303.out
new file mode 100644
index 00000000..d48808e6
--- /dev/null
+++ b/tests/btrfs/303.out
@@ -0,0 +1,2 @@
+QA output created by 303
+Silence is golden
-- 
2.42.0





[Index of Archives]     [Linux Filesystems Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux