Linux Btrfs filesystem development
 help / color / mirror / Atom feed
* [PATCH] btrfs: regression test for duplicated rmdir in incremental send with extrefs
@ 2026-04-17  7:07 tchou
  2026-04-17  7:48 ` Filipe Manana
  0 siblings, 1 reply; 2+ messages in thread
From: tchou @ 2026-04-17  7:07 UTC (permalink / raw)
  To: fstests; +Cc: linux-btrfs, Ting-Chang Hou

From: Ting-Chang Hou <tchou@synology.com>

Regression test for btrfs incremental send issue where duplicated rmdir
instructions were sent when using INODE_EXTREF. This happens when there
are many hardlinks to the same file across two directories, causing the
INODE_EXTREF items to interleave between directories.

This issue is fixed by the following linux kernel btrfs patch:

commit 1fabe43b4e1a ("btrfs: send: fix duplicated rmdir operations when using extrefs")

Signed-off-by: Ting-Chang Hou <tchou@synology.com>
---
 tests/btrfs/348     | 99 +++++++++++++++++++++++++++++++++++++++++++++
 tests/btrfs/348.out |  1 +
 2 files changed, 100 insertions(+)
 create mode 100755 tests/btrfs/348
 create mode 100644 tests/btrfs/348.out

diff --git a/tests/btrfs/348 b/tests/btrfs/348
new file mode 100755
index 00000000..6e887e77
--- /dev/null
+++ b/tests/btrfs/348
@@ -0,0 +1,99 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2025 Synology Inc.  All Rights Reserved.
+#
+# FS QA Test No. btrfs/348
+#
+# Regression test for btrfs incremental send issue where duplicated rmdir
+# instructions were sent when using INODE_EXTREF. This happens when there
+# are many hardlinks to the same file across two directories, causing the
+# INODE_EXTREF items to interleave between directories. The original fix
+# in commit 29d6d30f5c8a ("Btrfs: send, don't send rmdir for same target
+# multiple times") only handled consecutive rmdir operations for the same
+# directory, but failed when rmdir operations were not consecutive due to
+# the interleaved INODE_EXTREF ordering.
+#
+# This issue is fixed by the following linux kernel btrfs patch:
+#
+#   commit 1fabe43b4e1a ("btrfs: send: fix duplicated rmdir operations when using extrefs")
+#
+. ./common/preamble
+_begin_fstest auto quick send
+
+tmp=`mktemp -d`
+
+# Override the default cleanup function.
+_cleanup()
+{
+	rm -fr $tmp
+}
+
+. ./common/filter
+
+_require_scratch
+_require_fssum
+
+_scratch_mkfs >/dev/null 2>&1
+_scratch_mount
+
+mkdir $SCRATCH_MNT/a $SCRATCH_MNT/b
+
+echo 123 > $SCRATCH_MNT/a/foo
+
+# Create enough hardlinks to trigger INODE_EXTREF usage.
+# When hardlinks exceed what a single INODE_REF item can hold,
+# INODE_EXTREF is used. The key of INODE_EXTREF includes a hash
+# of the name and parent inode, causing items from different
+# directories to interleave.
+for ((i = 1; i <= 1000; i++)); do
+	ln $SCRATCH_MNT/a/foo $SCRATCH_MNT/a/foo.$i
+	ln $SCRATCH_MNT/a/foo $SCRATCH_MNT/b/foo.$i
+done
+
+# Filesystem looks like:
+#
+# .                              (ino 256)
+# |-- a/                         (ino 257)
+# |   |-- foo                    (ino 259)
+# |   |-- foo.1 ... foo.1000     (ino 259, hardlinks)
+# |
+# |-- b/                         (ino 258)
+#     |-- foo.1 ... foo.1000     (ino 259, hardlinks)
+
+_btrfs subvolume snapshot -r $SCRATCH_MNT $SCRATCH_MNT/snap1
+
+rm -r $SCRATCH_MNT/a $SCRATCH_MNT/b
+
+# Filesystem now looks like:
+#
+# .                              (ino 256)
+# |-- snap1/                     (read-only snapshot)
+
+_btrfs subvolume snapshot -r $SCRATCH_MNT $SCRATCH_MNT/snap2
+
+run_check $FSSUM_PROG -A -f -w $tmp/1.fssum $SCRATCH_MNT/snap1
+run_check $FSSUM_PROG -A -f -w $tmp/2.fssum -x $SCRATCH_MNT/snap2/snap1 \
+	$SCRATCH_MNT/snap2
+
+_btrfs send -f $tmp/1.snap $SCRATCH_MNT/snap1
+_btrfs send -p $SCRATCH_MNT/snap1 -f $tmp/2.snap $SCRATCH_MNT/snap2
+
+_scratch_unmount
+_check_btrfs_filesystem $SCRATCH_DEV
+
+_scratch_mkfs >/dev/null 2>&1
+_scratch_mount
+
+_btrfs receive -f $tmp/1.snap $SCRATCH_MNT
+run_check $FSSUM_PROG -r $tmp/1.fssum $SCRATCH_MNT/snap1
+
+# This used to fail with:
+# ERROR: rmdir o<ino>-<gen>-0 failed: No such file or directory
+_btrfs receive -f $tmp/2.snap $SCRATCH_MNT
+run_check $FSSUM_PROG -r $tmp/2.fssum $SCRATCH_MNT/snap2
+
+_scratch_unmount
+_check_btrfs_filesystem $SCRATCH_DEV
+
+status=0
+exit
diff --git a/tests/btrfs/348.out b/tests/btrfs/348.out
new file mode 100644
index 00000000..f5e0b75a
--- /dev/null
+++ b/tests/btrfs/348.out
@@ -0,0 +1 @@
+QA output created by 348
--
2.34.1


Disclaimer: The contents of this e-mail message and any attachments are confidential and are intended solely for addressee. The information may also be legally privileged. This transmission is sent in trust, for the sole purpose of delivery to the intended recipient. If you have received this transmission in error, any use, reproduction or dissemination of this transmission is strictly prohibited. If you are not the intended recipient, please immediately notify the sender by reply e-mail or phone and delete this message and its attachments, if any.

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

* Re: [PATCH] btrfs: regression test for duplicated rmdir in incremental send with extrefs
  2026-04-17  7:07 [PATCH] btrfs: regression test for duplicated rmdir in incremental send with extrefs tchou
@ 2026-04-17  7:48 ` Filipe Manana
  0 siblings, 0 replies; 2+ messages in thread
From: Filipe Manana @ 2026-04-17  7:48 UTC (permalink / raw)
  To: tchou; +Cc: fstests, linux-btrfs

On Fri, Apr 17, 2026 at 8:08 AM tchou <tchou@synology.com> wrote:
>
> From: Ting-Chang Hou <tchou@synology.com>
>
> Regression test for btrfs incremental send issue where duplicated rmdir
> instructions were sent when using INODE_EXTREF. This happens when there
> are many hardlinks to the same file across two directories, causing the
> INODE_EXTREF items to interleave between directories.
>
> This issue is fixed by the following linux kernel btrfs patch:
>
> commit 1fabe43b4e1a ("btrfs: send: fix duplicated rmdir operations when using extrefs")
>
> Signed-off-by: Ting-Chang Hou <tchou@synology.com>
> ---
>  tests/btrfs/348     | 99 +++++++++++++++++++++++++++++++++++++++++++++
>  tests/btrfs/348.out |  1 +
>  2 files changed, 100 insertions(+)
>  create mode 100755 tests/btrfs/348
>  create mode 100644 tests/btrfs/348.out
>
> diff --git a/tests/btrfs/348 b/tests/btrfs/348
> new file mode 100755
> index 00000000..6e887e77
> --- /dev/null
> +++ b/tests/btrfs/348
> @@ -0,0 +1,99 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2025 Synology Inc.  All Rights Reserved.
> +#
> +# FS QA Test No. btrfs/348
> +#
> +# Regression test for btrfs incremental send issue where duplicated rmdir
> +# instructions were sent when using INODE_EXTREF. This happens when there
> +# are many hardlinks to the same file across two directories, causing the
> +# INODE_EXTREF items to interleave between directories. The original fix
> +# in commit 29d6d30f5c8a ("Btrfs: send, don't send rmdir for same target
> +# multiple times") only handled consecutive rmdir operations for the same
> +# directory, but failed when rmdir operations were not consecutive due to
> +# the interleaved INODE_EXTREF ordering.
> +#
> +# This issue is fixed by the following linux kernel btrfs patch:
> +#
> +#   commit 1fabe43b4e1a ("btrfs: send: fix duplicated rmdir operations when using extrefs")

We already have a test case for this since October 2025: btrfs/338

Also in the future, please specify the commit like this:

_fixed_by_kernel_commit 1fabe43b4e1a \
        "btrfs: send: fix duplicated rmdir operations when using extrefs"

Thanks.

> +#
> +. ./common/preamble
> +_begin_fstest auto quick send
> +
> +tmp=`mktemp -d`
> +
> +# Override the default cleanup function.
> +_cleanup()
> +{
> +       rm -fr $tmp
> +}
> +
> +. ./common/filter
> +
> +_require_scratch
> +_require_fssum
> +
> +_scratch_mkfs >/dev/null 2>&1
> +_scratch_mount
> +
> +mkdir $SCRATCH_MNT/a $SCRATCH_MNT/b
> +
> +echo 123 > $SCRATCH_MNT/a/foo
> +
> +# Create enough hardlinks to trigger INODE_EXTREF usage.
> +# When hardlinks exceed what a single INODE_REF item can hold,
> +# INODE_EXTREF is used. The key of INODE_EXTREF includes a hash
> +# of the name and parent inode, causing items from different
> +# directories to interleave.
> +for ((i = 1; i <= 1000; i++)); do
> +       ln $SCRATCH_MNT/a/foo $SCRATCH_MNT/a/foo.$i
> +       ln $SCRATCH_MNT/a/foo $SCRATCH_MNT/b/foo.$i
> +done
> +
> +# Filesystem looks like:
> +#
> +# .                              (ino 256)
> +# |-- a/                         (ino 257)
> +# |   |-- foo                    (ino 259)
> +# |   |-- foo.1 ... foo.1000     (ino 259, hardlinks)
> +# |
> +# |-- b/                         (ino 258)
> +#     |-- foo.1 ... foo.1000     (ino 259, hardlinks)
> +
> +_btrfs subvolume snapshot -r $SCRATCH_MNT $SCRATCH_MNT/snap1
> +
> +rm -r $SCRATCH_MNT/a $SCRATCH_MNT/b
> +
> +# Filesystem now looks like:
> +#
> +# .                              (ino 256)
> +# |-- snap1/                     (read-only snapshot)
> +
> +_btrfs subvolume snapshot -r $SCRATCH_MNT $SCRATCH_MNT/snap2
> +
> +run_check $FSSUM_PROG -A -f -w $tmp/1.fssum $SCRATCH_MNT/snap1
> +run_check $FSSUM_PROG -A -f -w $tmp/2.fssum -x $SCRATCH_MNT/snap2/snap1 \
> +       $SCRATCH_MNT/snap2
> +
> +_btrfs send -f $tmp/1.snap $SCRATCH_MNT/snap1
> +_btrfs send -p $SCRATCH_MNT/snap1 -f $tmp/2.snap $SCRATCH_MNT/snap2
> +
> +_scratch_unmount
> +_check_btrfs_filesystem $SCRATCH_DEV
> +
> +_scratch_mkfs >/dev/null 2>&1
> +_scratch_mount
> +
> +_btrfs receive -f $tmp/1.snap $SCRATCH_MNT
> +run_check $FSSUM_PROG -r $tmp/1.fssum $SCRATCH_MNT/snap1
> +
> +# This used to fail with:
> +# ERROR: rmdir o<ino>-<gen>-0 failed: No such file or directory
> +_btrfs receive -f $tmp/2.snap $SCRATCH_MNT
> +run_check $FSSUM_PROG -r $tmp/2.fssum $SCRATCH_MNT/snap2
> +
> +_scratch_unmount
> +_check_btrfs_filesystem $SCRATCH_DEV
> +
> +status=0
> +exit
> diff --git a/tests/btrfs/348.out b/tests/btrfs/348.out
> new file mode 100644
> index 00000000..f5e0b75a
> --- /dev/null
> +++ b/tests/btrfs/348.out
> @@ -0,0 +1 @@
> +QA output created by 348
> --
> 2.34.1
>
>
> Disclaimer: The contents of this e-mail message and any attachments are confidential and are intended solely for addressee. The information may also be legally privileged. This transmission is sent in trust, for the sole purpose of delivery to the intended recipient. If you have received this transmission in error, any use, reproduction or dissemination of this transmission is strictly prohibited. If you are not the intended recipient, please immediately notify the sender by reply e-mail or phone and delete this message and its attachments, if any.
>

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

end of thread, other threads:[~2026-04-17  7:49 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-17  7:07 [PATCH] btrfs: regression test for duplicated rmdir in incremental send with extrefs tchou
2026-04-17  7:48 ` Filipe Manana

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