Linux EXT4 FS development
 help / color / mirror / Atom feed
* [PATCH v8 0/13] fstests: add test coverage for cloned filesystem ids
@ 2026-07-25  7:38 Anand Jain
  2026-07-25  7:38 ` [PATCH v8 01/13] fstests: add _loop_image_create_clone() helper Anand Jain
                   ` (13 more replies)
  0 siblings, 14 replies; 25+ messages in thread
From: Anand Jain @ 2026-07-25  7:38 UTC (permalink / raw)
  To: fstests; +Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang,
	djwong

v8:
- _require_fs_space: double the required space (x2) to account for both source and clone
- Use proper quoting/unquoting for _mkfs_dev (Thanks Darrick)
- Call _fail() if cp fails
- _require_fanotify_function: check for kernel fsnotify support
- _require_unique_f_fsid: reorganize comments and replace 'if' with 'case' statement (Thanks Darrick)
- Add SEMANAGE_PROG variable (Thanks Darrick)
- fanotify verification: add checks for SEMANAGE_PROG and _require_fanotify_function
- Verify that the monitoring process is actually created

v7:
  https://lore.kernel.org/fstests/cover.1781694879.git.asj@kernel.org

v6:
  https://lore.kernel.org/fstests/cover.1779939330.git.asj@kernel.org

v5:
  https://lore.kernel.org/fstests/cover.1779367627.git.asj@kernel.org

v4:
  https://lore.kernel.org/fstests/cover.1777357320.git.asj@kernel.org

v3:
  https://lore.kernel.org/fstests/cover.1777281778.git.asj@kernel.org

v2:
  https://lore.kernel.org/fstests/cover.1774090817.git.asj@kernel.org

v1:
  https://lore.kernel.org/fstests/cover.1772095513.git.asj@kernel.org

This series adds fstests infrastructure and test cases to verify correct
filesystem identity when a filesystem is cloned (block-level copy).
Test covers inotify, fanotify, f_fsid, libblkid, IMA, exportfs file handles
and libblkid tools verify with metadata_uuid.
  New helpers:
   _loop_image_create_clone() and _loop_image_destroy() to help create fs and clone
   _clone_mount_option() helper to apply per-filesystem clone mount options
   _require_fanotify_function check if kernel supports fs notification
   _require_unique_f_fsid() helper to handle fs difference in fsid implementation

  New tests:
  - fanotify events are isolated between cloned filesystems
  - f_fsid is unique across cloned filesystem instances
  - libblkid correctly resolves duplicate UUIDs to distinct devices
    with and without metadata_uuid
  - IMA distinct identity for each cloned filesystem
  - exportfs file handles resolve correctly on cloned filesystems

Kernel Patches:
  Requires Btrfs kernel patches for all tests to pass.
   [1] https://lore.kernel.org/linux-btrfs/cover.1777281686.git.asj@kernel.org


Anand Jain (13):
  fstests: add _loop_image_create_clone() helper
  fstests: add _clone_mount_option() helper
  fstests: add FSNOTIFYWAIT_PROG
  fstests: add _require_fanotify_function
  fstests: add _require_unique_f_fsid() helper
  fstests: add SEMANAGE_PROG
  fstests: verify fanotify isolation on cloned filesystems
  fstests: verify f_fsid for cloned filesystems
  fstests: verify libblkid resolution of duplicate UUIDs
  fstests: verify IMA isolation on cloned filesystems
  fstests: verify exportfs file handles on cloned filesystems
  fstests: add _change_metadata_uuid helper
  fstests: test UUID consistency for clones with metadata_uuid

 common/config         |   2 +
 common/rc             | 135 +++++++++++++++++++++++++++++++++++++++
 tests/generic/801     | 143 ++++++++++++++++++++++++++++++++++++++++++
 tests/generic/801.out |   7 +++
 tests/generic/802     |  64 +++++++++++++++++++
 tests/generic/802.out |   4 ++
 tests/generic/803     |  72 +++++++++++++++++++++
 tests/generic/803.out |   6 ++
 tests/generic/804     | 108 +++++++++++++++++++++++++++++++
 tests/generic/804.out |  10 +++
 tests/generic/805     |  80 +++++++++++++++++++++++
 tests/generic/805.out |   2 +
 tests/generic/806     |  74 ++++++++++++++++++++++
 tests/generic/806.out |   6 ++
 14 files changed, 713 insertions(+)
 create mode 100644 tests/generic/801
 create mode 100644 tests/generic/801.out
 create mode 100644 tests/generic/802
 create mode 100644 tests/generic/802.out
 create mode 100644 tests/generic/803
 create mode 100644 tests/generic/803.out
 create mode 100644 tests/generic/804
 create mode 100644 tests/generic/804.out
 create mode 100644 tests/generic/805
 create mode 100644 tests/generic/805.out
 create mode 100644 tests/generic/806
 create mode 100644 tests/generic/806.out

-- 
2.43.0


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

* [PATCH v8 01/13] fstests: add _loop_image_create_clone() helper
  2026-07-25  7:38 [PATCH v8 0/13] fstests: add test coverage for cloned filesystem ids Anand Jain
@ 2026-07-25  7:38 ` Anand Jain
  2026-09-01 12:33   ` Zorro Lang
  2026-07-25  7:38 ` [PATCH v8 02/13] fstests: add _clone_mount_option() helper Anand Jain
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 25+ messages in thread
From: Anand Jain @ 2026-07-25  7:38 UTC (permalink / raw)
  To: fstests; +Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang,
	djwong

Introduce _loop_image_create_clone() and _loop_image_destroy() to mkfs an
image file and clone it to another image file, and attach a loop device to
them. And its destroy part.

Signed-off-by: Anand Jain <asj@kernel.org>
---
 common/rc | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/common/rc b/common/rc
index 106f044adc2d..e8ff5be0c547 100644
--- a/common/rc
+++ b/common/rc
@@ -1520,6 +1520,71 @@ _scratch_resvblks()
 	esac
 }
 
+# Create a small loop image, run an optional tuning function ($2) on it,
+# clone it, and attach both to loop devices, returned in ($1).
+# Args:
+#   $1: Nameref to return the array of allocated loop devices [base, clone].
+#   $2: Optional callback function to tune the base filesystem before cloning.
+_loop_image_create_clone()
+{
+	local -n _ret=$1
+	local pre_clone_tune_func="$2"
+	local img_file=$TEST_DIR/${seq}.img
+	local img_file_clone=$TEST_DIR/${seq}_clone.img
+	local size=$(_small_fs_size_mb 128) # Smallest possible
+	local loop_devs=()
+
+	# Since we copy the block device image, we keep its size small.
+	_require_fs_space $TEST_DIR $((size * 1024 * 2))
+
+	_create_file_sized $((size * 1024 * 1024)) $img_file ||
+				_fail "Failed: Create $img_file $size"
+
+	loop_devs=("$(_create_loop_device $img_file)")
+
+	case $FSTYP in
+	xfs)
+		_mkfs_dev -s size=4096 "${loop_devs[0]}"
+		;;
+	btrfs)
+		_mkfs_dev "${loop_devs[0]}"
+		;;
+	*)
+		_mkfs_dev "${loop_devs[0]}"
+		;;
+	esac
+
+	# Only execute if the function argument is not empty
+	if [ -n "$pre_clone_tune_func" ]; then
+		$pre_clone_tune_func "${loop_devs[0]}"
+	fi
+
+	sync "${loop_devs[0]}"
+	cp $img_file $img_file_clone || _fail "Failed to copy cloned image"
+
+	loop_devs+=("$(_create_loop_device $img_file_clone)")
+
+	_ret=()
+	for i in "${loop_devs[@]}"; do
+		_ret+=("$i")
+	done
+}
+
+# Teardown loop devices and delete their underlying backing image files.
+# Accepts a list of loop device paths (e.g., /dev/loop0 /dev/loop1).
+_loop_image_destroy()
+{
+	for d in "$@"; do
+		# Retrieve the path of the backing file
+		local f=$(losetup --noheadings --output BACK-FILE $d)
+
+		# Detach the loop device from the backing file
+		_destroy_loop_device "$d"
+
+		# Clean up the backing disk image file
+		[ -n "$f" ] && rm -f "$f"
+	done
+}
 
 # 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] 25+ messages in thread

* [PATCH v8 02/13] fstests: add _clone_mount_option() helper
  2026-07-25  7:38 [PATCH v8 0/13] fstests: add test coverage for cloned filesystem ids Anand Jain
  2026-07-25  7:38 ` [PATCH v8 01/13] fstests: add _loop_image_create_clone() helper Anand Jain
@ 2026-07-25  7:38 ` Anand Jain
  2026-09-01 12:39   ` Zorro Lang
  2026-07-25  7:39 ` [PATCH v8 03/13] fstests: add FSNOTIFYWAIT_PROG Anand Jain
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 25+ messages in thread
From: Anand Jain @ 2026-07-25  7:38 UTC (permalink / raw)
  To: fstests; +Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang,
	djwong

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>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
---
 common/rc | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/common/rc b/common/rc
index e8ff5be0c547..53e5d9d43af6 100644
--- a/common/rc
+++ b/common/rc
@@ -414,6 +414,19 @@ _scratch_mount_options()
 					$SCRATCH_DEV $SCRATCH_MNT
 }
 
+# Return filesystem-specific mount options required for mounting clone/snapshot
+# devices.
+_clone_mount_option()
+{
+	case "$FSTYP" in
+	xfs)
+		# Allow mounting a duplicate filesystem on the same host
+		echo "-o nouuid"
+		;;
+	*)
+	esac
+}
+
 _supports_filetype()
 {
 	local dir=$1
-- 
2.43.0


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

* [PATCH v8 03/13] fstests: add FSNOTIFYWAIT_PROG
  2026-07-25  7:38 [PATCH v8 0/13] fstests: add test coverage for cloned filesystem ids Anand Jain
  2026-07-25  7:38 ` [PATCH v8 01/13] fstests: add _loop_image_create_clone() helper Anand Jain
  2026-07-25  7:38 ` [PATCH v8 02/13] fstests: add _clone_mount_option() helper Anand Jain
@ 2026-07-25  7:39 ` Anand Jain
  2026-09-01 15:37   ` Zorro Lang
  2026-07-25  7:39 ` [PATCH v8 04/13] fstests: add _require_fanotify_function Anand Jain
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 25+ messages in thread
From: Anand Jain @ 2026-07-25  7:39 UTC (permalink / raw)
  To: fstests; +Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang,
	djwong

Define `FSNOTIFYWAIT_PROG` for an upcoming test case that uses `fsnotifywait`.

Signed-off-by: Anand Jain <asj@kernel.org>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
---
 common/config | 1 +
 1 file changed, 1 insertion(+)

diff --git a/common/config b/common/config
index d5299d5b926f..5661fa0ec310 100644
--- a/common/config
+++ b/common/config
@@ -242,6 +242,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 FSNOTIFYWAIT_PROG="$(type -P fsnotifywait)"
 
 # udev wait functions.
 #
-- 
2.43.0


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

* [PATCH v8 04/13] fstests: add _require_fanotify_function
  2026-07-25  7:38 [PATCH v8 0/13] fstests: add test coverage for cloned filesystem ids Anand Jain
                   ` (2 preceding siblings ...)
  2026-07-25  7:39 ` [PATCH v8 03/13] fstests: add FSNOTIFYWAIT_PROG Anand Jain
@ 2026-07-25  7:39 ` Anand Jain
  2026-09-01 15:42   ` Zorro Lang
  2026-07-25  7:39 ` [PATCH v8 05/13] fstests: add _require_unique_f_fsid() helper Anand Jain
                   ` (9 subsequent siblings)
  13 siblings, 1 reply; 25+ messages in thread
