* [PATCH 1/9] fstests: allow SCRATCH_DEV_POOL for non-Btrfs filesystems
2026-02-26 14:41 [PATCH 0/9] fstests: add test coverage for cloned filesystem ids Anand Jain
@ 2026-02-26 14:41 ` Anand Jain
2026-02-26 14:41 ` [PATCH 2/9] fstests: add _mkfs_scratch_clone() helper Anand Jain
` (7 subsequent siblings)
8 siblings, 0 replies; 19+ messages in thread
From: Anand Jain @ 2026-02-26 14:41 UTC (permalink / raw)
To: fstests; +Cc: linux-btrfs, linux-ext4, linux-xfs
Tests for cloned device verification should pass on Btrfs, XFS, and ext4.
We need 2 scratch devices, allow SCRATCH_DEV_POOL for other FSs.
Signed-off-by: Anand Jain <asj@kernel.org>
---
common/rc | 15 +++------------
1 file changed, 3 insertions(+), 12 deletions(-)
diff --git a/common/rc b/common/rc
index 92cb69820311..9db8b3e88996 100644
--- a/common/rc
+++ b/common/rc
@@ -3990,18 +3990,9 @@ _require_scratch_dev_pool()
ndevs=$1
fi
- # btrfs test case needs ndevs or more scratch_dev_pool; other FS not sure
- # so fail it
- case $FSTYP in
- btrfs)
- if [ "`echo $SCRATCH_DEV_POOL|wc -w`" -lt $ndevs ]; then
- _notrun "btrfs and this test needs $ndevs or more disks in SCRATCH_DEV_POOL"
- fi
- ;;
- *)
- _notrun "dev_pool is not supported by fstype \"$FSTYP\""
- ;;
- esac
+ if [ "`echo $SCRATCH_DEV_POOL|wc -w`" -lt $ndevs ]; then
+ _notrun "This test needs $ndevs or more disks in SCRATCH_DEV_POOL"
+ fi
for i in $SCRATCH_DEV_POOL; do
if [ "`_is_block_dev "$i"`" = "" ]; then
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 2/9] fstests: add _mkfs_scratch_clone() helper
2026-02-26 14:41 [PATCH 0/9] fstests: add test coverage for cloned filesystem ids Anand Jain
2026-02-26 14:41 ` [PATCH 1/9] fstests: allow SCRATCH_DEV_POOL for non-Btrfs filesystems Anand Jain
@ 2026-02-26 14:41 ` Anand Jain
2026-03-09 19:13 ` Zorro Lang
2026-02-26 14:41 ` [PATCH 3/9] fstests: add _clone_mount_option() helper Anand Jain
` (6 subsequent siblings)
8 siblings, 1 reply; 19+ messages in thread
From: Anand Jain @ 2026-02-26 14:41 UTC (permalink / raw)
To: fstests; +Cc: linux-btrfs, linux-ext4, linux-xfs
Introduce _mkfs_scratch_clone() to mkfs the scratch device and clone it to
the next device in SCRATCH_DEV_POOL.
Signed-off-by: Anand Jain <asj@kernel.org>
---
common/rc | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/common/rc b/common/rc
index 9db8b3e88996..2253438ef0f6 100644
--- a/common/rc
+++ b/common/rc
@@ -1503,6 +1503,38 @@ _scratch_resvblks()
esac
}
+_scratch_mkfs_sized_clone()
+{
+ local devs=($SCRATCH_DEV_POOL)
+ local scratch_data="$1"
+ local size=$(_small_fs_size_mb 128) # Smallest possible
+
+ size=$((size * 1024 * 1024))
+
+ # make sure there are two devices
+ if [ "${#devs[@]}" -ne 2 ]; then
+ _notrun "Test requires exactly 2 devices"
+ fi
+
+ case "$FSTYP" in
+ "btrfs")
+ _scratch_mkfs_sized $size
+ _scratch_mount
+ $BTRFS_UTIL_PROG subvolume create $SCRATCH_MNT/sv1
+ _scratch_unmount
+ ;;
+ "xfs"|"ext4")
+ _scratch_mkfs_sized $size
+ ;;
+ *)
+ _notrun "fstests clone op unsupported for FS $FSTYP"
+ ;;
+ esac
+
+ # clone SCRATCH_DEV devs[0] to devs[1].
+ dd if=$SCRATCH_DEV of=${devs[1]} bs=$size status=none count=1 || \
+ _fail "Clone failed"
+}
# Repair scratch filesystem. Returns 0 if the FS is good to go (either no
# errors found or errors were fixed) and nonzero otherwise; also spits out
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH 2/9] fstests: add _mkfs_scratch_clone() helper
2026-02-26 14:41 ` [PATCH 2/9] fstests: add _mkfs_scratch_clone() helper Anand Jain
@ 2026-03-09 19:13 ` Zorro Lang
2026-03-11 2:32 ` Anand Jain
0 siblings, 1 reply; 19+ messages in thread
From: Zorro Lang @ 2026-03-09 19:13 UTC (permalink / raw)
To: Anand Jain; +Cc: fstests, linux-btrfs, linux-ext4, linux-xfs
On Thu, Feb 26, 2026 at 10:41:43PM +0800, Anand Jain wrote:
> Introduce _mkfs_scratch_clone() to mkfs the scratch device and clone it to
> the next device in SCRATCH_DEV_POOL.
>
> Signed-off-by: Anand Jain <asj@kernel.org>
> ---
> common/rc | 32 ++++++++++++++++++++++++++++++++
> 1 file changed, 32 insertions(+)
>
> diff --git a/common/rc b/common/rc
> index 9db8b3e88996..2253438ef0f6 100644
> --- a/common/rc
> +++ b/common/rc
> @@ -1503,6 +1503,38 @@ _scratch_resvblks()
> esac
> }
>
> +_scratch_mkfs_sized_clone()
> +{
> + local devs=($SCRATCH_DEV_POOL)
> + local scratch_data="$1"
> + local size=$(_small_fs_size_mb 128) # Smallest possible
> +
> + size=$((size * 1024 * 1024))
> +
> + # make sure there are two devices
> + if [ "${#devs[@]}" -ne 2 ]; then
What about if ${#devs[@]} > 2 ?
> + _notrun "Test requires exactly 2 devices"
> + fi
> +
> + case "$FSTYP" in
> + "btrfs")
> + _scratch_mkfs_sized $size
> + _scratch_mount
> + $BTRFS_UTIL_PROG subvolume create $SCRATCH_MNT/sv1
> + _scratch_unmount
> + ;;
> + "xfs"|"ext4")
> + _scratch_mkfs_sized $size
> + ;;
> + *)
> + _notrun "fstests clone op unsupported for FS $FSTYP"
> + ;;
> + esac
> +
> + # clone SCRATCH_DEV devs[0] to devs[1].
> + dd if=$SCRATCH_DEV of=${devs[1]} bs=$size status=none count=1 || \
> + _fail "Clone failed"
I'm wondering if we absolutely need to use SCRATCH_DEV_POOL for this test. Could we clone SCRATCH_DEV
to an image file instead? Or would it be feasible to simply run the test using two image files?
Thanks,
Zorro
> +}
>
> # Repair scratch filesystem. Returns 0 if the FS is good to go (either no
> # errors found or errors were fixed) and nonzero otherwise; also spits out
> --
> 2.43.0
>
>
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH 2/9] fstests: add _mkfs_scratch_clone() helper
2026-03-09 19:13 ` Zorro Lang
@ 2026-03-11 2:32 ` Anand Jain
2026-03-14 17:04 ` Zorro Lang
0 siblings, 1 reply; 19+ messages in thread
From: Anand Jain @ 2026-03-11 2:32 UTC (permalink / raw)
To: Zorro Lang, Anand Jain; +Cc: fstests, linux-btrfs, linux-ext4, linux-xfs
> What about if ${#devs[@]} > 2 ?
On purpose- so tests using _scratch_mkfs_sized_clone() don't
pick a random higher number. If a test needs more than two
devices, opens an opportunity to critically review this function.
>> + fi
>> +
>> + case "$FSTYP" in
>> + "btrfs")
>> + _scratch_mkfs_sized $size
>> + _scratch_mount
>> + $BTRFS_UTIL_PROG subvolume create $SCRATCH_MNT/sv1
>> + _scratch_unmount
>> + ;;
>> + "xfs"|"ext4")
>> + _scratch_mkfs_sized $size
>> + ;;
>> + *)
>> + _notrun "fstests clone op unsupported for FS $FSTYP"
>> + ;;
>> + esac
>> +
>> + # clone SCRATCH_DEV devs[0] to devs[1].
>> + dd if=$SCRATCH_DEV of=${devs[1]} bs=$size status=none count=1 || \
>> + _fail "Clone failed"
>
> I'm wondering if we absolutely need to use SCRATCH_DEV_POOL for this test. Could we clone SCRATCH_DEV
> to an image file instead? Or would it be feasible to simply run the test using two image files?
Using a config file and testing directly on block devices lets
us cover a wider range of devices.
When I wrote this test case, I was also considering whether a
serial-number–based mount without extra mount option, would be
better in the kernel.
The downside is that xfs/ext4 testers now need to use
SCRATCH_DEV_POOL. Let me know what you prefer.
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH 2/9] fstests: add _mkfs_scratch_clone() helper
2026-03-11 2:32 ` Anand Jain
@ 2026-03-14 17:04 ` Zorro Lang
2026-03-16 16:15 ` Christoph Hellwig
0 siblings, 1 reply; 19+ messages in thread
From: Zorro Lang @ 2026-03-14 17:04 UTC (permalink / raw)
To: Anand Jain; +Cc: Anand Jain, fstests, linux-btrfs, linux-ext4, linux-xfs
On Wed, Mar 11, 2026 at 10:32:18AM +0800, Anand Jain wrote:
>
> > What about if ${#devs[@]} > 2 ?
>
> On purpose- so tests using _scratch_mkfs_sized_clone() don't
> pick a random higher number. If a test needs more than two
> devices, opens an opportunity to critically review this function.
> >> + fi
> >> +
> >> + case "$FSTYP" in
> >> + "btrfs")
> >> + _scratch_mkfs_sized $size
> >> + _scratch_mount
> >> + $BTRFS_UTIL_PROG subvolume create $SCRATCH_MNT/sv1
> >> + _scratch_unmount
> >> + ;;
> >> + "xfs"|"ext4")
> >> + _scratch_mkfs_sized $size
> >> + ;;
> >> + *)
> >> + _notrun "fstests clone op unsupported for FS $FSTYP"
> >> + ;;
> >> + esac
> >> +
> >> + # clone SCRATCH_DEV devs[0] to devs[1].
> >> + dd if=$SCRATCH_DEV of=${devs[1]} bs=$size status=none count=1 || \
> >> + _fail "Clone failed"
> >
> > I'm wondering if we absolutely need to use SCRATCH_DEV_POOL for this test. Could we clone SCRATCH_DEV
> > to an image file instead? Or would it be feasible to simply run the test using two image files?
>
> Using a config file and testing directly on block devices lets
> us cover a wider range of devices.
>
> When I wrote this test case, I was also considering whether a
> serial-number–based mount without extra mount option, would be
> better in the kernel.
>
> The downside is that xfs/ext4 testers now need to use
> SCRATCH_DEV_POOL. Let me know what you prefer.
I'm concerned that testers from other filesystems might not be familiar
with SCRATCH_DEV_POOL, as it's typically not a requirement for their
testing. I'm not sure if they would be willing to configure and switch
to SCRATCH_DEV_POOL, just for these few test cases. If we can avoid making
the pool to be a hard requirement, it might be more user-friendly for other
fs list. Welcome feedback and review points from other filesystem mailing
lists :)
Thanks,
Zorro
>
>
>
>
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH 2/9] fstests: add _mkfs_scratch_clone() helper
2026-03-14 17:04 ` Zorro Lang
@ 2026-03-16 16:15 ` Christoph Hellwig
2026-03-21 12:02 ` Anand Jain
0 siblings, 1 reply; 19+ messages in thread
From: Christoph Hellwig @ 2026-03-16 16:15 UTC (permalink / raw)
To: Zorro Lang
Cc: Anand Jain, Anand Jain, fstests, linux-btrfs, linux-ext4,
linux-xfs
On Sun, Mar 15, 2026 at 01:04:22AM +0800, Zorro Lang wrote:
> I'm concerned that testers from other filesystems might not be familiar
> with SCRATCH_DEV_POOL, as it's typically not a requirement for their
> testing. I'm not sure if they would be willing to configure and switch
> to SCRATCH_DEV_POOL, just for these few test cases. If we can avoid making
> the pool to be a hard requirement, it might be more user-friendly for other
> fs list. Welcome feedback and review points from other filesystem mailing
> lists :)
Yes, doing this using loop devices or ramdisk is going to get us much
better coverage.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 2/9] fstests: add _mkfs_scratch_clone() helper
2026-03-16 16:15 ` Christoph Hellwig
@ 2026-03-21 12:02 ` Anand Jain
0 siblings, 0 replies; 19+ messages in thread
From: Anand Jain @ 2026-03-21 12:02 UTC (permalink / raw)
To: Christoph Hellwig, Zorro Lang
Cc: Anand Jain, fstests, linux-btrfs, linux-ext4, linux-xfs
On 17/3/26 00:15, Christoph Hellwig wrote:
> On Sun, Mar 15, 2026 at 01:04:22AM +0800, Zorro Lang wrote:
>> I'm concerned that testers from other filesystems might not be familiar
>> with SCRATCH_DEV_POOL, as it's typically not a requirement for their
>> testing. I'm not sure if they would be willing to configure and switch
>> to SCRATCH_DEV_POOL, just for these few test cases. If we can avoid making
>> the pool to be a hard requirement, it might be more user-friendly for other
>> fs list. Welcome feedback and review points from other filesystem mailing
>> lists :)
>
> Yes, doing this using loop devices or ramdisk is going to get us much
> better coverage.
Agreed. Let's stick with SCRATCH_DEV compatibility for now.
v2 is in the ML.
Thanks.
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 3/9] fstests: add _clone_mount_option() helper
2026-02-26 14:41 [PATCH 0/9] fstests: add test coverage for cloned filesystem ids Anand Jain
2026-02-26 14:41 ` [PATCH 1/9] fstests: allow SCRATCH_DEV_POOL for non-Btrfs filesystems Anand Jain
2026-02-26 14:41 ` [PATCH 2/9] fstests: add _mkfs_scratch_clone() helper Anand Jain
@ 2026-02-26 14:41 ` Anand Jain
2026-02-26 14:41 ` [PATCH 4/9] fstests: add test for inotify isolation on cloned devices Anand Jain
` (5 subsequent siblings)
8 siblings, 0 replies; 19+ messages in thread
From: Anand Jain @ 2026-02-26 14:41 UTC (permalink / raw)
To: fstests; +Cc: linux-btrfs, linux-ext4, linux-xfs
Adds _clone_mount_option() helper function to handle filesystem-specific
requirements for mounting cloned devices. Abstract the need for -o nouuid
on XFS.
Signed-off-by: Anand Jain <asj@kernel.org>
---
common/rc | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/common/rc b/common/rc
index 2253438ef0f6..438de54a467b 100644
--- a/common/rc
+++ b/common/rc
@@ -397,6 +397,14 @@ _scratch_mount_options()
$SCRATCH_DEV $SCRATCH_MNT
}
+_clone_mount_option()
+{
+ local mount_opts=""
+ [[ "$FSTYP" == "xfs" ]] && mount_opts="-o nouuid"
+
+ echo $mount_opts
+}
+
_supports_filetype()
{
local dir=$1
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 4/9] fstests: add test for inotify isolation on cloned devices
2026-02-26 14:41 [PATCH 0/9] fstests: add test coverage for cloned filesystem ids Anand Jain
` (2 preceding siblings ...)
2026-02-26 14:41 ` [PATCH 3/9] fstests: add _clone_mount_option() helper Anand Jain
@ 2026-02-26 14:41 ` Anand Jain
2026-03-01 13:07 ` Amir Goldstein
2026-02-26 14:41 ` [PATCH 5/9] fstests: verify fanotify isolation on cloned filesystems Anand Jain
` (4 subsequent siblings)
8 siblings, 1 reply; 19+ messages in thread
From: Anand Jain @ 2026-02-26 14:41 UTC (permalink / raw)
To: fstests; +Cc: linux-btrfs, linux-ext4, linux-xfs
Add a new test, to verify that the kernel correctly differentiates between
two block devices sharing the same FSID/UUID.
Signed-off-by: Anand Jain <asj@kernel.org>
---
common/config | 1 +
tests/generic/790 | 78 +++++++++++++++++++++++++++++++++++++++++++
tests/generic/790.out | 7 ++++
3 files changed, 86 insertions(+)
create mode 100644 tests/generic/790
create mode 100644 tests/generic/790.out
diff --git a/common/config b/common/config
index 1420e35ddfee..c08f828575a2 100644
--- a/common/config
+++ b/common/config
@@ -228,6 +228,7 @@ export BTRFS_MAP_LOGICAL_PROG=$(type -P btrfs-map-logical)
export PARTED_PROG="$(type -P parted)"
export XFS_PROPERTY_PROG="$(type -P xfs_property)"
export FSCRYPTCTL_PROG="$(type -P fscryptctl)"
+export INOTIFYWAIT_PROG="$(type -P inotifywait)"
# udev wait functions.
#
diff --git a/tests/generic/790 b/tests/generic/790
new file mode 100644
index 000000000000..3809fced622d
--- /dev/null
+++ b/tests/generic/790
@@ -0,0 +1,78 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2026 Anand Jain <asj@kernel.org>. All Rights Reserved.
+#
+# FS QA Test 790
+#
+# Verify if the kernel or userspace becomes confused when two block devices
+# share the same fid/fsid/uuid. Create inotify on both original and cloned
+# filesystem. Monitor the notification in the respective logs.
+
+. ./common/preamble
+
+_begin_fstest auto quick mount clone
+
+_require_test
+_require_scratch_dev_pool 2
+_require_command "$INOTIFYWAIT_PROG" inotifywait
+
+_cleanup()
+{
+ cd /
+ rm -r -f $tmp.*
+ umount $mnt1 $mnt2 2>/dev/null
+ _scratch_dev_pool_put
+}
+
+_scratch_dev_pool_get 2
+_scratch_mkfs_sized_clone >$seqres.full 2>&1
+devs=($SCRATCH_DEV_POOL)
+mnt2=$TEST_DIR/mnt2
+mkdir -p $mnt2
+
+_scratch_mount $(_clone_mount_option)
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
+ _fail "Failed to mount dev2"
+
+log1=$tmp.inotify1
+log2=$tmp.inotify2
+
+echo "Setup inotify watchers on both SCRATCH_MNT and mnt2"
+$INOTIFYWAIT_PROG -m -e create --format '%f' $SCRATCH_MNT > $log1 2>&1 &
+pid1=$!
+$INOTIFYWAIT_PROG -m -e create --format '%f' $mnt2 > $log2 2>&1 &
+pid2=$!
+sleep 2
+
+echo "Trigger file creation on SCRATCH_MNT"
+touch $SCRATCH_MNT/file_on_scratch_mnt
+sync
+sleep 1
+
+echo "Trigger file creation on mnt2"
+touch $mnt2/file_on_mnt2
+sync
+sleep 1
+
+echo "Verify inotify isolation"
+kill $pid1 $pid2
+wait $pid1 $pid2 2>/dev/null
+
+if grep -q "file_on_scratch_mnt" $log1 && ! grep -q "file_on_mnt2" $log1; then
+ echo "SUCCESS: SCRATCH_MNT events isolated."
+else
+ echo "FAIL: SCRATCH_MNT inotify confusion!"
+ [ ! -s $log1 ] && echo " - SCRATCH_MNT received no events."
+ grep -q "file_on_mnt2" $log1 && echo " - SCRATCH_MNT received event from mnt2."
+fi
+
+if grep -q "file_on_mnt2" $log2 && ! grep -q "file_on_scratch_mnt" $log2; then
+ echo "SUCCESS: mnt2 events isolated."
+else
+ echo "FAIL: mnt2 inotify confusion!"
+ [ ! -s $log2 ] && echo " - mnt2 received no events."
+ grep -q "file_on_scratch_mnt" $log2 && echo " - mnt2 received event from SCRATCH_MNT."
+fi
+
+status=0
+exit
diff --git a/tests/generic/790.out b/tests/generic/790.out
new file mode 100644
index 000000000000..3c92c34ffbda
--- /dev/null
+++ b/tests/generic/790.out
@@ -0,0 +1,7 @@
+QA output created by 790
+Setup inotify watchers on both SCRATCH_MNT and mnt2
+Trigger file creation on SCRATCH_MNT
+Trigger file creation on mnt2
+Verify inotify isolation
+SUCCESS: SCRATCH_MNT events isolated.
+SUCCESS: mnt2 events isolated.
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH 4/9] fstests: add test for inotify isolation on cloned devices
2026-02-26 14:41 ` [PATCH 4/9] fstests: add test for inotify isolation on cloned devices Anand Jain
@ 2026-03-01 13:07 ` Amir Goldstein
2026-03-02 13:24 ` Anand Jain
0 siblings, 1 reply; 19+ messages in thread
From: Amir Goldstein @ 2026-03-01 13:07 UTC (permalink / raw)
To: Anand Jain; +Cc: fstests, linux-btrfs, linux-ext4, linux-xfs, Jan Kara
On Thu, Feb 26, 2026 at 10:41:45PM +0800, Anand Jain wrote:
> Add a new test, to verify that the kernel correctly differentiates between
> two block devices sharing the same FSID/UUID.
>
> Signed-off-by: Anand Jain <asj@kernel.org>
> ---
> common/config | 1 +
> tests/generic/790 | 78 +++++++++++++++++++++++++++++++++++++++++++
> tests/generic/790.out | 7 ++++
> 3 files changed, 86 insertions(+)
> create mode 100644 tests/generic/790
> create mode 100644 tests/generic/790.out
>
> diff --git a/common/config b/common/config
> index 1420e35ddfee..c08f828575a2 100644
> --- a/common/config
> +++ b/common/config
> @@ -228,6 +228,7 @@ export BTRFS_MAP_LOGICAL_PROG=$(type -P btrfs-map-logical)
> export PARTED_PROG="$(type -P parted)"
> export XFS_PROPERTY_PROG="$(type -P xfs_property)"
> export FSCRYPTCTL_PROG="$(type -P fscryptctl)"
> +export INOTIFYWAIT_PROG="$(type -P inotifywait)"
>
> # udev wait functions.
> #
> diff --git a/tests/generic/790 b/tests/generic/790
> new file mode 100644
> index 000000000000..3809fced622d
> --- /dev/null
> +++ b/tests/generic/790
> @@ -0,0 +1,78 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2026 Anand Jain <asj@kernel.org>. All Rights Reserved.
> +#
> +# FS QA Test 790
> +#
> +# Verify if the kernel or userspace becomes confused when two block devices
> +# share the same fid/fsid/uuid. Create inotify on both original and cloned
> +# filesystem. Monitor the notification in the respective logs.
> +
> +. ./common/preamble
> +
> +_begin_fstest auto quick mount clone
> +
> +_require_test
> +_require_scratch_dev_pool 2
> +_require_command "$INOTIFYWAIT_PROG" inotifywait
> +
> +_cleanup()
> +{
> + cd /
> + rm -r -f $tmp.*
> + umount $mnt1 $mnt2 2>/dev/null
> + _scratch_dev_pool_put
> +}
> +
> +_scratch_dev_pool_get 2
> +_scratch_mkfs_sized_clone >$seqres.full 2>&1
> +devs=($SCRATCH_DEV_POOL)
> +mnt2=$TEST_DIR/mnt2
> +mkdir -p $mnt2
> +
> +_scratch_mount $(_clone_mount_option)
> +_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
> + _fail "Failed to mount dev2"
> +
> +log1=$tmp.inotify1
> +log2=$tmp.inotify2
> +
> +echo "Setup inotify watchers on both SCRATCH_MNT and mnt2"
> +$INOTIFYWAIT_PROG -m -e create --format '%f' $SCRATCH_MNT > $log1 2>&1 &
> +pid1=$!
> +$INOTIFYWAIT_PROG -m -e create --format '%f' $mnt2 > $log2 2>&1 &
> +pid2=$!
> +sleep 2
> +
> +echo "Trigger file creation on SCRATCH_MNT"
> +touch $SCRATCH_MNT/file_on_scratch_mnt
> +sync
> +sleep 1
> +
> +echo "Trigger file creation on mnt2"
> +touch $mnt2/file_on_mnt2
> +sync
> +sleep 1
> +
> +echo "Verify inotify isolation"
> +kill $pid1 $pid2
> +wait $pid1 $pid2 2>/dev/null
I think you also need to take care of killing the bg process
in _cleanup() so that the test could be cleanly aborted.
Thanks,
Amir.
> +
> +if grep -q "file_on_scratch_mnt" $log1 && ! grep -q "file_on_mnt2" $log1; then
> + echo "SUCCESS: SCRATCH_MNT events isolated."
> +else
> + echo "FAIL: SCRATCH_MNT inotify confusion!"
> + [ ! -s $log1 ] && echo " - SCRATCH_MNT received no events."
> + grep -q "file_on_mnt2" $log1 && echo " - SCRATCH_MNT received event from mnt2."
> +fi
> +
> +if grep -q "file_on_mnt2" $log2 && ! grep -q "file_on_scratch_mnt" $log2; then
> + echo "SUCCESS: mnt2 events isolated."
> +else
> + echo "FAIL: mnt2 inotify confusion!"
> + [ ! -s $log2 ] && echo " - mnt2 received no events."
> + grep -q "file_on_scratch_mnt" $log2 && echo " - mnt2 received event from SCRATCH_MNT."
> +fi
> +
> +status=0
> +exit
> diff --git a/tests/generic/790.out b/tests/generic/790.out
> new file mode 100644
> index 000000000000..3c92c34ffbda
> --- /dev/null
> +++ b/tests/generic/790.out
> @@ -0,0 +1,7 @@
> +QA output created by 790
> +Setup inotify watchers on both SCRATCH_MNT and mnt2
> +Trigger file creation on SCRATCH_MNT
> +Trigger file creation on mnt2
> +Verify inotify isolation
> +SUCCESS: SCRATCH_MNT events isolated.
> +SUCCESS: mnt2 events isolated.
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH 4/9] fstests: add test for inotify isolation on cloned devices
2026-03-01 13:07 ` Amir Goldstein
@ 2026-03-02 13:24 ` Anand Jain
0 siblings, 0 replies; 19+ messages in thread
From: Anand Jain @ 2026-03-02 13:24 UTC (permalink / raw)
To: Amir Goldstein, Anand Jain
Cc: fstests, linux-btrfs, linux-ext4, linux-xfs, Jan Kara
>> +_cleanup()
>> +{
>> + cd /
>> + rm -r -f $tmp.*
>> + umount $mnt1 $mnt2 2>/dev/null
>> + _scratch_dev_pool_put
>> +}
>> +
>> +_scratch_dev_pool_get 2
>> +_scratch_mkfs_sized_clone >$seqres.full 2>&1
>> +devs=($SCRATCH_DEV_POOL)
>> +mnt2=$TEST_DIR/mnt2
>> +mkdir -p $mnt2
>> +
>> +_scratch_mount $(_clone_mount_option)
>> +_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
>> + _fail "Failed to mount dev2"
>> +
>> +log1=$tmp.inotify1
>> +log2=$tmp.inotify2
>> +
>> +echo "Setup inotify watchers on both SCRATCH_MNT and mnt2"
>> +$INOTIFYWAIT_PROG -m -e create --format '%f' $SCRATCH_MNT > $log1 2>&1 &
>> +pid1=$!
>> +$INOTIFYWAIT_PROG -m -e create --format '%f' $mnt2 > $log2 2>&1 &
>> +pid2=$!
>> +sleep 2
>> +
>> +echo "Trigger file creation on SCRATCH_MNT"
>> +touch $SCRATCH_MNT/file_on_scratch_mnt
>> +sync
>> +sleep 1
>> +
>> +echo "Trigger file creation on mnt2"
>> +touch $mnt2/file_on_mnt2
>> +sync
>> +sleep 1
>> +
>> +echo "Verify inotify isolation"
>> +kill $pid1 $pid2
>> +wait $pid1 $pid2 2>/dev/null
>
> I think you also need to take care of killing the bg process
> in _cleanup() so that the test could be cleanly aborted.
You are right, SIGINT can terminate the testcase at any point, we need
kill(1) in _cleanup().
I'll fix this in v2.
Thanks, Anand
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 5/9] fstests: verify fanotify isolation on cloned filesystems
2026-02-26 14:41 [PATCH 0/9] fstests: add test coverage for cloned filesystem ids Anand Jain
` (3 preceding siblings ...)
2026-02-26 14:41 ` [PATCH 4/9] fstests: add test for inotify isolation on cloned devices Anand Jain
@ 2026-02-26 14:41 ` Anand Jain
2026-03-01 13:15 ` Amir Goldstein
2026-02-26 14:41 ` [PATCH 6/9] fstests: verify f_fsid for " Anand Jain
` (3 subsequent siblings)
8 siblings, 1 reply; 19+ messages in thread
From: Anand Jain @ 2026-02-26 14:41 UTC (permalink / raw)
To: fstests; +Cc: linux-btrfs, linux-ext4, linux-xfs
Verify that fanotify events are correctly routed to the appropriate
watcher when cloned filesystems are mounted.
Helps verify kernel's event notification distinguishes between devices
sharing the same FSID/UUID.
Signed-off-by: Anand Jain <asj@kernel.org>
---
.gitignore | 1 +
src/Makefile | 2 +-
src/fanotify.c | 66 +++++++++++++++++++++++++++++++++
tests/generic/791 | 86 +++++++++++++++++++++++++++++++++++++++++++
tests/generic/791.out | 7 ++++
5 files changed, 161 insertions(+), 1 deletion(-)
create mode 100644 src/fanotify.c
create mode 100644 tests/generic/791
create mode 100644 tests/generic/791.out
diff --git a/.gitignore b/.gitignore
index 82c57f415301..7f91310ce58b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -212,6 +212,7 @@ tags
/src/dio-writeback-race
/src/unlink-fsync
/src/file_attr
+/src/fanotify
# Symlinked files
/tests/generic/035.out
diff --git a/src/Makefile b/src/Makefile
index d0a4106e6be8..ff71cde936a7 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -36,7 +36,7 @@ LINUX_TARGETS = xfsctl bstat t_mtab getdevicesize preallo_rw_pattern_reader \
fscrypt-crypt-util bulkstat_null_ocount splice-test chprojid_fail \
detached_mounts_propagation ext4_resize t_readdir_3 splice2pipe \
uuid_ioctl t_snapshot_deleted_subvolume fiemap-fault min_dio_alignment \
- rw_hint
+ rw_hint fanotify
EXTRA_EXECS = dmerror fill2attr fill2fs fill2fs_check scaleread.sh \
btrfs_crc32c_forged_name.py popdir.pl popattr.py \
diff --git a/src/fanotify.c b/src/fanotify.c
new file mode 100644
index 000000000000..e30c48dc0e52
--- /dev/null
+++ b/src/fanotify.c
@@ -0,0 +1,66 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) 2026 Anand Jain <asj@kernel.org>. All Rights Reserved.
+ *
+ * Simple fanotify monitor to verify mount-point event isolation.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stdint.h>
+#include <sys/fanotify.h>
+
+int main(int argc, char *argv[])
+{
+ int fd;
+ char buf[4096] __attribute__((aligned(8)));
+ setlinebuf(stdout);
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s <path>\n", argv[0]);
+ return 1;
+ }
+
+ // Initialize with FID reporting
+ fd = fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_FID, O_RDONLY);
+ if (fd < 0) {
+ perror("fanotify_init");
+ return 1;
+ }
+
+ if (fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_FILESYSTEM,
+ FAN_CREATE, AT_FDCWD, argv[1]) < 0) {
+ perror("fanotify_mark");
+ return 1;
+ }
+
+ printf("Listening for events on %s...\n", argv[1]);
+ while (1) {
+ struct fanotify_event_metadata *metadata = (struct fanotify_event_metadata *)buf;
+ ssize_t len = read(fd, buf, sizeof(buf));
+
+ if (len <= 0) break;
+
+ while (FAN_EVENT_OK(metadata, len)) {
+ // metadata_len is the offset to the first info record
+ if (metadata->event_len > metadata->metadata_len) {
+ struct fanotify_event_info_header *hdr =
+(struct fanotify_event_info_header *)((char *)metadata + metadata->metadata_len);
+
+ if (hdr->info_type == FAN_EVENT_INFO_TYPE_FID) {
+ struct fanotify_event_info_fid *fid = (struct fanotify_event_info_fid *)hdr;
+ printf("FSID: %08x%08x\n",
+ fid->fsid.val[0], fid->fsid.val[1]);
+ }
+ }
+ metadata = FAN_EVENT_NEXT(metadata, len);
+ }
+ }
+
+ fflush(stdout);
+ close(fd);
+ return 0;
+}
diff --git a/tests/generic/791 b/tests/generic/791
new file mode 100644
index 000000000000..fe8109083732
--- /dev/null
+++ b/tests/generic/791
@@ -0,0 +1,86 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2026 Anand Jain <asj@kernel.org>. All Rights Reserved.
+#
+# FS QA Test 791
+# Verify fanotify FID functionality on cloned filesystems by setting up
+# watchers and making sure notifications are in the correct logs files.
+
+. ./common/preamble
+
+_begin_fstest auto quick mount clone
+
+_require_test
+_require_scratch_dev_pool 2
+
+[ "$FSTYP" = "ext4" ] && _fixed_by_kernel_commit xxxxxxxxxxxx \
+ "ext4: derive f_fsid from block device to avoid collisions"
+
+_cleanup()
+{
+ cd /
+ rm -r -f $tmp.*
+ umount $mnt1 $mnt2 2>/dev/null
+ _scratch_dev_pool_put
+}
+
+_scratch_dev_pool_get 2
+_scratch_mkfs_sized_clone >$seqres.full 2>&1
+devs=($SCRATCH_DEV_POOL)
+mnt2=$TEST_DIR/mnt2
+mkdir -p $mnt2
+
+_scratch_mount $(_clone_mount_option)
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
+ _fail "Failed to mount dev2"
+
+fsid1=$(stat -f -c "%i" $SCRATCH_MNT)
+fsid2=$(stat -f -c "%i" $mnt2)
+
+[[ "$fsid1" == "$fsid2" ]] && \
+ _notrun "Require clone filesystem with unique f_fsid"
+
+log1=$tmp.fanotify1
+log2=$tmp.fanotify2
+
+echo "Setup FID fanotify watchers on both SCRATCH_MNT and mnt2"
+$here/src/fanotify $SCRATCH_MNT > $log1 2>&1 &
+pid1=$!
+$here/src/fanotify $mnt2 > $log2 2>&1 &
+pid2=$!
+sleep 2
+
+echo "Trigger file creation on SCRATCH_MNT"
+touch $SCRATCH_MNT/file_on_scratch_mnt
+sync
+sleep 1
+
+echo "Trigger file creation on mnt2"
+touch $mnt2/file_on_mnt2
+sync
+sleep 1
+
+echo "Verify fsid in the fanotify"
+kill $pid1 $pid2
+wait $pid1 $pid2 2>/dev/null
+
+echo fsid1=$fsid1 fsid2=$fsid2 >> $seqres.full
+cat $log1 >> $seqres.full
+cat $log2 >> $seqres.full
+
+if grep -q "${fsid1}" $log1 && ! grep -q "${fsid2}" $log1; then
+ echo "SUCCESS: SCRATCH_MNT events found"
+else
+ [ ! -s $log1 ] && echo " - SCRATCH_MNT received no events."
+ grep -q "${fsid2}" $log1 && echo " - SCRATCH_MNT received event from mnt2."
+fi
+
+if grep -q "${fsid2}" $log2 && ! grep -q "${fsid1}" $log2; then
+ echo "SUCCESS: mnt2 events found"
+else
+ [ ! -s $log2 ] && echo " - mnt2 received no events."
+ grep -q "${fsid1}" $log2 && echo " - mnt2 received event from SCRATCH_MNT."
+fi
+
+status=0
+exit
diff --git a/tests/generic/791.out b/tests/generic/791.out
new file mode 100644
index 000000000000..9725c99bcb4b
--- /dev/null
+++ b/tests/generic/791.out
@@ -0,0 +1,7 @@
+QA output created by 791
+Setup FID fanotify watchers on both SCRATCH_MNT and mnt2
+Trigger file creation on SCRATCH_MNT
+Trigger file creation on mnt2
+Verify fsid in the fanotify
+SUCCESS: SCRATCH_MNT events found
+SUCCESS: mnt2 events found
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH 5/9] fstests: verify fanotify isolation on cloned filesystems
2026-02-26 14:41 ` [PATCH 5/9] fstests: verify fanotify isolation on cloned filesystems Anand Jain
@ 2026-03-01 13:15 ` Amir Goldstein
2026-03-02 13:30 ` Anand Jain
0 siblings, 1 reply; 19+ messages in thread
From: Amir Goldstein @ 2026-03-01 13:15 UTC (permalink / raw)
To: Anand Jain; +Cc: fstests, linux-btrfs, linux-ext4, linux-xfs, Jan Kara
On Thu, Feb 26, 2026 at 10:41:46PM +0800, Anand Jain wrote:
> Verify that fanotify events are correctly routed to the appropriate
> watcher when cloned filesystems are mounted.
> Helps verify kernel's event notification distinguishes between devices
> sharing the same FSID/UUID.
>
> Signed-off-by: Anand Jain <asj@kernel.org>
> ---
> .gitignore | 1 +
> src/Makefile | 2 +-
> src/fanotify.c | 66 +++++++++++++++++++++++++++++++++
> tests/generic/791 | 86 +++++++++++++++++++++++++++++++++++++++++++
> tests/generic/791.out | 7 ++++
> 5 files changed, 161 insertions(+), 1 deletion(-)
> create mode 100644 src/fanotify.c
> create mode 100644 tests/generic/791
> create mode 100644 tests/generic/791.out
>
> diff --git a/.gitignore b/.gitignore
> index 82c57f415301..7f91310ce58b 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -212,6 +212,7 @@ tags
> /src/dio-writeback-race
> /src/unlink-fsync
> /src/file_attr
> +/src/fanotify
>
> # Symlinked files
> /tests/generic/035.out
> diff --git a/src/Makefile b/src/Makefile
> index d0a4106e6be8..ff71cde936a7 100644
> --- a/src/Makefile
> +++ b/src/Makefile
> @@ -36,7 +36,7 @@ LINUX_TARGETS = xfsctl bstat t_mtab getdevicesize preallo_rw_pattern_reader \
> fscrypt-crypt-util bulkstat_null_ocount splice-test chprojid_fail \
> detached_mounts_propagation ext4_resize t_readdir_3 splice2pipe \
> uuid_ioctl t_snapshot_deleted_subvolume fiemap-fault min_dio_alignment \
> - rw_hint
> + rw_hint fanotify
Check if you already have fsnotifywait installed on your system
most likely you do. It was added to inotify-tools quite some time ago.
Could save you from adding a custom prog.
Not 100% sure about fsnotifywait, but quite sure that
fsnotifywatch --verbose prints the FSID of events.
Thanks,
Amir.
>
> EXTRA_EXECS = dmerror fill2attr fill2fs fill2fs_check scaleread.sh \
> btrfs_crc32c_forged_name.py popdir.pl popattr.py \
> diff --git a/src/fanotify.c b/src/fanotify.c
> new file mode 100644
> index 000000000000..e30c48dc0e52
> --- /dev/null
> +++ b/src/fanotify.c
> @@ -0,0 +1,66 @@
> +/*
> + * SPDX-License-Identifier: GPL-2.0
> + * Copyright (c) 2026 Anand Jain <asj@kernel.org>. All Rights Reserved.
> + *
> + * Simple fanotify monitor to verify mount-point event isolation.
> + */
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <fcntl.h>
> +#include <unistd.h>
> +#include <errno.h>
> +#include <string.h>
> +#include <stdint.h>
> +#include <sys/fanotify.h>
> +
> +int main(int argc, char *argv[])
> +{
> + int fd;
> + char buf[4096] __attribute__((aligned(8)));
> + setlinebuf(stdout);
> +
> + if (argc < 2) {
> + fprintf(stderr, "Usage: %s <path>\n", argv[0]);
> + return 1;
> + }
> +
> + // Initialize with FID reporting
> + fd = fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_FID, O_RDONLY);
> + if (fd < 0) {
> + perror("fanotify_init");
> + return 1;
> + }
> +
> + if (fanotify_mark(fd, FAN_MARK_ADD | FAN_MARK_FILESYSTEM,
> + FAN_CREATE, AT_FDCWD, argv[1]) < 0) {
> + perror("fanotify_mark");
> + return 1;
> + }
> +
> + printf("Listening for events on %s...\n", argv[1]);
> + while (1) {
> + struct fanotify_event_metadata *metadata = (struct fanotify_event_metadata *)buf;
> + ssize_t len = read(fd, buf, sizeof(buf));
> +
> + if (len <= 0) break;
> +
> + while (FAN_EVENT_OK(metadata, len)) {
> + // metadata_len is the offset to the first info record
> + if (metadata->event_len > metadata->metadata_len) {
> + struct fanotify_event_info_header *hdr =
> +(struct fanotify_event_info_header *)((char *)metadata + metadata->metadata_len);
> +
> + if (hdr->info_type == FAN_EVENT_INFO_TYPE_FID) {
> + struct fanotify_event_info_fid *fid = (struct fanotify_event_info_fid *)hdr;
> + printf("FSID: %08x%08x\n",
> + fid->fsid.val[0], fid->fsid.val[1]);
> + }
> + }
> + metadata = FAN_EVENT_NEXT(metadata, len);
> + }
> + }
> +
> + fflush(stdout);
> + close(fd);
> + return 0;
> +}
> diff --git a/tests/generic/791 b/tests/generic/791
> new file mode 100644
> index 000000000000..fe8109083732
> --- /dev/null
> +++ b/tests/generic/791
> @@ -0,0 +1,86 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2026 Anand Jain <asj@kernel.org>. All Rights Reserved.
> +#
> +# FS QA Test 791
> +# Verify fanotify FID functionality on cloned filesystems by setting up
> +# watchers and making sure notifications are in the correct logs files.
> +
> +. ./common/preamble
> +
> +_begin_fstest auto quick mount clone
> +
> +_require_test
> +_require_scratch_dev_pool 2
> +
> +[ "$FSTYP" = "ext4" ] && _fixed_by_kernel_commit xxxxxxxxxxxx \
> + "ext4: derive f_fsid from block device to avoid collisions"
> +
> +_cleanup()
> +{
> + cd /
> + rm -r -f $tmp.*
> + umount $mnt1 $mnt2 2>/dev/null
> + _scratch_dev_pool_put
> +}
> +
> +_scratch_dev_pool_get 2
> +_scratch_mkfs_sized_clone >$seqres.full 2>&1
> +devs=($SCRATCH_DEV_POOL)
> +mnt2=$TEST_DIR/mnt2
> +mkdir -p $mnt2
> +
> +_scratch_mount $(_clone_mount_option)
> +_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
> + _fail "Failed to mount dev2"
> +
> +fsid1=$(stat -f -c "%i" $SCRATCH_MNT)
> +fsid2=$(stat -f -c "%i" $mnt2)
> +
> +[[ "$fsid1" == "$fsid2" ]] && \
> + _notrun "Require clone filesystem with unique f_fsid"
> +
> +log1=$tmp.fanotify1
> +log2=$tmp.fanotify2
> +
> +echo "Setup FID fanotify watchers on both SCRATCH_MNT and mnt2"
> +$here/src/fanotify $SCRATCH_MNT > $log1 2>&1 &
> +pid1=$!
> +$here/src/fanotify $mnt2 > $log2 2>&1 &
> +pid2=$!
> +sleep 2
> +
> +echo "Trigger file creation on SCRATCH_MNT"
> +touch $SCRATCH_MNT/file_on_scratch_mnt
> +sync
> +sleep 1
> +
> +echo "Trigger file creation on mnt2"
> +touch $mnt2/file_on_mnt2
> +sync
> +sleep 1
> +
> +echo "Verify fsid in the fanotify"
> +kill $pid1 $pid2
> +wait $pid1 $pid2 2>/dev/null
> +
> +echo fsid1=$fsid1 fsid2=$fsid2 >> $seqres.full
> +cat $log1 >> $seqres.full
> +cat $log2 >> $seqres.full
> +
> +if grep -q "${fsid1}" $log1 && ! grep -q "${fsid2}" $log1; then
> + echo "SUCCESS: SCRATCH_MNT events found"
> +else
> + [ ! -s $log1 ] && echo " - SCRATCH_MNT received no events."
> + grep -q "${fsid2}" $log1 && echo " - SCRATCH_MNT received event from mnt2."
> +fi
> +
> +if grep -q "${fsid2}" $log2 && ! grep -q "${fsid1}" $log2; then
> + echo "SUCCESS: mnt2 events found"
> +else
> + [ ! -s $log2 ] && echo " - mnt2 received no events."
> + grep -q "${fsid1}" $log2 && echo " - mnt2 received event from SCRATCH_MNT."
> +fi
> +
> +status=0
> +exit
> diff --git a/tests/generic/791.out b/tests/generic/791.out
> new file mode 100644
> index 000000000000..9725c99bcb4b
> --- /dev/null
> +++ b/tests/generic/791.out
> @@ -0,0 +1,7 @@
> +QA output created by 791
> +Setup FID fanotify watchers on both SCRATCH_MNT and mnt2
> +Trigger file creation on SCRATCH_MNT
> +Trigger file creation on mnt2
> +Verify fsid in the fanotify
> +SUCCESS: SCRATCH_MNT events found
> +SUCCESS: mnt2 events found
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH 5/9] fstests: verify fanotify isolation on cloned filesystems
2026-03-01 13:15 ` Amir Goldstein
@ 2026-03-02 13:30 ` Anand Jain
0 siblings, 0 replies; 19+ messages in thread
From: Anand Jain @ 2026-03-02 13:30 UTC (permalink / raw)
To: Amir Goldstein, Anand Jain
Cc: fstests, linux-btrfs, linux-ext4, linux-xfs, Jan Kara
>> diff --git a/src/Makefile b/src/Makefile
>> index d0a4106e6be8..ff71cde936a7 100644
>> --- a/src/Makefile
>> +++ b/src/Makefile
>> @@ -36,7 +36,7 @@ LINUX_TARGETS = xfsctl bstat t_mtab getdevicesize preallo_rw_pattern_reader \
>> fscrypt-crypt-util bulkstat_null_ocount splice-test chprojid_fail \
>> detached_mounts_propagation ext4_resize t_readdir_3 splice2pipe \
>> uuid_ioctl t_snapshot_deleted_subvolume fiemap-fault min_dio_alignment \
>> - rw_hint
>> + rw_hint fanotify
>
> Check if you already have fsnotifywait installed on your system
> most likely you do. It was added to inotify-tools quite some time ago.
> Could save you from adding a custom prog.
> Not 100% sure about fsnotifywait, but quite sure that
> fsnotifywatch --verbose prints the FSID of events.
>
I missed that command. V2 switched to using fsnotifywait.
V2 is not sent yet, I'll wait for any further comments.
Thanks for the review.
Anand
> Thanks,
> Amir.
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 6/9] fstests: verify f_fsid for cloned filesystems
2026-02-26 14:41 [PATCH 0/9] fstests: add test coverage for cloned filesystem ids Anand Jain
` (4 preceding siblings ...)
2026-02-26 14:41 ` [PATCH 5/9] fstests: verify fanotify isolation on cloned filesystems Anand Jain
@ 2026-02-26 14:41 ` Anand Jain
2026-02-26 14:41 ` [PATCH 7/9] fstests: verify libblkid resolution of duplicate UUIDs Anand Jain
` (2 subsequent siblings)
8 siblings, 0 replies; 19+ messages in thread
From: Anand Jain @ 2026-02-26 14:41 UTC (permalink / raw)
To: fstests; +Cc: linux-btrfs, linux-ext4, linux-xfs
Verify that the cloned filesystem provides an f_fsid that is persistent
across mount cycles, yet unique from the original filesystem's f_fsid.
Signed-off-by: Anand Jain <asj@kernel.org>
---
tests/generic/792 | 57 +++++++++++++++++++++++++++++++++++++++++++
tests/generic/792.out | 7 ++++++
2 files changed, 64 insertions(+)
create mode 100644 tests/generic/792
create mode 100644 tests/generic/792.out
diff --git a/tests/generic/792 b/tests/generic/792
new file mode 100644
index 000000000000..3a2f463dc76e
--- /dev/null
+++ b/tests/generic/792
@@ -0,0 +1,57 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2026 Anand Jain <asj@kernel.org>. All Rights Reserved.
+#
+# FS QA Test 792
+# Verify f_fsid and s_uuid of cloned filesystems across mount cycle.
+
+. ./common/preamble
+
+_begin_fstest auto quick mount clone
+
+_require_test
+_require_scratch_dev_pool 2
+
+[ "$FSTYP" = "btrfs" ] && _fixed_by_kernel_commit xxxxxxxxxxxx \
+ "btrfs: use on-disk uuid for s_uuid in temp_fsid mounts"
+[ "$FSTYP" = "btrfs" ] && _fixed_by_kernel_commit xxxxxxxxxxxx \
+ "btrfs: derive f_fsid from on-disk fsuuid and dev_t"
+
+_cleanup()
+{
+ cd /
+ rm -r -f $tmp.*
+ umount $mnt2 2>/dev/null
+ _scratch_dev_pool_put
+}
+
+_scratch_dev_pool_get 2
+_scratch_mkfs_sized_clone >$seqres.full 2>&1
+devs=($SCRATCH_DEV_POOL)
+mnt2=$TEST_DIR/mnt2
+mkdir -p $mnt2
+
+_scratch_mount $(_clone_mount_option)
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
+ _fail "Failed to mount dev2"
+
+fsid_scratch=$(stat -f -c "%i" $SCRATCH_MNT)
+fsid_clone=$(stat -f -c "%i" $mnt2)
+
+echo "**** fsid initially ****"
+echo $fsid_scratch | sed -e "s/$fsid_scratch/FSID_SCRATCH/g"
+echo $fsid_clone | sed -e "s/$fsid_clone/FSID_CLONE/g"
+
+# Make sure fsid still match across a mount cycle, also reverse the order.
+echo "**** fsid after mount cycle ****"
+_scratch_unmount
+_unmount $mnt2
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
+ _fail "Failed to mount dev2"
+_scratch_mount $(_clone_mount_option)
+
+stat -f -c "%i" $SCRATCH_MNT | sed -e "s/$fsid_scratch/FSID_SCRATCH/g"
+stat -f -c "%i" $mnt2 | sed -e "s/$fsid_clone/FSID_CLONE/g"
+
+status=0
+exit
diff --git a/tests/generic/792.out b/tests/generic/792.out
new file mode 100644
index 000000000000..27ecbce2225e
--- /dev/null
+++ b/tests/generic/792.out
@@ -0,0 +1,7 @@
+QA output created by 792
+**** fsid initially ****
+FSID_SCRATCH
+FSID_CLONE
+**** fsid after mount cycle ****
+FSID_SCRATCH
+FSID_CLONE
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 7/9] fstests: verify libblkid resolution of duplicate UUIDs
2026-02-26 14:41 [PATCH 0/9] fstests: add test coverage for cloned filesystem ids Anand Jain
` (5 preceding siblings ...)
2026-02-26 14:41 ` [PATCH 6/9] fstests: verify f_fsid for " Anand Jain
@ 2026-02-26 14:41 ` Anand Jain
2026-02-26 14:41 ` [PATCH 8/9] fstests: verify IMA isolation on cloned filesystems Anand Jain
2026-02-26 14:41 ` [PATCH 9/9] fstests: verify exportfs file handles " Anand Jain
8 siblings, 0 replies; 19+ messages in thread
From: Anand Jain @ 2026-02-26 14:41 UTC (permalink / raw)
To: fstests; +Cc: linux-btrfs, linux-ext4, linux-xfs
Verify how findmnt, df (libblkid) resolve device paths when multiple
block devices share the same FSUUID.
Signed-off-by: Anand Jain <asj@kernel.org>
---
tests/generic/793 | 73 +++++++++++++++++++++++++++++++++++++++++++
tests/generic/793.out | 22 +++++++++++++
2 files changed, 95 insertions(+)
create mode 100644 tests/generic/793
create mode 100644 tests/generic/793.out
diff --git a/tests/generic/793 b/tests/generic/793
new file mode 100644
index 000000000000..dd80212fad73
--- /dev/null
+++ b/tests/generic/793
@@ -0,0 +1,73 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2026 Anand Jain <asj@kernel.org>. All Rights Reserved.
+#
+# FS QA Test 793
+# Verify how libblkid resolve devices when multiple devices sharing the
+# same FSUUID.
+
+. ./common/preamble
+. ./common/filter
+
+_begin_fstest auto quick mount clone
+
+_require_test
+_require_scratch_dev_pool 2
+
+_cleanup()
+{
+ cd /
+ rm -r -f $tmp.*
+ umount $mnt2 2>/dev/null
+ _scratch_dev_pool_put
+}
+
+filter_pool()
+{
+ _filter_scratch | \
+ sed -e "s|${devs[1]}|DEV2|g" \
+ -e "s|$mnt2|MNT2|g" | \
+ _filter_spaces
+}
+
+print_info()
+{
+ local mntpt=$1
+ local tgt=$(findmnt -no SOURCE $mntpt)
+ local fsuuid=$(blkid -s UUID -o value $tgt)
+
+ echo "mntpt=$mntpt tgt=$tgt fsuuid=$fsuuid" >> $seqres.full
+ echo
+ findmnt -o SOURCE,TARGET,UUID "$tgt" | tail -n +2 | \
+ sed -e "s/$fsuuid/FSUUID/g" | filter_pool
+ awk -v dev="$tgt" '$1 == dev { print $1, $2 }' /proc/self/mounts | \
+ filter_pool
+ df --all --output=source,target "$tgt" | tail -n +2 | filter_pool
+ echo
+}
+
+_scratch_dev_pool_get 2
+_scratch_mkfs_sized_clone >$seqres.full 2>&1
+devs=($SCRATCH_DEV_POOL)
+mnt2=$TEST_DIR/mnt2
+mkdir -p $mnt2
+
+_scratch_mount $(_clone_mount_option)
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
+ _fail "Failed to mount dev2"
+
+print_info $SCRATCH_MNT
+print_info $mnt2
+
+echo "**** mount cycle ****"
+_scratch_unmount
+_unmount $mnt2
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
+ _fail "Failed to mount dev2"
+_scratch_mount $(_clone_mount_option)
+
+print_info $SCRATCH_MNT
+print_info $mnt2
+
+status=0
+exit
diff --git a/tests/generic/793.out b/tests/generic/793.out
new file mode 100644
index 000000000000..4c7c349ec4ed
--- /dev/null
+++ b/tests/generic/793.out
@@ -0,0 +1,22 @@
+QA output created by 793
+
+SCRATCH_DEV SCRATCH_MNT FSUUID
+SCRATCH_DEV SCRATCH_MNT
+SCRATCH_DEV SCRATCH_MNT
+
+
+DEV2 MNT2 FSUUID
+DEV2 MNT2
+DEV2 MNT2
+
+**** mount cycle ****
+
+SCRATCH_DEV SCRATCH_MNT FSUUID
+SCRATCH_DEV SCRATCH_MNT
+SCRATCH_DEV SCRATCH_MNT
+
+
+DEV2 MNT2 FSUUID
+DEV2 MNT2
+DEV2 MNT2
+
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 8/9] fstests: verify IMA isolation on cloned filesystems
2026-02-26 14:41 [PATCH 0/9] fstests: add test coverage for cloned filesystem ids Anand Jain
` (6 preceding siblings ...)
2026-02-26 14:41 ` [PATCH 7/9] fstests: verify libblkid resolution of duplicate UUIDs Anand Jain
@ 2026-02-26 14:41 ` Anand Jain
2026-02-26 14:41 ` [PATCH 9/9] fstests: verify exportfs file handles " Anand Jain
8 siblings, 0 replies; 19+ messages in thread
From: Anand Jain @ 2026-02-26 14:41 UTC (permalink / raw)
To: fstests; +Cc: linux-btrfs, linux-ext4, linux-xfs
Add testcase to verify IMA measurement isolation when multiple devices
share the same FSUUID.
Signed-off-by: Anand Jain <asj@kernel.org>
---
tests/generic/794 | 101 ++++++++++++++++++++++++++++++++++++++++++
tests/generic/794.out | 10 +++++
2 files changed, 111 insertions(+)
create mode 100644 tests/generic/794
create mode 100644 tests/generic/794.out
diff --git a/tests/generic/794 b/tests/generic/794
new file mode 100644
index 000000000000..e3bf3f9c6a7e
--- /dev/null
+++ b/tests/generic/794
@@ -0,0 +1,101 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2026 Anand Jain <asj@kernel.org>. All Rights Reserved.
+#
+# FS QA Test 794
+# Verify IMA isolation on cloned filesystems:
+# . Mount two devices sharing the same FSUUID (cloned).
+# . Apply an IMA policy to measure files based on that FSUUID.
+# . Create unique files on each mount point to trigger measurements.
+# . Confirm the IMA log correctly attributes events to the respective mounts.
+
+. ./common/preamble
+. ./common/filter
+
+_begin_fstest auto quick clone
+
+_require_test
+_require_scratch_dev_pool 2
+
+[ "$FSTYP" = "btrfs" ] && _fixed_by_kernel_commit xxxxxxxxxxxx \
+ "btrfs: use on-disk uuid for s_uuid in temp_fsid mounts"
+[ "$FSTYP" = "btrfs" ] && _fixed_by_kernel_commit xxxxxxxxxxxx \
+ "btrfs: derive f_fsid from on-disk fsuuid and dev_t"
+
+_cleanup()
+{
+ cd /
+ rm -r -f $tmp.*
+ umount $mnt2 2>/dev/null
+ _scratch_dev_pool_put
+}
+
+filter_pool()
+{
+ _filter_scratch | \
+ sed -e "s|${devs[1]}|DEV2|g" \
+ -e "s|$mnt2|MNT2|g" | \
+ _filter_spaces
+}
+
+do_ima()
+{
+ local ima_policy="/sys/kernel/security/ima/policy"
+ local ima_log="/sys/kernel/security/ima/ascii_runtime_measurements"
+ local fsuuid
+ local mnt=$1
+ local run_enable=$2
+
+ # Since the in-memory IMA audit log is only cleared upon reboot,
+ # use unique random filenames to avoid log collisions.
+ local foofile=$(mktemp --dry-run foobar_XXXXX)
+
+ echo $mnt $run_enable | filter_pool
+
+ [ -w "$ima_policy" ] || _notrun "IMA policy not writable"
+
+ fsuuid=$(blkid -s UUID -o value $SCRATCH_DEV)
+
+ # Load IMA policy to measure file access specifically for this
+ # filesystem UUID.
+ if [[ $run_enable -eq 1 ]]; then
+ echo "measure func=FILE_CHECK fsuuid=$fsuuid" > "$ima_policy" || \
+ _notrun "Policy rejected"
+ fi
+
+ # Create a file to trigger measurement and verify its entry in
+ # the IMA log.
+ echo "test_data" > $mnt/$foofile
+
+ # For $ima_log column entry please ref to
+ grep $foofile "$ima_log" | awk '{ print $5 }' | filter_pool | \
+ sed "s/$foofile/FOOBAR_FILE/"
+
+ echo "dbg: $mnt $fsuuid $foofile" >> $seqres.full
+ cat $ima_log | tail -1 >> $seqres.full
+ echo >> $seqres.full
+}
+
+_scratch_dev_pool_get 2
+_scratch_mkfs_sized_clone >$seqres.full 2>&1
+devs=($SCRATCH_DEV_POOL)
+mnt2=$TEST_DIR/mnt2
+mkdir -p $mnt2
+
+_scratch_mount $(_clone_mount_option)
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
+ _fail "Failed to mount dev2"
+
+do_ima $SCRATCH_MNT 1
+do_ima $mnt2 0
+
+# Btrfs uses in-memory dynamic temp_fsid
+echo mount cycle
+_unmount $mnt2
+_mount $mount_opts ${devs[1]} $mnt2 || _fail "Failed to mount dev2"
+
+do_ima $SCRATCH_MNT 0
+do_ima $mnt2 0
+
+status=0
+exit
diff --git a/tests/generic/794.out b/tests/generic/794.out
new file mode 100644
index 000000000000..026b365853e6
--- /dev/null
+++ b/tests/generic/794.out
@@ -0,0 +1,10 @@
+QA output created by 794
+SCRATCH_MNT 1
+SCRATCH_MNT/FOOBAR_FILE
+MNT2 0
+MNT2/FOOBAR_FILE
+mount cycle
+SCRATCH_MNT 0
+SCRATCH_MNT/FOOBAR_FILE
+MNT2 0
+MNT2/FOOBAR_FILE
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH 9/9] fstests: verify exportfs file handles on cloned filesystems
2026-02-26 14:41 [PATCH 0/9] fstests: add test coverage for cloned filesystem ids Anand Jain
` (7 preceding siblings ...)
2026-02-26 14:41 ` [PATCH 8/9] fstests: verify IMA isolation on cloned filesystems Anand Jain
@ 2026-02-26 14:41 ` Anand Jain
8 siblings, 0 replies; 19+ messages in thread
From: Anand Jain @ 2026-02-26 14:41 UTC (permalink / raw)
To: fstests; +Cc: linux-btrfs, linux-ext4, linux-xfs
Ensure that exportfs can correctly decode file handles on a cloned
filesystem across a mount cycle, by file handles generated on a
cloned device remain valid after mount cycle.
Signed-off-by: Anand Jain <asj@kernel.org>
---
tests/generic/795 | 67 +++++++++++++++++++++++++++++++++++++++++++
tests/generic/795.out | 2 ++
2 files changed, 69 insertions(+)
create mode 100644 tests/generic/795
create mode 100644 tests/generic/795.out
diff --git a/tests/generic/795 b/tests/generic/795
new file mode 100644
index 000000000000..b6a75e500949
--- /dev/null
+++ b/tests/generic/795
@@ -0,0 +1,67 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2026 Anand Jain <asj@kernel.org>. All Rights Reserved.
+#
+# FS QA Test No. 795
+
+. ./common/preamble
+
+_begin_fstest auto quick exportfs clone
+
+_require_test
+_require_exportfs
+_require_scratch_dev_pool 2
+_require_test_program "open_by_handle"
+
+_cleanup()
+{
+ cd /
+ rm -r -f $tmp.*
+ _unmount $mnt2 2>/dev/null
+ _scratch_dev_pool_put
+}
+
+# Create test dir and test files, encode file handles and store to tmp file
+create_test_files()
+{
+ rm -rf $testdir
+ mkdir -p $testdir
+ $here/src/open_by_handle -cwp -o $tmp.handles_file $testdir $NUMFILES
+}
+
+# Decode file handles loaded from tmp file
+test_file_handles()
+{
+ local opt=$1
+ local when=$2
+
+ echo test_file_handles after $when
+ $here/src/open_by_handle $opt -i $tmp.handles_file $mnt2 $NUMFILES
+}
+
+_scratch_dev_pool_get 2
+_scratch_mkfs_sized_clone >$seqres.full 2>&1
+devs=($SCRATCH_DEV_POOL)
+mnt2=$TEST_DIR/mnt2
+mkdir -p $mnt2
+
+_scratch_mount $(_clone_mount_option)
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
+ _fail "Failed to mount dev2"
+
+NUMFILES=1
+testdir=$mnt2/testdir
+
+# Decode file handles of files/dir after cycle mount
+create_test_files
+
+_scratch_unmount
+_unmount $mnt2
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
+ _fail "Failed to mount dev2"
+_scratch_mount $(_clone_mount_option)
+
+test_file_handles -rp "cycle mount"
+
+status=0
+exit
diff --git a/tests/generic/795.out b/tests/generic/795.out
new file mode 100644
index 000000000000..774fe7487d65
--- /dev/null
+++ b/tests/generic/795.out
@@ -0,0 +1,2 @@
+QA output created by 795
+test_file_handles after cycle mount
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread