[PATCH 4/9] fstests: add test for inotify isolation on cloned devices

Anand Jain
2026-02-26T14:42:07Z

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