From: Anand Jain @ 2026-07-25  7:39 UTC (permalink / raw)
  To: fstests; +Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang,
	djwong

fanotify support may not be compiled into the kernel. Add
_require_fanotify_function to skip tests when fanotify is disabled.

Signed-off-by: Anand Jain <asj@kernel.org>
---
 common/rc | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/common/rc b/common/rc
index 53e5d9d43af6..21b516accdf7 100644
--- a/common/rc
+++ b/common/rc
@@ -6329,6 +6329,13 @@ _require_max_file_range_blocks()
 	esac
 }
 
+_require_fanotify_function()
+{
+        if $FSNOTIFYWAIT_PROG 2>&1 | grep -q "Function not implemented"; then
+                _notrun "Need CONFIG_FANOTIFY and CONFIG_FANOTIFY_ACCESS_PERMISSIONS to be enabled"
+        fi
+}
+
 _require_fanotify_ioerrors()
 {
 	local x
-- 
2.43.0


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

* [PATCH v8 05/13] fstests: add _require_unique_f_fsid() helper
  2026-07-25  7:38 [PATCH v8 0/13] fstests: add test coverage for cloned filesystem ids Anand Jain
                   ` (3 preceding siblings ...)
  2026-07-25  7:39 ` [PATCH v8 04/13] fstests: add _require_fanotify_function Anand Jain
@ 2026-07-25  7:39 ` Anand Jain
  2026-09-01 16:09   ` Zorro Lang
  2026-07-25  7:39 ` [PATCH v8 06/13] fstests: add SEMANAGE_PROG Anand Jain
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 25+ messages in thread
From: Anand Jain @ 2026-07-25  7:39 UTC (permalink / raw)
  To: fstests; +Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang,
	djwong

Add a helper to check if the target filesystem supports unique f_fsid
tracking across cloned or snapshot instances.

Certain filesystems like XFS, Btrfs, and F2FS ensure unique f_fsid
identifiers per filesystem instance. However, Ext4 derives its f_fsid
directly from its superblock UUID, which leads to identical f_fsid
values on cloned images until the UUID is manually modified by userspace.

Introduce _require_unique_f_fsid() to allow test cases requiring strict
f_fsid uniqueness to skip gracefully on unsupported filesystems.

Signed-off-by: Anand Jain <asj@kernel.org>
---
 common/rc | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/common/rc b/common/rc
index 21b516accdf7..f73251365a60 100644
--- a/common/rc
+++ b/common/rc
@@ -6356,6 +6356,33 @@ _require_fanotify_ioerrors()
 	_notrun "$FSTYP does not support fanotify ioerrors"
 }
 
+# Skip the test if the filesystem does not enforce unique f_fsids
+# natively. Checking this dynamically requires recreating a clone
+# layout, so we use a static lookup based on FSTYP.
+#
+# Across all filesystems, a UUID collision causes libblkid tools to return
+# non-deterministic device mappings. It is ultimately the responsibility
+# of the userspace utility or use-case to enforce uniqueness when a clone
+# diverges. For details, see mailing list thread discussions:
+#   Link: https://lore.kernel.org/linux-ext4/20260409131238.GC18443@macsyma-wired.lan/
+_require_unique_f_fsid()
+{
+	case "$FSTYP" in
+	ext*)
+		# Ext4 derives f_fsid from the superblock UUID, meaning
+		# clones share the same f_fsid until their UUIDs
+		# diverge.
+		_notrun "Target filesystem ($FSTYP) does not guarantee unique f_fsid on clones."
+		;;
+	*)
+		# Conversely, XFS, Btrfs, and F2FS ensure f_fsid remains
+		# unique per filesystem instance (often by deriving it
+		# from the UUID and underlying block device.)
+		;;
+	esac
+}
+
+
 # Computes a percentage of the available space in a filesystem and
 # returns that quantity in MB. The percentage must not contain a percent
 # sign ("%").
-- 
2.43.0


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

* [PATCH v8 06/13] fstests: add SEMANAGE_PROG
  2026-07-25  7:38 [PATCH v8 0/13] fstests: add test coverage for cloned filesystem ids Anand Jain
                   ` (4 preceding siblings ...)
  2026-07-25  7:39 ` [PATCH v8 05/13] fstests: add _require_unique_f_fsid() helper Anand Jain
@ 2026-07-25  7:39 ` Anand Jain
  2026-07-25  7:39 ` [PATCH v8 07/13] fstests: verify fanotify isolation on cloned filesystems Anand Jain
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 25+ messages in thread
From: Anand Jain @ 2026-07-25  7:39 UTC (permalink / raw)
  To: fstests; +Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang,
	djwong

Define `SEMANAGE_PROG` for an upcoming test case that uses `semanage(8)`.

Signed-off-by: Anand Jain <asj@kernel.org>
---
 common/config | 1 +
 1 file changed, 1 insertion(+)

diff --git a/common/config b/common/config
index 5661fa0ec310..d760b796ce86 100644
--- a/common/config
+++ b/common/config
@@ -243,6 +243,7 @@ export PARTED_PROG="$(type -P parted)"
 export XFS_PROPERTY_PROG="$(type -P xfs_property)"
 export FSCRYPTCTL_PROG="$(type -P fscryptctl)"
 export FSNOTIFYWAIT_PROG="$(type -P fsnotifywait)"
+export SEMANAGE_PROG="$(type -P semanage)"
 
 # udev wait functions.
 #
-- 
2.43.0


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

* [PATCH v8 07/13] fstests: verify fanotify isolation on cloned filesystems
  2026-07-25  7:38 [PATCH v8 0/13] fstests: add test coverage for cloned filesystem ids Anand Jain
                   ` (5 preceding siblings ...)
  2026-07-25  7:39 ` [PATCH v8 06/13] fstests: add SEMANAGE_PROG Anand Jain
@ 2026-07-25  7:39 ` Anand Jain
  2026-09-01 18:23   ` Zorro Lang
  2026-07-25  7:39 ` [PATCH v8 08/13] fstests: verify f_fsid for " Anand Jain
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 25+ messages in thread
From: Anand Jain @ 2026-07-25  7:39 UTC (permalink / raw)
  To: fstests; +Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang,
	djwong

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>
---
 tests/generic/801     | 143 ++++++++++++++++++++++++++++++++++++++++++
 tests/generic/801.out |   7 +++
 2 files changed, 150 insertions(+)
 create mode 100644 tests/generic/801
 create mode 100644 tests/generic/801.out

diff --git a/tests/generic/801 b/tests/generic/801
new file mode 100644
index 000000000000..904ba9440b3d
--- /dev/null
+++ b/tests/generic/801
@@ -0,0 +1,143 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2026 Anand Jain <asj@kernel.org>.  All Rights Reserved.
+#
+# FS QA Test 801
+# 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_block_device $TEST_DEV
+_require_loop
+_require_command "$SEMANAGE_PROG" semanage
+_require_command "$FSNOTIFYWAIT_PROG" fsnotifywait
+_require_fanotify_function
+_require_unique_f_fsid
+
+_cleanup()
+{
+	cd /
+	[[ -n $pid1 ]] && { kill -TERM "$pid1" 2> /dev/null; wait $pid1; }
+	[[ -n $pid2 ]] && { kill -TERM "$pid2" 2> /dev/null; wait $pid2; }
+
+	if [ "$semanage_added" = "yes" ]; then
+		semanage permissive -d unconfined_t >/dev/null 2>&1 || true
+	fi
+
+	umount $mnt1 $mnt2 >/dev/null 2>&1
+	_loop_image_destroy "${devs[@]}" 2> /dev/null
+	rm -r -f $tmp.*
+}
+
+# Run fsnotifywait in unbuffered mode to watch filesystem-wide create events
+monitor_fanotify()
+{
+	local mmnt=$1
+	exec stdbuf -oL $FSNOTIFYWAIT_PROG -m -F -S -e create "$mmnt" 2>&1
+}
+
+# Transform f_fsid into the hi.lo format used in fanotify FID logs
+fsid_to_fid_parts()
+{
+	local fsid=$1
+	# Pad to 16 hex chars (64-bit), then split into two 32-bit halves
+	local padded=$(printf '%016x' "0x${fsid}")
+	local hi=$(printf '%x' "0x${padded:0:8}")   # strips leading zeros
+	local lo=$(printf '%x' "0x${padded:8:8}")   # strips leading zeros
+	echo "${hi}.${lo}"
+}
+
+# Create base loop device and its clone
+devs=()
+_loop_image_create_clone devs
+mkdir -p $TEST_DIR/$seq
+mnt1=$TEST_DIR/$seq/mnt1
+mnt2=$TEST_DIR/$seq/mnt2
+mkdir -p $mnt1
+mkdir -p $mnt2
+
+# Mount both base and clone filesystems using required clone mount options
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[0]} $mnt1 || \
+						_fail "Failed to mount dev1"
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
+						_fail "Failed to mount dev2"
+
+# Fetch filesystem IDs to verify the kernel can differentiate between them
+fsid1=$(stat -f -c "%i" $mnt1)
+fsid2=$(stat -f -c "%i" $mnt2)
+
+log1=$tmp.fanotify1
+log2=$tmp.fanotify2
+
+pid1=""
+pid2=""
+echo "Setup FID fanotify watchers on both mnt1 and mnt2"
+
+# Permit unconfined_t domains when SELinux is enforcing to prevent fanotify
+# blockages
+semanage_added="no"
+if [ "$(getenforce 2>/dev/null)" = "Enforcing" ]; then
+    if ! semanage permissive -l | grep -q "unconfined_t"; then
+        semanage permissive -a unconfined_t >/dev/null 2>&1 && semanage_added="yes"
+    fi
+fi
+
+# Start asynchronous fanotify monitors
+( monitor_fanotify "$mnt1" > "$log1" ) &
+pid1=$!
+( monitor_fanotify "$mnt2" > "$log2" ) &
+pid2=$!
+sleep 2
+
+if ! kill -0 "$pid1" 2>/dev/null || ! kill -0 "$pid2" 2>/dev/null; then
+	cat "$log1"
+	cat "$log2"
+	_fail "$FSNOTIFYWAIT_PROG setup failed"
+fi
+
+echo "Trigger file creation on mnt1"
+touch $mnt1/file_on_mnt1
+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
+pid1=""
+pid2=""
+
+e_fsid1=$(fsid_to_fid_parts "$fsid1")
+e_fsid2=$(fsid_to_fid_parts "$fsid2")
+
+# Dump debug details to the full log
+echo $fsid1 $e_fsid1 $fsid2 $e_fsid2 >> $seqres.full
+cat $log1 >> $seqres.full
+cat $log2 >> $seqres.full
+
+# Ensure monitor 1 only captured events belonging to mnt 1 and fsid 1
+if grep -qF "$e_fsid1" "$log1" && ! grep -qF "$e_fsid2" "$log1"; then
+	echo "SUCCESS: mnt1 events found"
+else
+	[ ! -s "$log1" ] && echo "  - mnt1 received no events."
+	grep -qF "$e_fsid2" "$log1" && echo "  - mnt1 received event from mnt2."
+fi
+
+# Ensure monitor 2 only captured events belonging to mnt 2 and fsid 2
+if grep -qF "$e_fsid2" "$log2" && ! grep -qF "$e_fsid1" "$log2"; then
+	echo "SUCCESS: mnt2 events found"
+else
+	[ ! -s "$log2" ] && echo "  - mnt2 received no events."
+	grep -qF "$e_fsid1" "$log2" && echo "  - mnt2 received event from mnt1."
+fi
+
+status=0
+exit
diff --git a/tests/generic/801.out b/tests/generic/801.out
new file mode 100644
index 000000000000..d7b318d9f27c
--- /dev/null
+++ b/tests/generic/801.out
@@ -0,0 +1,7 @@
+QA output created by 801
+Setup FID fanotify watchers on both mnt1 and mnt2
+Trigger file creation on mnt1
+Trigger file creation on mnt2
+Verify fsid in the fanotify
+SUCCESS: mnt1 events found
+SUCCESS: mnt2 events found
-- 
2.43.0


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

