From 72de4807ba84da485dda1a91572d66da9149e95a Mon Sep 17 00:00:00 2001 From: Anand Jain Date: Sun, 13 Sep 2026 02:06:28 +0800 Subject: [PATCH] btrfs: derive f_fsid with dev_t only when temp_fsid is active Commit c2a74ed0494c ("btrfs: derive f_fsid from on-disk fsid and dev_t") mixed dev_t into f_fsid for all single-device setups to avoid f_fsid collisions with cloned filesystems. However, doing this unconditionally breaks backward compatibility. statfs(2) f_fsid changes after a kernel upgrade, and also can shift across reboots or dev re-attaches as dev_t values change. Fix this by only mixing dev_t when temp_fsid is active. This means for non-temp_fsid setups or the original mount, we use the old method of deriving fsid based on the UUID. So in the case of a cloned Btrfs filesystem, we won't be able to maintain the same fsid across mount recycle if the mount order changes. Reported-by: Dave Hansen Link: https://lore.kernel.org/linux-btrfs/be0c08f5-2f31-40f5-8a3b-f2f58b3e00ff@intel.com Fixes: c2a74ed0494c ("btrfs: derive f_fsid from on-disk fsid and dev_t") CC: stable@vger.kernel.org # 7.2 Signed-off-by: Anand Jain Reviewed-by: David Sterba Signed-off-by: David Sterba --- fs/btrfs/super.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 464129b1b0d4..ddb620ac241b 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1836,8 +1836,12 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) f_fsid.val[0] ^= btrfs_root_id(BTRFS_I(d_inode(dentry))->root) >> 32; f_fsid.val[1] ^= btrfs_root_id(BTRFS_I(d_inode(dentry))->root); - /* Hash dev_t to avoid f_fsid collision with cloned filesystems. */ - if (fs_info->fs_devices->total_devices == 1) { + /* + * Hash dev_t to avoid f_fsid collisions with cloned filesystems. + * Only do this when a clone is present so the original filesystem + * (mounted first) maintains backward-compatible f_fsid behavior. + */ + if (fs_info->fs_devices->temp_fsid) { __kernel_fsid_t dev_fsid = u64_to_fsid(huge_encode_dev(fs_info->fs_devices->latest_dev->bdev->bd_dev));