* [PATCH v8 08/13] fstests: verify f_fsid for cloned filesystems
  2026-07-25  7:38 [PATCH v8 0/13] fstests: add test coverage for cloned filesystem ids Anand Jain
                   ` (6 preceding siblings ...)
  2026-07-25  7:39 ` [PATCH v8 07/13] fstests: verify fanotify isolation on cloned filesystems Anand Jain
@ 2026-07-25  7:39 ` Anand Jain
  2026-09-01 18:51   ` Zorro Lang
  2026-07-25  7:39 ` [PATCH v8 09/13] fstests: verify libblkid resolution of duplicate UUIDs Anand Jain
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 25+ messages in thread
From: Anand Jain @ 2026-07-25  7:39 UTC (permalink / raw)
  To: fstests; +Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang,
	djwong

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/802     | 64 +++++++++++++++++++++++++++++++++++++++++++
 tests/generic/802.out |  4 +++
 2 files changed, 68 insertions(+)
 create mode 100644 tests/generic/802
 create mode 100644 tests/generic/802.out

diff --git a/tests/generic/802 b/tests/generic/802
new file mode 100644
index 000000000000..910807c11584
--- /dev/null
+++ b/tests/generic/802
@@ -0,0 +1,64 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2026 Anand Jain <asj@kernel.org>.  All Rights Reserved.
+#
+# FS QA Test 802
+# Check that the cloned filesystem provides an f_fsid that is persistent
+# across mount cycles if the block device maj:min remains unchanged.
+
+. ./common/preamble
+
+_begin_fstest auto quick mount clone
+
+_require_test
+_require_block_device $TEST_DEV
+_require_loop
+
+_fixed_by_fs_commit btrfs xxxxxxxxxxxx \
+	"btrfs: use on-disk uuid for s_uuid in temp_fsid mounts"
+_fixed_by_fs_commit btrfs xxxxxxxxxxxx \
+	"btrfs: derive f_fsid from on-disk fsuuid and dev_t"
+
+_cleanup()
+{
+	cd /
+	rm -r -f $tmp.*
+	umount $mnt1 $mnt2 2>/dev/null
+	_loop_image_destroy "${devs[@]}" 2> /dev/null
+}
+
+# Setup base loop device and its clone
+devs=()
+_loop_image_create_clone devs
+mkdir -p $TEST_DIR/$seq
+mnt1=$TEST_DIR/$seq/mnt1
+mnt2=$TEST_DIR/$seq/mnt2
+mkdir -p $mnt1
+mkdir -p $mnt2
+
+# Mount both filesystems simultaneously using mandatory clone mount options
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[0]} $mnt1 || \
+						_fail "Failed to mount dev1"
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
+						_fail "Failed to mount dev2"
+
+# Capture baseline filesystem IDs for comparison
+fsid_scratch=$(stat -f -c "%i" $mnt1)
+fsid_clone=$(stat -f -c "%i" $mnt2)
+
+# Verify that the fsids remain stable after a mount cycle, even when the
+# mount order is reversed.
+echo "**** fsid after mount cycle ****"
+_unmount $mnt1
+_unmount $mnt2
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
+						_fail "Failed to mount dev2"
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[0]} $mnt1 || \
+						_fail "Failed to mount dev1"
+
+# Compare post mount-cycle values against the baseline
+stat -f -c "%i" $mnt1 | 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/802.out b/tests/generic/802.out
new file mode 100644
index 000000000000..0202a9a2c108
--- /dev/null
+++ b/tests/generic/802.out
@@ -0,0 +1,4 @@
+QA output created by 802
+**** fsid after mount cycle ****
+FSID_SCRATCH
+FSID_CLONE
-- 
2.43.0


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

* [PATCH v8 09/13] fstests: verify libblkid resolution of duplicate UUIDs
  2026-07-25  7:38 [PATCH v8 0/13] fstests: add test coverage for cloned filesystem ids Anand Jain
                   ` (7 preceding siblings ...)
  2026-07-25  7:39 ` [PATCH v8 08/13] fstests: verify f_fsid for " Anand Jain
@ 2026-07-25  7:39 ` Anand Jain
  2026-09-01 19:12   ` Zorro Lang
  2026-07-25  7:39 ` [PATCH v8 10/13] fstests: verify IMA isolation on cloned filesystems Anand Jain
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 25+ messages in thread
From: Anand Jain @ 2026-07-25  7:39 UTC (permalink / raw)
  To: fstests; +Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang,
	djwong

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/803     | 72 +++++++++++++++++++++++++++++++++++++++++++
 tests/generic/803.out |  6 ++++
 2 files changed, 78 insertions(+)
 create mode 100644 tests/generic/803
 create mode 100644 tests/generic/803.out

diff --git a/tests/generic/803 b/tests/generic/803
new file mode 100644
index 000000000000..77901592366c
--- /dev/null
+++ b/tests/generic/803
@@ -0,0 +1,72 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2026 Anand Jain <asj@kernel.org>.  All Rights Reserved.
+#
+# FS QA Test 803
+# Check if the mountinfo based findmnt would resolve to the common uuid
+# as per the blkid (libblkid based).
+
+. ./common/preamble
+. ./common/filter
+
+_begin_fstest auto quick mount clone
+
+_require_test
+_require_block_device $TEST_DEV
+_require_loop
+
+_cleanup()
+{
+	cd /
+	rm -r -f $tmp.*
+	umount $mnt1 $mnt2 2>/dev/null
+	_loop_image_destroy "${devs[@]}" 2> /dev/null
+}
+
+# Normalize pool devices and mount points names
+filter_pool()
+{
+	sed -e "s|${devs[0]}|DEV1|g" -e "s|${mnt1}|MNT1|g" \
+	    -e "s|${devs[1]}|DEV2|g" -e "s|${mnt2}|MNT2|g" | _filter_spaces
+}
+
+# Setup base loop device and its clone
+devs=()
+_loop_image_create_clone devs
+mkdir -p $TEST_DIR/$seq
+mnt1=$TEST_DIR/$seq/mnt1
+mnt2=$TEST_DIR/$seq/mnt2
+mkdir -p $mnt1
+mkdir -p $mnt2
+
+# Get the uuid from the source device
+fsuuid=$(blkid -s UUID -o value ${devs[0]})
+
+# Mount both identical UUID filesystems simultaneously
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[0]} $mnt1 || \
+						_fail "Failed to mount dev1"
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
+						_fail "Failed to mount dev2"
+
+findmnt -o SOURCE,TARGET,UUID "${devs[0]}" | tail -n +2 | \
+				sed -e "s/${fsuuid}/FSUUID/g" | filter_pool
+findmnt -o SOURCE,TARGET,UUID "${devs[1]}" | tail -n +2 | \
+				sed -e "s/${fsuuid}/FSUUID/g" | filter_pool
+
+# Btrfs assigned a random uuid for the clone fs before the fix.
+# Cycle mounts and reverse the initialization (source and clone fs) order.
+echo "**** mount cycle ****"
+_unmount $mnt1
+_unmount $mnt2
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
+						_fail "Failed to mount dev2"
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[0]} $mnt1 || \
+						_fail "Failed to mount dev1"
+
+findmnt -o SOURCE,TARGET,UUID "${devs[0]}" | tail -n +2 | \
+				sed -e "s/${fsuuid}/FSUUID/g" | filter_pool
+findmnt -o SOURCE,TARGET,UUID "${devs[1]}" | tail -n +2 | \
+				sed -e "s/${fsuuid}/FSUUID/g" | filter_pool
+
+status=0
+exit
diff --git a/tests/generic/803.out b/tests/generic/803.out
new file mode 100644
index 000000000000..3a130c662430
--- /dev/null
+++ b/tests/generic/803.out
@@ -0,0 +1,6 @@
+QA output created by 803
+DEV1 MNT1 FSUUID
+DEV2 MNT2 FSUUID
+**** mount cycle ****
+DEV1 MNT1 FSUUID
+DEV2 MNT2 FSUUID
-- 
2.43.0


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

* [PATCH v8 10/13] fstests: verify IMA isolation on cloned filesystems
  2026-07-25  7:38 [PATCH v8 0/13] fstests: add test coverage for cloned filesystem ids Anand Jain
                   ` (8 preceding siblings ...)
  2026-07-25  7:39 ` [PATCH v8 09/13] fstests: verify libblkid resolution of duplicate UUIDs Anand Jain
@ 2026-07-25  7:39 ` Anand Jain
  2026-07-25  7:39 ` [PATCH v8 11/13] fstests: verify exportfs file handles " Anand Jain
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 25+ messages in thread
From: Anand Jain @ 2026-07-25  7:39 UTC (permalink / raw)
  To: fstests; +Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang,
	djwong

Add testcase to verify IMA measurement isolation when multiple devices
share the same FSUUID.

Signed-off-by: Anand Jain <asj@kernel.org>
---
 tests/generic/804     | 108 ++++++++++++++++++++++++++++++++++++++++++
 tests/generic/804.out |  10 ++++
 2 files changed, 118 insertions(+)
 create mode 100644 tests/generic/804
 create mode 100644 tests/generic/804.out

diff --git a/tests/generic/804 b/tests/generic/804
new file mode 100644
index 000000000000..ced32e6d79dd
--- /dev/null
+++ b/tests/generic/804
@@ -0,0 +1,108 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2026 Anand Jain <asj@kernel.org>.  All Rights Reserved.
+#
+# FS QA Test 804
+# 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_block_device $TEST_DEV
+_require_loop
+
+_fixed_by_fs_commit btrfs xxxxxxxxxxxx \
+	"btrfs: use on-disk uuid for s_uuid in temp_fsid mounts"
+_fixed_by_fs_commit btrfs xxxxxxxxxxxx \
+	"btrfs: derive f_fsid from on-disk fsuuid and dev_t"
+
+_cleanup()
+{
+	cd /
+	rm -r -f $tmp.*
+	_unmount $mnt1 2>/dev/null
+	_unmount $mnt2 2>/dev/null
+	_loop_image_destroy "${devs[@]}" 2> /dev/null
+}
+
+# Normalize device names and mount points
+filter_pool()
+{
+	sed -e "s|${devs[0]}|DEV1|g" -e "s|$mnt1|MNT1|g" \
+	    -e "s|${devs[1]}|DEV2|g" -e "s|$mnt2|MNT2|g" | _filter_spaces
+}
+
+# Core helper to set IMA policy and check measurement logs
+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 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 $enable | filter_pool
+
+	[ -w "$ima_policy" ] || _notrun "IMA policy not writable"
+
+	fsuuid=$(blkid -s UUID -o value ${devs[0]})
+
+	# Load IMA policy to measure file access specifically for this
+	# filesystem UUID.
+	if [[ $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
+
+	# IMA log extract
+	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
+}
+
+# Initialize loop base and cloned instances
+devs=()
+_loop_image_create_clone devs
+mnt1=$TEST_DIR/$seq/mnt1
+mnt2=$TEST_DIR/$seq/mnt2
+mkdir -p $mnt1
+mkdir -p $mnt2
+
+# Concurrently mount both clones
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[0]} $mnt1 || \
+						_fail "Failed to mount dev1"
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
+						_fail "Failed to mount dev2"
+
+#  IMA response on baseline and clone configuration
+do_ima $mnt1 1
+do_ima $mnt2 0
+
+# Cycle mount on the second device.
+echo mount cycle
+_unmount $mnt2
+_mount $mount_opts ${devs[1]} $mnt2 || _fail "Failed to mount dev2"
+
+do_ima $mnt1 0
+do_ima $mnt2 0
+
+status=0
+exit
diff --git a/tests/generic/804.out b/tests/generic/804.out
new file mode 100644
index 000000000000..9804181d6c17
--- /dev/null
+++ b/tests/generic/804.out
@@ -0,0 +1,10 @@
+QA output created by 804
+MNT1 1
+MNT1/FOOBAR_FILE
+MNT2 0
+MNT2/FOOBAR_FILE
+mount cycle
+MNT1 0
+MNT1/FOOBAR_FILE
+MNT2 0
+MNT2/FOOBAR_FILE
-- 
2.43.0


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

* [PATCH v8 11/13] fstests: verify exportfs file handles on cloned filesystems
  2026-07-25  7:38 [PATCH v8 0/13] fstests: add test coverage for cloned filesystem ids Anand Jain
                   ` (9 preceding siblings ...)
  2026-07-25  7:39 ` [PATCH v8 10/13] fstests: verify IMA isolation on cloned filesystems Anand Jain
@ 2026-07-25  7:39 ` Anand Jain
  2026-07-25  7:39 ` [PATCH v8 12/13] fstests: add _change_metadata_uuid helper Anand Jain
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 25+ messages in thread
From: Anand Jain @ 2026-07-25  7:39 UTC (permalink / raw)
  To: fstests; +Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang,
	djwong

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/805     | 80 +++++++++++++++++++++++++++++++++++++++++++
 tests/generic/805.out |  2 ++
 2 files changed, 82 insertions(+)
 create mode 100644 tests/generic/805
 create mode 100644 tests/generic/805.out

diff --git a/tests/generic/805 b/tests/generic/805
new file mode 100644
index 000000000000..5827eee039df
--- /dev/null
+++ b/tests/generic/805
@@ -0,0 +1,80 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2026 Anand Jain <asj@kernel.org>.  All Rights Reserved.
+#
+# FS QA Test No. 805
+# Verify that file handles encoded on a cloned filesystem remain valid and
+# resolvable via open_by_handle across a mount cycle and mount order swap.
+
+. ./common/preamble
+
+_begin_fstest auto quick exportfs clone
+
+_require_test
+_require_block_device $TEST_DEV
+_require_exportfs
+_require_loop
+_require_test_program "open_by_handle"
+
+_cleanup()
+{
+	cd /
+	rm -r -f $tmp.*
+	_unmount $mnt1 2>/dev/null
+	_unmount $mnt2 2>/dev/null
+	_loop_image_destroy "${devs[@]}" 2> /dev/null
+}
+
+# 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
+}
+
+# Attempt to read and decode the saved file handles on the targeted mount point.
+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
+}
+
+# Setup base loop device and its clone
+devs=()
+_loop_image_create_clone devs
+mkdir -p $TEST_DIR/$seq
+mnt1=$TEST_DIR/$seq/mnt1
+mnt2=$TEST_DIR/$seq/mnt2
+mkdir -p $mnt1
+mkdir -p $mnt2
+
+# Mount both identical UUID filesystems simultaneously
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[0]} $mnt1 || \
+						_fail "Failed to mount dev1"
+_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
+
+# Cycle mounts and reverse initialization sequence to check if
+# file handle lookups are okay
+_unmount $mnt1
+_unmount $mnt2
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
+						_fail "Failed to mount dev2"
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[0]} $mnt1 || \
+						_fail "Failed to mount dev1"
+
+# Verify file handles can still be resolved post-mount-cycle
+test_file_handles -rp "cycle mount"
+
+status=0
+exit
diff --git a/tests/generic/805.out b/tests/generic/805.out
new file mode 100644
index 000000000000..29b11ec77ffb
--- /dev/null
+++ b/tests/generic/805.out
@@ -0,0 +1,2 @@
+QA output created by 805
+test_file_handles after cycle mount
-- 
2.43.0


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

* [PATCH v8 12/13] fstests: add _change_metadata_uuid helper
  2026-07-25  7:38 [PATCH v8 0/13] fstests: add test coverage for cloned filesystem ids Anand Jain
                   ` (10 preceding siblings ...)
  2026-07-25  7:39 ` [PATCH v8 11/13] fstests: verify exportfs file handles " Anand Jain
@ 2026-07-25  7:39 ` Anand Jain
  2026-07-25  7:39 ` [PATCH v8 13/13] fstests: test UUID consistency for clones with metadata_uuid Anand Jain
  2026-08-31  7:17 ` [PATCH v8 0/13] fstests: add test coverage for cloned filesystem ids Anand Suveer Jain
  13 siblings, 0 replies; 25+ messages in thread
From: Anand Jain @ 2026-07-25  7:39 UTC (permalink / raw)
  To: fstests; +Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang,
	djwong

_change_metadata_uuid changes the UUID of the golden filesystem before it
is cloned.

Signed-off-by: Anand Jain <asj@kernel.org>
---
 common/rc | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/common/rc b/common/rc
index f73251365a60..45cf9360ba73 100644
--- a/common/rc
+++ b/common/rc
@@ -1533,6 +1533,29 @@ _scratch_resvblks()
 	esac
 }
 
+# Change the metadata UUID of the given device to a newly generated one.
+# Args:
+#   $1: Block device path to modify.
+_change_metadata_uuid()
+{
+	local temp_mnt=$TEST_DIR/${seq}_mnt
+	local dev=$1
+
+	case $FSTYP in
+	xfs)
+		_require_command "$XFS_ADMIN_PROG" "xfs_admin"
+		$XFS_ADMIN_PROG -U generate $dev >> $seqres.full
+		;;
+	btrfs)
+		_require_command "$BTRFS_TUNE_PROG" "btrfstune"
+		$BTRFS_TUNE_PROG -m $dev
+		;;
+	*)
+		_notrun "Require filesystem with metadata_uuid feature"
+		;;
+	esac
+}
+
 # Create a small loop image, run an optional tuning function ($2) on it,
 # clone it, and attach both to loop devices, returned in ($1).
 # Args:
-- 
2.43.0


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

* [PATCH v8 13/13] fstests: test UUID consistency for clones with metadata_uuid
  2026-07-25  7:38 [PATCH v8 0/13] fstests: add test coverage for cloned filesystem ids Anand Jain
                   ` (11 preceding siblings ...)
  2026-07-25  7:39 ` [PATCH v8 12/13] fstests: add _change_metadata_uuid helper Anand Jain
@ 2026-07-25  7:39 ` Anand Jain
  2026-08-31  7:17 ` [PATCH v8 0/13] fstests: add test coverage for cloned filesystem ids Anand Suveer Jain
  13 siblings, 0 replies; 25+ messages in thread
From: Anand Jain @ 2026-07-25  7:39 UTC (permalink / raw)
  To: fstests; +Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, zlang,
	djwong

Btrfs and xfs uses the metadata_uuid superblock feature to change the
on-disk UUID without rewriting every block header. This patch adds a
sanity check to ensure UUID consistency when a filesystem with
metadata_uuid enabled is cloned.

Signed-off-by: Anand Jain <asj@kernel.org>
---
 tests/generic/806     | 74 +++++++++++++++++++++++++++++++++++++++++++
 tests/generic/806.out |  6 ++++
 2 files changed, 80 insertions(+)
 create mode 100644 tests/generic/806
 create mode 100644 tests/generic/806.out

diff --git a/tests/generic/806 b/tests/generic/806
new file mode 100644
index 000000000000..6d3166491006
--- /dev/null
+++ b/tests/generic/806
@@ -0,0 +1,74 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2026 Anand Jain <asj@kernel.org>.  All Rights Reserved.
+#
+# FS QA Test 806
+#
+# Verify that the cloned filesystem UUID remains consistent, even when the
+# `metadata_uuid` feature is enabled.
+#
+
+. ./common/preamble
+. ./common/filter
+
+_begin_fstest auto quick mount clone
+
+_require_test
+_require_block_device $TEST_DEV
+_require_loop
+
+_cleanup()
+{
+	cd /
+	rm -r -f $tmp.*
+	umount $mnt1 $mnt2 2>/dev/null
+	_loop_image_destroy "${devs[@]}" 2> /dev/null
+}
+
+filter_pool()
+{
+	sed -e "s|${devs[0]}|DEV1|g" -e "s|${mnt1}|MNT1|g" \
+	    -e "s|${devs[1]}|DEV2|g" -e "s|${mnt2}|MNT2|g" | _filter_spaces
+}
+
+# Create base loop device and its clone, applying the metadata_uuid tuning
+# callback to the base filesystem before the copy occurs.
+devs=()
+_loop_image_create_clone devs _change_metadata_uuid
+mkdir -p $TEST_DIR/$seq
+mnt1=$TEST_DIR/$seq/mnt1
+mnt2=$TEST_DIR/$seq/mnt2
+mkdir -p $mnt1
+mkdir -p $mnt2
+
+# Get the uuid from the source device
+fsuuid=$(blkid -s UUID -o value ${devs[0]})
+
+# Mount both clone and baseline
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[0]} $mnt1 || \
+						_fail "Failed to mount dev1"
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
+						_fail "Failed to mount dev2"
+
+findmnt -o SOURCE,TARGET,UUID "${devs[0]}" | tail -n +2 | \
+				sed -e "s/${fsuuid}/FSUUID/g" | filter_pool
+findmnt -o SOURCE,TARGET,UUID "${devs[1]}" | tail -n +2 | \
+				sed -e "s/${fsuuid}/FSUUID/g" | filter_pool
+
+# Cycle mounts and reverse the initialization order to ensure UUID tracking
+# doesn't mismatch or flip when metadata_uuid optimization is active.
+echo "**** mount cycle ****"
+_unmount $mnt1
+_unmount $mnt2
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
+						_fail "Failed to mount dev2"
+_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[0]} $mnt1 || \
+						_fail "Failed to mount dev1"
+
+findmnt -o SOURCE,TARGET,UUID "${devs[0]}" | tail -n +2 | \
+				sed -e "s/${fsuuid}/FSUUID/g" | filter_pool
+findmnt -o SOURCE,TARGET,UUID "${devs[1]}" | tail -n +2 | \
+				sed -e "s/${fsuuid}/FSUUID/g" | filter_pool
+
+status=0
+exit
diff --git a/tests/generic/806.out b/tests/generic/806.out
new file mode 100644
index 000000000000..918f422ecddf
--- /dev/null
+++ b/tests/generic/806.out
@@ -0,0 +1,6 @@
+QA output created by 806
+DEV1 MNT1 FSUUID
+DEV2 MNT2 FSUUID
+**** mount cycle ****
+DEV1 MNT1 FSUUID
+DEV2 MNT2 FSUUID
-- 
2.43.0


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

* Re: [PATCH v8 0/13] fstests: add test coverage for cloned filesystem ids
  2026-07-25  7:38 [PATCH v8 0/13] fstests: add test coverage for cloned filesystem ids Anand Jain
                   ` (12 preceding siblings ...)
  2026-07-25  7:39 ` [PATCH v8 13/13] fstests: test UUID consistency for clones with metadata_uuid Anand Jain
@ 2026-08-31  7:17 ` Anand Suveer Jain
  13 siblings, 0 replies; 25+ messages in thread
From: Anand Suveer Jain @ 2026-08-31  7:17 UTC (permalink / raw)
  To: zlang; +Cc: linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel, fstests


Zorro, Ping?

Cheers, Anand

On 25/7/26 15:38, Anand Jain wrote:
> v8:
> - _require_fs_space: double the required space (x2) to account for both source and clone
> - Use proper quoting/unquoting for _mkfs_dev (Thanks Darrick)
> - Call _fail() if cp fails
> - _require_fanotify_function: check for kernel fsnotify support
> - _require_unique_f_fsid: reorganize comments and replace 'if' with 'case' statement (Thanks Darrick)
> - Add SEMANAGE_PROG variable (Thanks Darrick)
> - fanotify verification: add checks for SEMANAGE_PROG and _require_fanotify_function
> - Verify that the monitoring process is actually created
> 
> v7:
>   https://lore.kernel.org/fstests/cover.1781694879.git.asj@kernel.org
> 
> v6:
>   https://lore.kernel.org/fstests/cover.1779939330.git.asj@kernel.org
> 
> v5:
>   https://lore.kernel.org/fstests/cover.1779367627.git.asj@kernel.org
> 
> v4:
>   https://lore.kernel.org/fstests/cover.1777357320.git.asj@kernel.org
> 
> v3:
>   https://lore.kernel.org/fstests/cover.1777281778.git.asj@kernel.org
> 
> v2:
>   https://lore.kernel.org/fstests/cover.1774090817.git.asj@kernel.org
> 
> v1:
>   https://lore.kernel.org/fstests/cover.1772095513.git.asj@kernel.org
> 
> This series adds fstests infrastructure and test cases to verify correct
> filesystem identity when a filesystem is cloned (block-level copy).
> Test covers inotify, fanotify, f_fsid, libblkid, IMA, exportfs file handles
> and libblkid tools verify with metadata_uuid.
>   New helpers:
>    _loop_image_create_clone() and _loop_image_destroy() to help create fs and clone
>    _clone_mount_option() helper to apply per-filesystem clone mount options
>    _require_fanotify_function check if kernel supports fs notification
>    _require_unique_f_fsid() helper to handle fs difference in fsid implementation
> 
>   New tests:
>   - fanotify events are isolated between cloned filesystems
>   - f_fsid is unique across cloned filesystem instances
>   - libblkid correctly resolves duplicate UUIDs to distinct devices
>     with and without metadata_uuid
>   - IMA distinct identity for each cloned filesystem
>   - exportfs file handles resolve correctly on cloned filesystems
> 
> Kernel Patches:
>   Requires Btrfs kernel patches for all tests to pass.
>    [1] https://lore.kernel.org/linux-btrfs/cover.1777281686.git.asj@kernel.org
> 
> 
> Anand Jain (13):
>   fstests: add _loop_image_create_clone() helper
>   fstests: add _clone_mount_option() helper
>   fstests: add FSNOTIFYWAIT_PROG
>   fstests: add _require_fanotify_function
>   fstests: add _require_unique_f_fsid() helper
>   fstests: add SEMANAGE_PROG
>   fstests: verify fanotify isolation on cloned filesystems
>   fstests: verify f_fsid for cloned filesystems
>   fstests: verify libblkid resolution of duplicate UUIDs
>   fstests: verify IMA isolation on cloned filesystems
>   fstests: verify exportfs file handles on cloned filesystems
>   fstests: add _change_metadata_uuid helper
>   fstests: test UUID consistency for clones with metadata_uuid
> 
>  common/config         |   2 +
>  common/rc             | 135 +++++++++++++++++++++++++++++++++++++++
>  tests/generic/801     | 143 ++++++++++++++++++++++++++++++++++++++++++
>  tests/generic/801.out |   7 +++
>  tests/generic/802     |  64 +++++++++++++++++++
>  tests/generic/802.out |   4 ++
>  tests/generic/803     |  72 +++++++++++++++++++++
>  tests/generic/803.out |   6 ++
>  tests/generic/804     | 108 +++++++++++++++++++++++++++++++
>  tests/generic/804.out |  10 +++
>  tests/generic/805     |  80 +++++++++++++++++++++++
>  tests/generic/805.out |   2 +
>  tests/generic/806     |  74 ++++++++++++++++++++++
>  tests/generic/806.out |   6 ++
>  14 files changed, 713 insertions(+)
>  create mode 100644 tests/generic/801
>  create mode 100644 tests/generic/801.out
>  create mode 100644 tests/generic/802
>  create mode 100644 tests/generic/802.out
>  create mode 100644 tests/generic/803
>  create mode 100644 tests/generic/803.out
>  create mode 100644 tests/generic/804
>  create mode 100644 tests/generic/804.out
>  create mode 100644 tests/generic/805
>  create mode 100644 tests/generic/805.out
>  create mode 100644 tests/generic/806
>  create mode 100644 tests/generic/806.out
> 


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

* Re: [PATCH v8 01/13] fstests: add _loop_image_create_clone() helper
  2026-07-25  7:38 ` [PATCH v8 01/13] fstests: add _loop_image_create_clone() helper Anand Jain
@ 2026-09-01 12:33   ` Zorro Lang
  2026-09-01 13:52     ` Anand Suveer Jain
  0 siblings, 1 reply; 25+ messages in thread
From: Zorro Lang @ 2026-09-01 12:33 UTC (permalink / raw)
  To: Anand Jain
  Cc: fstests, linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel,
	djwong

On Sat, Jul 25, 2026 at 03:38:58PM +0800, Anand Jain wrote:
> Introduce _loop_image_create_clone() and _loop_image_destroy() to mkfs an
> image file and clone it to another image file, and attach a loop device to
> them. And its destroy part.
> 
> Signed-off-by: Anand Jain <asj@kernel.org>
> ---
>  common/rc | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 65 insertions(+)
> 
> diff --git a/common/rc b/common/rc
> index 106f044adc2d..e8ff5be0c547 100644
> --- a/common/rc
> +++ b/common/rc
> @@ -1520,6 +1520,71 @@ _scratch_resvblks()
>  	esac
>  }
>  
> +# Create a small loop image, run an optional tuning function ($2) on it,
> +# clone it, and attach both to loop devices, returned in ($1).
> +# Args:
> +#   $1: Nameref to return the array of allocated loop devices [base, clone].
> +#   $2: Optional callback function to tune the base filesystem before cloning.
> +_loop_image_create_clone()

To capture both the relationship and distinction between this function and
existing _create_loop_device, I'd like to rename it to *_create_cloned_loop_devs*.

> +{
> +	local -n _ret=$1
> +	local pre_clone_tune_func="$2"
> +	local img_file=$TEST_DIR/${seq}.img
> +	local img_file_clone=$TEST_DIR/${seq}_clone.img
> +	local size=$(_small_fs_size_mb 128) # Smallest possible
> +	local loop_devs=()
> +
> +	# Since we copy the block device image, we keep its size small.
> +	_require_fs_space $TEST_DIR $((size * 1024 * 2))
> +
> +	_create_file_sized $((size * 1024 * 1024)) $img_file ||
> +				_fail "Failed: Create $img_file $size"
> +
> +	loop_devs=("$(_create_loop_device $img_file)")
> +
> +	case $FSTYP in
> +	xfs)
> +		_mkfs_dev -s size=4096 "${loop_devs[0]}"

Why xfs needs a specific "-s size=4096" ? Hardcoding this parameter might cause
failures in certain incompatible environments.

> +		;;
> +	btrfs)
> +		_mkfs_dev "${loop_devs[0]}"

If btrfs is handled the same way as the default `*)` branch below, there is
no need to have a dedicated branch for it.

> +		;;
> +	*)
> +		_mkfs_dev "${loop_devs[0]}"
> +		;;
> +	esac
> +
> +	# Only execute if the function argument is not empty
> +	if [ -n "$pre_clone_tune_func" ]; then
> +		$pre_clone_tune_func "${loop_devs[0]}"
> +	fi
> +
> +	sync "${loop_devs[0]}"

Since the mkfs command above operates directly on a loop device, I wanted to
make sure, can the sync command be targeted at a block device, and does it
guarantee a cache flush or blockdev page cache sync ?

How about:
  sync -d "${loop_devs[0]}"
  blockdev --flushbufs "${loop_devs[0]}"
or any better idea?

> +	cp $img_file $img_file_clone || _fail "Failed to copy cloned image"
> +
> +	loop_devs+=("$(_create_loop_device $img_file_clone)")
> +
> +	_ret=()
> +	for i in "${loop_devs[@]}"; do
> +		_ret+=("$i")
> +	done

How about:
  _ret=("${loop_devs[@]}")
directly?

> +}
> +
> +# Teardown loop devices and delete their underlying backing image files.
> +# Accepts a list of loop device paths (e.g., /dev/loop0 /dev/loop1).
> +_loop_image_destroy()

To keep it consistent with the renamed function above, we could rename this
to *_destroy_cloned_loop_devs*. Alternatively, if we don't consider it
clone-specific, *destroy_loop_devs* would also be good to me.

Thanks,
Zorro

> +{
> +	for d in "$@"; do
> +		# Retrieve the path of the backing file
> +		local f=$(losetup --noheadings --output BACK-FILE $d)
> +
> +		# Detach the loop device from the backing file
> +		_destroy_loop_device "$d"
> +
> +		# Clean up the backing disk image file
> +		[ -n "$f" ] && rm -f "$f"
> +	done
> +}
>  
>  # 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] 25+ messages in thread

* Re: [PATCH v8 02/13] fstests: add _clone_mount_option() helper
  2026-07-25  7:38 ` [PATCH v8 02/13] fstests: add _clone_mount_option() helper Anand Jain
@ 2026-09-01 12:39   ` Zorro Lang
  2026-09-01 13:54     ` Anand Suveer Jain
  0 siblings, 1 reply; 25+ messages in thread
From: Zorro Lang @ 2026-09-01 12:39 UTC (permalink / raw)
  To: Anand Jain
  Cc: fstests, linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel,
	djwong

On Sat, Jul 25, 2026 at 03:38:59PM +0800, Anand Jain wrote:
> 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>
> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
> ---
>  common/rc | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/common/rc b/common/rc
> index e8ff5be0c547..53e5d9d43af6 100644
> --- a/common/rc
> +++ b/common/rc
> @@ -414,6 +414,19 @@ _scratch_mount_options()
>  					$SCRATCH_DEV $SCRATCH_MNT
>  }
>  
> +# Return filesystem-specific mount options required for mounting clone/snapshot
> +# devices.
> +_clone_mount_option()

Just a minor nitpick :) For consistency with other *_mount_options functions
(in common/rc), I suggest using "options" instead of "option" -- _clone_mount_options

> +{
> +	case "$FSTYP" in
> +	xfs)
> +		# Allow mounting a duplicate filesystem on the same host
> +		echo "-o nouuid"
> +		;;
> +	*)
> +	esac
> +}
> +
>  _supports_filetype()
>  {
>  	local dir=$1
> -- 
> 2.43.0
> 

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

* Re: [PATCH v8 01/13] fstests: add _loop_image_create_clone() helper
  2026-09-01 12:33   ` Zorro Lang
@ 2026-09-01 13:52     ` Anand Suveer Jain
  0 siblings, 0 replies; 25+ messages in thread
From: Anand Suveer Jain @ 2026-09-01 13:52 UTC (permalink / raw)
  To: fstests, linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel,
	djwong



On 1/9/26 20:33, Zorro Lang wrote:
> On Sat, Jul 25, 2026 at 03:38:58PM +0800, Anand Jain wrote:
>> Introduce _loop_image_create_clone() and _loop_image_destroy() to mkfs an
>> image file and clone it to another image file, and attach a loop device to
>> them. And its destroy part.
>>
>> Signed-off-by: Anand Jain <asj@kernel.org>
>> ---
>>  common/rc | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 65 insertions(+)
>>
>> diff --git a/common/rc b/common/rc
>> index 106f044adc2d..e8ff5be0c547 100644
>> --- a/common/rc
>> +++ b/common/rc
>> @@ -1520,6 +1520,71 @@ _scratch_resvblks()
>>  	esac
>>  }
>>  
>> +# Create a small loop image, run an optional tuning function ($2) on it,
>> +# clone it, and attach both to loop devices, returned in ($1).
>> +# Args:
>> +#   $1: Nameref to return the array of allocated loop devices [base, clone].
>> +#   $2: Optional callback function to tune the base filesystem before cloning.
>> +_loop_image_create_clone()
> 
> To capture both the relationship and distinction between this function and
> existing _create_loop_device, I'd like to rename it to *_create_cloned_loop_devs*.

 I'm fine with _create_cloned_loop_devs() and other patches must be
updated accordingly.

>> +{
>> +	local -n _ret=$1
>> +	local pre_clone_tune_func="$2"
>> +	local img_file=$TEST_DIR/${seq}.img
>> +	local img_file_clone=$TEST_DIR/${seq}_clone.img
>> +	local size=$(_small_fs_size_mb 128) # Smallest possible
>> +	local loop_devs=()
>> +
>> +	# Since we copy the block device image, we keep its size small.
>> +	_require_fs_space $TEST_DIR $((size * 1024 * 2))
>> +
>> +	_create_file_sized $((size * 1024 * 1024)) $img_file ||
>> +				_fail "Failed: Create $img_file $size"
>> +


>> +	loop_devs=("$(_create_loop_device $img_file)")
>> +
>> +	case $FSTYP in
>> +	xfs)
>> +		_mkfs_dev -s size=4096 "${loop_devs[0]}"
> 
> Why xfs needs a specific "-s size=4096" ? Hardcoding this parameter might cause
> failures in certain incompatible environments.
>> +		;;
>> +	btrfs)
>> +		_mkfs_dev "${loop_devs[0]}"
> 
> If btrfs is handled the same way as the default `*)` branch below, there is
> no need to have a dedicated branch for it.
> 
>> +		;;
>> +	*)
>> +		_mkfs_dev "${loop_devs[0]}"
>> +		;;
>> +	esac
>> +
>> +	# Only execute if the function argument is not empty
>> +	if [ -n "$pre_clone_tune_func" ]; then
>> +		$pre_clone_tune_func "${loop_devs[0]}"
>> +	fi
>> +
>> +	sync "${loop_devs[0]}"
> 
> Since the mkfs command above operates directly on a loop device, I wanted to
> make sure, can the sync command be targeted at a block device, and does it
> guarantee a cache flush or blockdev page cache sync ?
> 
> How about:
>   sync -d "${loop_devs[0]}"
>   blockdev --flushbufs "${loop_devs[0]}"
> or any better idea?
> 

Spotted stale code here while refactoring pre_clone_tune_func.
The updated code with the suggested renames is below.

Agreed that <dev> in sync is redundant. Adding sync serves
as a safeguard if a future mkfs fails to do so. Flushing
via blockdev --flushbufs followed by a global sync properly
follows the data flow path it may not be strictly required
but it is safer.


>> +	cp $img_file $img_file_clone || _fail "Failed to copy cloned image"
>> +
>> +	loop_devs+=("$(_create_loop_device $img_file_clone)")
>> +
>> +	_ret=()
>> +	for i in "${loop_devs[@]}"; do
>> +		_ret+=("$i")
>> +	done
> 
> How about:
>   _ret=("${loop_devs[@]}")
> directly?
> 

yeah. added.

>> +}
>> +
>> +# Teardown loop devices and delete their underlying backing image files.
>> +# Accepts a list of loop device paths (e.g., /dev/loop0 /dev/loop1).
>> +_loop_image_destroy()
> 
> To keep it consistent with the renamed function above, we could rename this
> to *_destroy_cloned_loop_devs*. Alternatively, if we don't consider it
> clone-specific, *destroy_loop_devs* would also be good to me.
> 

 _destroy_cloned_loop_devs() is fine.



Updated code:

---------------------------------
diff --git a/common/rc b/common/rc
index 45cf9360ba73..285463b4e3db 100644
--- a/common/rc
+++ b/common/rc
@@ -1561,7 +1561,7 @@ _change_metadata_uuid()
 # Args:
 #   $1: Nameref to return the array of allocated loop devices [base,
clone].
 #   $2: Optional callback function to tune the base filesystem before
cloning.
-_loop_image_create_clone()
+_create_cloned_loop_devs()
 {
 	local -n _ret=$1
 	local pre_clone_tune_func="$2"
@@ -1578,37 +1578,28 @@ _loop_image_create_clone()

 	loop_devs=("$(_create_loop_device $img_file)")

-	case $FSTYP in
-	xfs)
-		_mkfs_dev -s size=4096 "${loop_devs[0]}"
-		;;
-	btrfs)
-		_mkfs_dev "${loop_devs[0]}"
-		;;
-	*)
-		_mkfs_dev "${loop_devs[0]}"
-		;;
-	esac
+	_mkfs_dev "${loop_devs[0]}"

 	# Only execute if the function argument is not empty
 	if [ -n "$pre_clone_tune_func" ]; then
 		$pre_clone_tune_func "${loop_devs[0]}"
 	fi

-	sync "${loop_devs[0]}"
+	# We are about to copy the loop device's backing file
+	# Flush loop device's buffer cache
+	blockdev --flushbufs "${loop_devs[0]}"
+	# Sync system's dirty pages including backing file's
+	sync
 	cp $img_file $img_file_clone || _fail "Failed to copy cloned image"

 	loop_devs+=("$(_create_loop_device $img_file_clone)")

-	_ret=()
-	for i in "${loop_devs[@]}"; do
-		_ret+=("$i")
-	done
+	_ret=("${loop_devs[@]}")
 }

 # Teardown loop devices and delete their underlying backing image files.
 # Accepts a list of loop device paths (e.g., /dev/loop0 /dev/loop1).
-_loop_image_destroy()
+_destroy_cloned_loop_devs()
 {
 	for d in "$@"; do
 		# Retrieve the path of the backing file
-------------------------------


Thanks.
Anand


> Thanks,
> Zorro
> 
>> +{
>> +	for d in "$@"; do
>> +		# Retrieve the path of the backing file
>> +		local f=$(losetup --noheadings --output BACK-FILE $d)
>> +
>> +		# Detach the loop device from the backing file
>> +		_destroy_loop_device "$d"
>> +
>> +		# Clean up the backing disk image file
>> +		[ -n "$f" ] && rm -f "$f"
>> +	done
>> +}
>>  
>>  # 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] 25+ messages in thread

* Re: [PATCH v8 02/13] fstests: add _clone_mount_option() helper
  2026-09-01 12:39   ` Zorro Lang
@ 2026-09-01 13:54     ` Anand Suveer Jain
  0 siblings, 0 replies; 25+ messages in thread
From: Anand Suveer Jain @ 2026-09-01 13:54 UTC (permalink / raw)
  To: Zorro Lang
  Cc: fstests, linux-btrfs, linux-xfs, linux-ext4, linux-f2fs-devel,
	djwong

On 1/9/26 20:39, Zorro Lang wrote:
> On Sat, Jul 25, 2026 at 03:38:59PM +0800, Anand Jain wrote:
>> 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>
>> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
>> ---
>>  common/rc | 13 +++++++++++++
>>  1 file changed, 13 insertions(+)
>>
>> diff --git a/common/rc b/common/rc
>> index e8ff5be0c547..53e5d9d43af6 100644
>> --- a/common/rc
>> +++ b/common/rc
>> @@ -414,6 +414,19 @@ _scratch_mount_options()
>>  					$SCRATCH_DEV $SCRATCH_MNT
>>  }
>>  
>> +# Return filesystem-specific mount options required for mounting clone/snapshot
>> +# devices.
>> +_clone_mount_option()
> 
> Just a minor nitpick :) For consistency with other *_mount_options functions
> (in common/rc), I suggest using "options" instead of "option" -- _clone_mount_options
> 

I'm okay with that, though this rename will impact the rest of the patch
series too.

Thanks, Anand


>> +{
>> +	case "$FSTYP" in
>> +	xfs)
>> +		# Allow mounting a duplicate filesystem on the same host
>> +		echo "-o nouuid"
>> +		;;
>> +	*)
>> +	esac
>> +}
>> +
>>  _supports_filetype()
>>  {
>>  	local dir=$1
>> -- 
>> 2.43.0
>>


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

* Re: [PATCH v8 03/13] fstests: add FSNOTIFYWAIT_PROG
  2026-07-25  7:39 ` [PATCH v8 03/13] fstests: add FSNOTIFYWAIT_PROG Anand Jain
@ 2026-09-01 15:37   ` Zorro Lang
  0 siblings, 0 replies; 25+ messages in thread
From: Zorro Lang @ 2026-09-01 15:37 UTC (permalink / raw)
  To: Anand Jain
  Cc: fstests, linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel,
	djwong

On Sat, Jul 25, 2026 at 03:39:00PM +0800, Anand Jain wrote:
> Define `FSNOTIFYWAIT_PROG` for an upcoming test case that uses `fsnotifywait`.
> 
> Signed-off-by: Anand Jain <asj@kernel.org>
> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
> ---
>  common/config | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/common/config b/common/config
> index d5299d5b926f..5661fa0ec310 100644
> --- a/common/config
> +++ b/common/config
> @@ -242,6 +242,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 FSNOTIFYWAIT_PROG="$(type -P fsnotifywait)"

OK, new *notifywait command.

Reviewed-by: Zorro Lang <zlang@kernel.org>

>  
>  # udev wait functions.
>  #
> -- 
> 2.43.0
> 

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

* Re: [PATCH v8 04/13] fstests: add _require_fanotify_function
  2026-07-25  7:39 ` [PATCH v8 04/13] fstests: add _require_fanotify_function Anand Jain
@ 2026-09-01 15:42   ` Zorro Lang
  0 siblings, 0 replies; 25+ messages in thread
From: Zorro Lang @ 2026-09-01 15:42 UTC (permalink / raw)
  To: Anand Jain
  Cc: fstests, linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel,
	djwong

On Sat, Jul 25, 2026 at 03:39:01PM +0800, Anand Jain wrote:
> fanotify support may not be compiled into the kernel. Add
> _require_fanotify_function to skip tests when fanotify is disabled.
> 
> Signed-off-by: Anand Jain <asj@kernel.org>
> ---
>  common/rc | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/common/rc b/common/rc
> index 53e5d9d43af6..21b516accdf7 100644
> --- a/common/rc
> +++ b/common/rc
> @@ -6329,6 +6329,13 @@ _require_max_file_range_blocks()
>  	esac
>  }
>  
> +_require_fanotify_function()
> +{
> +        if $FSNOTIFYWAIT_PROG 2>&1 | grep -q "Function not implemented"; then
> +                _notrun "Need CONFIG_FANOTIFY and CONFIG_FANOTIFY_ACCESS_PERMISSIONS to be enabled"
> +        fi

What happens if $FSNOTIFYWAIT_PROG fails with an error other than
'Function not implemented'?

Thanks,
Zorro

> +}
> +
>  _require_fanotify_ioerrors()
>  {
>  	local x
> -- 
> 2.43.0
> 

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

* Re: [PATCH v8 05/13] fstests: add _require_unique_f_fsid() helper
  2026-07-25  7:39 ` [PATCH v8 05/13] fstests: add _require_unique_f_fsid() helper Anand Jain
@ 2026-09-01 16:09   ` Zorro Lang
  0 siblings, 0 replies; 25+ messages in thread
From: Zorro Lang @ 2026-09-01 16:09 UTC (permalink / raw)
  To: Anand Jain
  Cc: fstests, linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel,
	djwong

On Sat, Jul 25, 2026 at 03:39:02PM +0800, Anand Jain wrote:
> Add a helper to check if the target filesystem supports unique f_fsid
> tracking across cloned or snapshot instances.
> 
> Certain filesystems like XFS, Btrfs, and F2FS ensure unique f_fsid
> identifiers per filesystem instance. However, Ext4 derives its f_fsid
> directly from its superblock UUID, which leads to identical f_fsid
> values on cloned images until the UUID is manually modified by userspace.
> 
> Introduce _require_unique_f_fsid() to allow test cases requiring strict
> f_fsid uniqueness to skip gracefully on unsupported filesystems.
> 
> Signed-off-by: Anand Jain <asj@kernel.org>
> ---
>  common/rc | 27 +++++++++++++++++++++++++++
>  1 file changed, 27 insertions(+)
> 
> diff --git a/common/rc b/common/rc
> index 21b516accdf7..f73251365a60 100644
> --- a/common/rc
> +++ b/common/rc
> @@ -6356,6 +6356,33 @@ _require_fanotify_ioerrors()
>  	_notrun "$FSTYP does not support fanotify ioerrors"
>  }
>  
> +# Skip the test if the filesystem does not enforce unique f_fsids
> +# natively. Checking this dynamically requires recreating a clone
> +# layout, so we use a static lookup based on FSTYP.
> +#
> +# Across all filesystems, a UUID collision causes libblkid tools to return
> +# non-deterministic device mappings. It is ultimately the responsibility
> +# of the userspace utility or use-case to enforce uniqueness when a clone
> +# diverges. For details, see mailing list thread discussions:
> +#   Link: https://lore.kernel.org/linux-ext4/20260409131238.GC18443@macsyma-wired.lan/
> +_require_unique_f_fsid()
> +{
> +	case "$FSTYP" in
> +	ext*)
> +		# Ext4 derives f_fsid from the superblock UUID, meaning
> +		# clones share the same f_fsid until their UUIDs
> +		# diverge.
> +		_notrun "Target filesystem ($FSTYP) does not guarantee unique f_fsid on clones."
> +		;;
> +	*)
> +		# Conversely, XFS, Btrfs, and F2FS ensure f_fsid remains
> +		# unique per filesystem instance (often by deriving it
> +		# from the UUID and underlying block device.)
> +		;;
> +	esac

I would prefer to let the experts of each filesystem confirm whether their
fs guarantees a unique f_fsid. How about switching this logic to an *allowlist*
*(whitelist)* approach, where we _notrun by default and only allow filesystems
that explicitly guarantee unique f_fsid support?

  case "$FSTYP" in
  btrfs|xfs|f2fs)
        ;;
  *)
        _notrun "Target filesystem ($FSTYP) does not guarantee unique f_fsid on clones."
        ;;
  esac

Thanks,
Zorro

> +}
> +
> +
>  # Computes a percentage of the available space in a filesystem and
>  # returns that quantity in MB. The percentage must not contain a percent
>  # sign ("%").
> -- 
> 2.43.0
> 

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

* Re: [PATCH v8 07/13] fstests: verify fanotify isolation on cloned filesystems
  2026-07-25  7:39 ` [PATCH v8 07/13] fstests: verify fanotify isolation on cloned filesystems Anand Jain
@ 2026-09-01 18:23   ` Zorro Lang
  0 siblings, 0 replies; 25+ messages in thread
From: Zorro Lang @ 2026-09-01 18:23 UTC (permalink / raw)
  To: Anand Jain
  Cc: fstests, linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel,
	djwong

On Sat, Jul 25, 2026 at 03:39:04PM +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>
> ---
>  tests/generic/801     | 143 ++++++++++++++++++++++++++++++++++++++++++

`g/801` is already taken. To avoid merge conflicts, you can use a higher
temporary number, and I'll assign the proper number when merging.

>  tests/generic/801.out |   7 +++
>  2 files changed, 150 insertions(+)
>  create mode 100644 tests/generic/801
>  create mode 100644 tests/generic/801.out
> 
> diff --git a/tests/generic/801 b/tests/generic/801
> new file mode 100644
> index 000000000000..904ba9440b3d
> --- /dev/null
> +++ b/tests/generic/801
> @@ -0,0 +1,143 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2026 Anand Jain <asj@kernel.org>.  All Rights Reserved.
> +#
> +# FS QA Test 801
> +# 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_block_device $TEST_DEV

Which test condition requires `TEST_DEV` to be a block device?

> +_require_loop
> +_require_command "$SEMANAGE_PROG" semanage
> +_require_command "$FSNOTIFYWAIT_PROG" fsnotifywait
> +_require_fanotify_function
> +_require_unique_f_fsid
> +
> +_cleanup()
> +{
> +	cd /
> +	[[ -n $pid1 ]] && { kill -TERM "$pid1" 2> /dev/null; wait $pid1; }
> +	[[ -n $pid2 ]] && { kill -TERM "$pid2" 2> /dev/null; wait $pid2; }
> +
> +	if [ "$semanage_added" = "yes" ]; then
> +		semanage permissive -d unconfined_t >/dev/null 2>&1 || true
> +	fi
> +
> +	umount $mnt1 $mnt2 >/dev/null 2>&1
> +	_loop_image_destroy "${devs[@]}" 2> /dev/null
> +	rm -r -f $tmp.*
> +}
> +
> +# Run fsnotifywait in unbuffered mode to watch filesystem-wide create events
> +monitor_fanotify()
> +{
> +	local mmnt=$1
> +	exec stdbuf -oL $FSNOTIFYWAIT_PROG -m -F -S -e create "$mmnt" 2>&1
> +}
> +
> +# Transform f_fsid into the hi.lo format used in fanotify FID logs
> +fsid_to_fid_parts()
> +{
> +	local fsid=$1
> +	# Pad to 16 hex chars (64-bit), then split into two 32-bit halves
> +	local padded=$(printf '%016x' "0x${fsid}")
> +	local hi=$(printf '%x' "0x${padded:0:8}")   # strips leading zeros
> +	local lo=$(printf '%x' "0x${padded:8:8}")   # strips leading zeros
> +	echo "${hi}.${lo}"
> +}
> +
> +# Create base loop device and its clone
> +devs=()
> +_loop_image_create_clone devs
> +mkdir -p $TEST_DIR/$seq
> +mnt1=$TEST_DIR/$seq/mnt1
> +mnt2=$TEST_DIR/$seq/mnt2
> +mkdir -p $mnt1
> +mkdir -p $mnt2
> +
> +# Mount both base and clone filesystems using required clone mount options
> +_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[0]} $mnt1 || \
> +						_fail "Failed to mount dev1"
> +_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
> +						_fail "Failed to mount dev2"
> +
> +# Fetch filesystem IDs to verify the kernel can differentiate between them
> +fsid1=$(stat -f -c "%i" $mnt1)
> +fsid2=$(stat -f -c "%i" $mnt2)
> +
> +log1=$tmp.fanotify1
> +log2=$tmp.fanotify2
> +
> +pid1=""
> +pid2=""
> +echo "Setup FID fanotify watchers on both mnt1 and mnt2"
> +
> +# Permit unconfined_t domains when SELinux is enforcing to prevent fanotify
> +# blockages
> +semanage_added="no"
> +if [ "$(getenforce 2>/dev/null)" = "Enforcing" ]; then
> +    if ! semanage permissive -l | grep -q "unconfined_t"; then
> +        semanage permissive -a unconfined_t >/dev/null 2>&1 && semanage_added="yes"
> +    fi
> +fi

Looks like semanage/SELinux isn't a necessary requirement of this test case,
if so that `_require_command "$SEMANAGE_PROG" semanage` also can be:

  if [ "$(getenforce 2>/dev/null)" = "Enforcing" ]; then
      _require_command "$SEMANAGE_PROG" semanage
  fi

right? And please replace semanage with $SEMANAGE_PROG.

> +
> +# Start asynchronous fanotify monitors
> +( monitor_fanotify "$mnt1" > "$log1" ) &
> +pid1=$!
> +( monitor_fanotify "$mnt2" > "$log2" ) &
> +pid2=$!
> +sleep 2

Are you using `sleep 2` to ensure `fsnotifywait` is fully set up?
I'm not sure if `sleep 2` is 100% reliable here. Since the subsequent tests
strictly depend on `fsnotifywait` starting up properly, is there a more
robust approach than `sleep 2`? For example, could we check the output
in `$log1` and `$log2` to make sure that? Or any other better idea?

> +
> +if ! kill -0 "$pid1" 2>/dev/null || ! kill -0 "$pid2" 2>/dev/null; then

`kill 0` only can make sure the process is running, can't make sure it's
fully set up, right?

> +	cat "$log1"
> +	cat "$log2"
> +	_fail "$FSNOTIFYWAIT_PROG setup failed"
> +fi
> +
> +echo "Trigger file creation on mnt1"
> +touch $mnt1/file_on_mnt1
> +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
> +pid1=""

unset pid1

> +pid2=""

unset pid2

> +
> +e_fsid1=$(fsid_to_fid_parts "$fsid1")
> +e_fsid2=$(fsid_to_fid_parts "$fsid2")
> +
> +# Dump debug details to the full log
> +echo $fsid1 $e_fsid1 $fsid2 $e_fsid2 >> $seqres.full
> +cat $log1 >> $seqres.full
> +cat $log2 >> $seqres.full
> +
> +# Ensure monitor 1 only captured events belonging to mnt 1 and fsid 1
> +if grep -qF "$e_fsid1" "$log1" && ! grep -qF "$e_fsid2" "$log1"; then
> +	echo "SUCCESS: mnt1 events found"
> +else
> +	[ ! -s "$log1" ] && echo "  - mnt1 received no events."
> +	grep -qF "$e_fsid2" "$log1" && echo "  - mnt1 received event from mnt2."
> +fi
> +
> +# Ensure monitor 2 only captured events belonging to mnt 2 and fsid 2
> +if grep -qF "$e_fsid2" "$log2" && ! grep -qF "$e_fsid1" "$log2"; then
> +	echo "SUCCESS: mnt2 events found"
> +else
> +	[ ! -s "$log2" ] && echo "  - mnt2 received no events."
> +	grep -qF "$e_fsid1" "$log2" && echo "  - mnt2 received event from mnt1."
> +fi
> +
> +status=0
> +exit

_exit 0

Thanks,
Zorro

> diff --git a/tests/generic/801.out b/tests/generic/801.out
> new file mode 100644
> index 000000000000..d7b318d9f27c
> --- /dev/null
> +++ b/tests/generic/801.out
> @@ -0,0 +1,7 @@
> +QA output created by 801
> +Setup FID fanotify watchers on both mnt1 and mnt2
> +Trigger file creation on mnt1
> +Trigger file creation on mnt2
> +Verify fsid in the fanotify
> +SUCCESS: mnt1 events found
> +SUCCESS: mnt2 events found
> -- 
> 2.43.0
> 

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

* Re: [PATCH v8 08/13] fstests: verify f_fsid for cloned filesystems
  2026-07-25  7:39 ` [PATCH v8 08/13] fstests: verify f_fsid for " Anand Jain
@ 2026-09-01 18:51   ` Zorro Lang
  0 siblings, 0 replies; 25+ messages in thread
From: Zorro Lang @ 2026-09-01 18:51 UTC (permalink / raw)
  To: Anand Jain
  Cc: fstests, linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel,
	djwong

On Sat, Jul 25, 2026 at 03:39:05PM +0800, Anand Jain wrote:
> 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/802     | 64 +++++++++++++++++++++++++++++++++++++++++++
>  tests/generic/802.out |  4 +++
>  2 files changed, 68 insertions(+)
>  create mode 100644 tests/generic/802
>  create mode 100644 tests/generic/802.out
> 
> diff --git a/tests/generic/802 b/tests/generic/802
> new file mode 100644
> index 000000000000..910807c11584
> --- /dev/null
> +++ b/tests/generic/802
> @@ -0,0 +1,64 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2026 Anand Jain <asj@kernel.org>.  All Rights Reserved.
> +#
> +# FS QA Test 802
> +# Check that the cloned filesystem provides an f_fsid that is persistent
> +# across mount cycles if the block device maj:min remains unchanged.
> +
> +. ./common/preamble
> +
> +_begin_fstest auto quick mount clone
> +
> +_require_test
> +_require_block_device $TEST_DEV
> +_require_loop
> +
> +_fixed_by_fs_commit btrfs xxxxxxxxxxxx \
> +	"btrfs: use on-disk uuid for s_uuid in temp_fsid mounts"
> +_fixed_by_fs_commit btrfs xxxxxxxxxxxx \
> +	"btrfs: derive f_fsid from on-disk fsuuid and dev_t"
> +
> +_cleanup()
> +{
> +	cd /
> +	rm -r -f $tmp.*
> +	umount $mnt1 $mnt2 2>/dev/null
> +	_loop_image_destroy "${devs[@]}" 2> /dev/null
> +}
> +
> +# Setup base loop device and its clone
> +devs=()
> +_loop_image_create_clone devs
> +mkdir -p $TEST_DIR/$seq

Better to `rm -rf $TEST_DIR/$seq` before creating a new one.

> +mnt1=$TEST_DIR/$seq/mnt1
> +mnt2=$TEST_DIR/$seq/mnt2
> +mkdir -p $mnt1
> +mkdir -p $mnt2
> +
> +# Mount both filesystems simultaneously using mandatory clone mount options
> +_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[0]} $mnt1 || \
> +						_fail "Failed to mount dev1"
> +_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
> +						_fail "Failed to mount dev2"
> +
> +# Capture baseline filesystem IDs for comparison
> +fsid_scratch=$(stat -f -c "%i" $mnt1)
> +fsid_clone=$(stat -f -c "%i" $mnt2)
> +
> +# Verify that the fsids remain stable after a mount cycle, even when the
> +# mount order is reversed.
> +echo "**** fsid after mount cycle ****"
> +_unmount $mnt1
> +_unmount $mnt2
> +_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
> +						_fail "Failed to mount dev2"
> +_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[0]} $mnt1 || \
> +						_fail "Failed to mount dev1"
> +
> +# Compare post mount-cycle values against the baseline
> +stat -f -c "%i" $mnt1 | sed -e "s/$fsid_scratch/FSID_SCRATCH/g"
> +stat -f -c "%i" $mnt2 | sed -e "s/$fsid_clone/FSID_CLONE/g"

Hmm... what if "$fsid_scratch" is same with "$fsid_clone"?

> +
> +status=0
> +exit

_exit 0

> diff --git a/tests/generic/802.out b/tests/generic/802.out
> new file mode 100644
> index 000000000000..0202a9a2c108
> --- /dev/null
> +++ b/tests/generic/802.out
> @@ -0,0 +1,4 @@
> +QA output created by 802
> +**** fsid after mount cycle ****
> +FSID_SCRATCH
> +FSID_CLONE
> -- 
> 2.43.0
> 

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

* Re: [PATCH v8 09/13] fstests: verify libblkid resolution of duplicate UUIDs
  2026-07-25  7:39 ` [PATCH v8 09/13] fstests: verify libblkid resolution of duplicate UUIDs Anand Jain
@ 2026-09-01 19:12   ` Zorro Lang
  0 siblings, 0 replies; 25+ messages in thread
From: Zorro Lang @ 2026-09-01 19:12 UTC (permalink / raw)
  To: Anand Jain
  Cc: fstests, linux-btrfs, linux-ext4, linux-xfs, linux-f2fs-devel,
	djwong

On Sat, Jul 25, 2026 at 03:39:06PM +0800, Anand Jain wrote:
> Verify how findmnt, df (libblkid) resolve device paths when multiple

I didn't find the `df` test part in this test case.

> block devices share the same FSUUID.
> 
> Signed-off-by: Anand Jain <asj@kernel.org>
> ---
>  tests/generic/803     | 72 +++++++++++++++++++++++++++++++++++++++++++
>  tests/generic/803.out |  6 ++++
>  2 files changed, 78 insertions(+)
>  create mode 100644 tests/generic/803
>  create mode 100644 tests/generic/803.out
> 
> diff --git a/tests/generic/803 b/tests/generic/803
> new file mode 100644
> index 000000000000..77901592366c
> --- /dev/null
> +++ b/tests/generic/803
> @@ -0,0 +1,72 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2026 Anand Jain <asj@kernel.org>.  All Rights Reserved.
> +#
> +# FS QA Test 803
> +# Check if the mountinfo based findmnt would resolve to the common uuid
> +# as per the blkid (libblkid based).
> +
> +. ./common/preamble
> +. ./common/filter
> +
> +_begin_fstest auto quick mount clone
> +
> +_require_test
> +_require_block_device $TEST_DEV
> +_require_loop
> +
> +_cleanup()
> +{
> +	cd /
> +	rm -r -f $tmp.*
> +	umount $mnt1 $mnt2 2>/dev/null
> +	_loop_image_destroy "${devs[@]}" 2> /dev/null
> +}
> +
> +# Normalize pool devices and mount points names
> +filter_pool()
> +{
> +	sed -e "s|${devs[0]}|DEV1|g" -e "s|${mnt1}|MNT1|g" \
> +	    -e "s|${devs[1]}|DEV2|g" -e "s|${mnt2}|MNT2|g" | _filter_spaces
> +}
> +
> +# Setup base loop device and its clone
> +devs=()
> +_loop_image_create_clone devs
> +mkdir -p $TEST_DIR/$seq
> +mnt1=$TEST_DIR/$seq/mnt1
> +mnt2=$TEST_DIR/$seq/mnt2
> +mkdir -p $mnt1
> +mkdir -p $mnt2
> +
> +# Get the uuid from the source device
> +fsuuid=$(blkid -s UUID -o value ${devs[0]})
> +
> +# Mount both identical UUID filesystems simultaneously
> +_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[0]} $mnt1 || \
> +						_fail "Failed to mount dev1"
> +_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
> +						_fail "Failed to mount dev2"
> +
> +findmnt -o SOURCE,TARGET,UUID "${devs[0]}" | tail -n +2 | \
> +				sed -e "s/${fsuuid}/FSUUID/g" | filter_pool

findmnt -n (or --noheadings) can be used here (and below) to avoid piping to
`tail -n +2`.

> +findmnt -o SOURCE,TARGET,UUID "${devs[1]}" | tail -n +2 | \
> +				sed -e "s/${fsuuid}/FSUUID/g" | filter_pool

Same here

> +
> +# Btrfs assigned a random uuid for the clone fs before the fix.
> +# Cycle mounts and reverse the initialization (source and clone fs) order.
> +echo "**** mount cycle ****"
> +_unmount $mnt1
> +_unmount $mnt2
> +_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[1]} $mnt2 || \
> +						_fail "Failed to mount dev2"
> +_mount $(_common_dev_mount_options) $(_clone_mount_option) ${devs[0]} $mnt1 || \
> +						_fail "Failed to mount dev1"
> +
> +findmnt -o SOURCE,TARGET,UUID "${devs[0]}" | tail -n +2 | \
> +				sed -e "s/${fsuuid}/FSUUID/g" | filter_pool

Same here

> +findmnt -o SOURCE,TARGET,UUID "${devs[1]}" | tail -n +2 | \
> +				sed -e "s/${fsuuid}/FSUUID/g" | filter_pool

Same here

> +
> +status=0
> +exit

_exit 0

> diff --git a/tests/generic/803.out b/tests/generic/803.out
> new file mode 100644
> index 000000000000..3a130c662430
> --- /dev/null
> +++ b/tests/generic/803.out
> @@ -0,0 +1,6 @@
> +QA output created by 803
> +DEV1 MNT1 FSUUID
> +DEV2 MNT2 FSUUID
> +**** mount cycle ****
> +DEV1 MNT1 FSUUID
> +DEV2 MNT2 FSUUID
> -- 
> 2.43.0
> 

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

end of thread, other threads:[~2026-09-01 19:12 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-25  7:38 [PATCH v8 0/13] fstests: add test coverage for cloned filesystem ids Anand Jain
2026-07-25  7:38 ` [PATCH v8 01/13] fstests: add _loop_image_create_clone() helper Anand Jain
2026-09-01 12:33   ` Zorro Lang
2026-09-01 13:52     ` Anand Suveer Jain
2026-07-25  7:38 ` [PATCH v8 02/13] fstests: add _clone_mount_option() helper Anand Jain
2026-09-01 12:39   ` Zorro Lang
2026-09-01 13:54     ` Anand Suveer Jain
2026-07-25  7:39 ` [PATCH v8 03/13] fstests: add FSNOTIFYWAIT_PROG Anand Jain
2026-09-01 15:37   ` Zorro Lang
2026-07-25  7:39 ` [PATCH v8 04/13] fstests: add _require_fanotify_function Anand Jain
2026-09-01 15:42   ` Zorro Lang
2026-07-25  7:39 ` [PATCH v8 05/13] fstests: add _require_unique_f_fsid() helper Anand Jain
2026-09-01 16:09   ` Zorro Lang
2026-07-25  7:39 ` [PATCH v8 06/13] fstests: add SEMANAGE_PROG Anand Jain
2026-07-25  7:39 ` [PATCH v8 07/13] fstests: verify fanotify isolation on cloned filesystems Anand Jain
2026-09-01 18:23   ` Zorro Lang
2026-07-25  7:39 ` [PATCH v8 08/13] fstests: verify f_fsid for " Anand Jain
2026-09-01 18:51   ` Zorro Lang
2026-07-25  7:39 ` [PATCH v8 09/13] fstests: verify libblkid resolution of duplicate UUIDs Anand Jain
2026-09-01 19:12   ` Zorro Lang
2026-07-25  7:39 ` [PATCH v8 10/13] fstests: verify IMA isolation on cloned filesystems Anand Jain
2026-07-25  7:39 ` [PATCH v8 11/13] fstests: verify exportfs file handles " Anand Jain
2026-07-25  7:39 ` [PATCH v8 12/13] fstests: add _change_metadata_uuid helper Anand Jain
2026-07-25  7:39 ` [PATCH v8 13/13] fstests: test UUID consistency for clones with metadata_uuid Anand Jain
2026-08-31  7:17 ` [PATCH v8 0/13] fstests: add test coverage for cloned filesystem ids Anand Suveer Jain

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