Skip to contentSkip to conversation

fix s_uuid and f_fsid consistency for cloned filesystems

PATCH Superseded Anand Jain 6 participants 24 messages Mar 21 – Apr 27

Subsystems (2)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore

Anand Jain

author
#0 lore raw

v2 cover fix s_uuid and f_fsid consistency for cloned filesystems

v2:
Derive statfs::f_fsid only when using new 'nouuid'; naming matches with xfs.

v1:
btrfs:
https://lore.kernel.org/linux-btrfs/[email protected]/
ext4:
https://lore.kernel.org/linux-ext4/e269a49eed2de23eb9f9bd7f506f0fe47696a023.1772095546.git.asj@kernel.org/

Anand Jain (3):
btrfs: use on-disk uuid for s_uuid in temp_fsid mounts
btrfs: derive f_fsid from on-disk fsuuid and dev_t
ext4: derive f_fsid from block device to avoid collisions

 fs/btrfs/disk-io.c |  3 ++-
 fs/btrfs/fs.h      |  1 +
 fs/btrfs/super.c   | 35 +++++++++++++++++++++++++++++++----
 fs/ext4/ext4.h     |  1 +
 fs/ext4/super.c    | 12 ++++++++++--
 5 files changed, 45 insertions(+), 7 deletions(-)
Signature · 1 line
2.43.0
author
#1 lore raw

PATCH v2 1/3 btrfs: use on-disk uuid for s_uuid in temp_fsid mounts

When mounting a cloned filesystem with a temporary fsuuid (temp_fsid), layered modules like overlayfs require a persistent identifier.

While the internal in-memory fs_devices->fsid must remain unique, to distinguish each instance of the mounted filesystem, let s_uuid carry the original on-disk UUID.

---
 fs/btrfs/disk-io.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
fs/btrfs/disk-io.c +2 -1
index c835141ee384..90e0369bf682 100644
@@ -3451,7 +3451,8 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
 	/* Update the values for the current filesystem. */
 	sb->s_blocksize = sectorsize;
 	sb->s_blocksize_bits = blksize_bits(sectorsize);
-	memcpy(&sb->s_uuid, fs_info->fs_devices->fsid, BTRFS_FSID_SIZE);
+	/* Copy on-disk uuid, even for temp_fsid mounts */
+	memcpy(&sb->s_uuid, fs_info->super_copy->fsid, BTRFS_FSID_SIZE);
 
 	mutex_lock(&fs_info->chunk_mutex);
 	ret = btrfs_read_sys_array(fs_info);
Signature · 1 line
2.43.0
author
#2 lore raw

PATCH v2 2/3 btrfs: derive f_fsid from on-disk fsuuid and dev_t

In reply to Anand Jain

f_fsid depends on fs_devices->fsid and subvol root id.

For cloned devices either same as the source or dynamical generated at mount won't suite because tools like fanotify and ima depends on it.

Switch to a stable derivation using the persistent on-disk fsuuid + root id + devt of the block device for the single device filesystem. This is consistent as long as the device remains unchanged/replace (excludes btrfs device replace secnario for now).

This change is only for the single device configs and is behind the -o nouuid mount option to keep this change compatible with ABI.

---
 fs/btrfs/fs.h    |  1 +
 fs/btrfs/super.c | 35 +++++++++++++++++++++++++++++++----
 2 files changed, 32 insertions(+), 4 deletions(-)
fs/btrfs/fs.h +1 -0
index a4758d94b32e..6e2a5c2bd03c 100644
@@ -270,6 +270,7 @@ enum {
 	BTRFS_MOUNT_IGNOREMETACSUMS		= (1ULL << 31),
 	BTRFS_MOUNT_IGNORESUPERFLAGS		= (1ULL << 32),
 	BTRFS_MOUNT_REF_TRACKER			= (1ULL << 33),
+	BTRFS_MOUNT_NOUUID			= (1ULL << 34),
 };
 
 /* These mount options require a full read-only fs, no new transaction is allowed. */
fs/btrfs/super.c +31 -4
index 125fca57c164..2fb82032f1e1 100644
@@ -102,6 +102,7 @@ enum {
 	Opt_compress_type,
 	Opt_degraded,
 	Opt_device,
+	Opt_nouuid,
 	Opt_fatal_errors,
 	Opt_flushoncommit,
 	Opt_max_inline,
@@ -227,6 +228,7 @@ static const struct fs_parameter_spec btrfs_fs_parameters[] = {
 	fsparam_flag_no("datasum", Opt_datasum),
 	fsparam_flag("degraded", Opt_degraded),
 	fsparam_string("device", Opt_device),
+	fsparam_flag("nouuid", Opt_nouuid),
 	fsparam_flag_no("discard", Opt_discard),
 	fsparam_enum("discard", Opt_discard_mode, btrfs_parameter_discard),
 	fsparam_enum("fatal_errors", Opt_fatal_errors, btrfs_parameter_fatal_errors),
@@ -382,6 +384,9 @@ static int btrfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
 			return PTR_ERR(device);
 		break;
 	}
+	case Opt_nouuid:
+		btrfs_set_opt(ctx->mount_opt, NOUUID);
+		break;
 	case Opt_datasum:
 		if (result.negated) {
 			btrfs_set_opt(ctx->mount_opt, NODATASUM);
@@ -1113,6 +1118,8 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
 		seq_puts(seq, ",discard");
 	if (btrfs_test_opt(info, DISCARD_ASYNC))
 		seq_puts(seq, ",discard=async");
+	if (btrfs_test_opt(info, NOUUID))
+		seq_puts(seq, ",nouuid");
 	if (!(info->sb->s_flags & SB_POSIXACL))
 		seq_puts(seq, ",noacl");
 	if (btrfs_free_space_cache_v1_active(info))
@@ -1733,7 +1740,7 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 	u64 total_free_data = 0;
 	u64 total_free_meta = 0;
 	u32 bits = fs_info->sectorsize_bits;
-	__be32 *fsid = (__be32 *)fs_info->fs_devices->fsid;
+	__be32 *fsid;
 	unsigned factor = 1;
 	struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv;
 	int ret;
@@ -1819,15 +1826,35 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 	buf->f_bsize = fs_info->sectorsize;
 	buf->f_namelen = BTRFS_NAME_LEN;
 
-	/* We treat it as constant endianness (it doesn't matter _which_)
-	   because we want the fsid to come out the same whether mounted
-	   on a big-endian or little-endian host */
+	/*
+	 * fs_devices->fsid is dynamically generated when temp_fsid is active
+	 * to support cloned devices. Use the original on-disk fsid instead,
+	 * as it remains consistent across mount cycles.
+	 */
+	fsid = (__be32 *)fs_info->super_copy->fsid;
+	/*
+	 * We treat it as constant endianness (it doesn't matter _which_)
+	 * because we want the fsid to come out the same whether mounted
+	 * on a big-endian or little-endian host.
+	 */
 	buf->f_fsid.val[0] = be32_to_cpu(fsid[0]) ^ be32_to_cpu(fsid[2]);
 	buf->f_fsid.val[1] = be32_to_cpu(fsid[1]) ^ be32_to_cpu(fsid[3]);
 	/* Mask in the root object ID too, to disambiguate subvols */
 	buf->f_fsid.val[0] ^= btrfs_root_id(BTRFS_I(d_inode(dentry))->root) >> 32;
 	buf->f_fsid.val[1] ^= btrfs_root_id(BTRFS_I(d_inode(dentry))->root);
 
+	/*
+	 * dev_t provides way to differentiate mounted cloned devices keeps
+	 * the statfs fid is consistent and unique.
+	 */
+	if (btrfs_test_opt(fs_info, NOUUID) &&
+	    fs_info->fs_devices->total_devices == 1) {
+		__kernel_fsid_t dev_fsid = \
+	u64_to_fsid(huge_encode_dev(fs_info->fs_devices->latest_dev->bdev->bd_dev));
+		buf->f_fsid.val[0] ^= dev_fsid.val[1];
+		buf->f_fsid.val[1] ^= dev_fsid.val[0];
+	}
+
 	return 0;
 }
 
Signature · 1 line
2.43.0
author
#3 lore raw

PATCH v2 3/3 ext4: derive f_fsid from block device to avoid collisions

In reply to Anand Jain

statfs() currently reports f_fsid derived from the on-disk UUID. Cloned block devices share the same UUID, so distinct ext4 instances can return identical f_fsid values. This leads to collisions in fanotify.

Encode sb->s_dev into f_fsid instead of using the superblock UUID. This provides a per-device identifier and avoids conflicts when filesystem is cloned, matching the behavior with xfs.

Place this change behind the new mount option "-o nouuid" for ABI compatibility.

---
 fs/ext4/ext4.h  |  1 +
 fs/ext4/super.c | 12 ++++++++++--
 2 files changed, 11 insertions(+), 2 deletions(-)
fs/ext4/ext4.h +1 -0
index 293f698b7042..64d98ab64c11 100644
@@ -1282,6 +1282,7 @@ struct ext4_inode_info {
 						    * scanning in mballoc
 						    */
 #define EXT4_MOUNT2_ABORT		0x00000100 /* Abort filesystem */
+#define EXT4_MOUNT2_NOUUID		0x00000200 /* No duplicate f_fsid for cloned filesystem */
 
 #define clear_opt(sb, opt)		EXT4_SB(sb)->s_mount_opt &= \
 						~EXT4_MOUNT_##opt
fs/ext4/super.c +10 -2
index 43f680c750ae..65b712af4ad7 100644
@@ -1664,7 +1664,7 @@ static const struct export_operations ext4_export_ops = {
 enum {
 	Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
 	Opt_resgid, Opt_resuid, Opt_sb,
-	Opt_nouid32, Opt_debug, Opt_removed,
+	Opt_nouid32, Opt_debug, Opt_removed, Opt_nouuid,
 	Opt_user_xattr, Opt_acl,
 	Opt_auto_da_alloc, Opt_noauto_da_alloc, Opt_noload,
 	Opt_commit, Opt_min_batch_time, Opt_max_batch_time, Opt_journal_dev,
@@ -1743,6 +1743,7 @@ static const struct fs_parameter_spec ext4_param_specs[] = {
 	fsparam_u32	("sb",			Opt_sb),
 	fsparam_enum	("errors",		Opt_errors, ext4_param_errors),
 	fsparam_flag	("nouid32",		Opt_nouid32),
+	fsparam_flag	("nouuid",		Opt_nouuid),
 	fsparam_flag	("debug",		Opt_debug),
 	fsparam_flag	("oldalloc",		Opt_removed),
 	fsparam_flag	("orlov",		Opt_removed),
@@ -1898,6 +1899,7 @@ static const struct mount_opts {
 	{Opt_acl, 0, MOPT_NOSUPPORT},
 #endif
 	{Opt_nouid32, EXT4_MOUNT_NO_UID32, MOPT_SET},
+	{Opt_nouuid, EXT4_MOUNT2_NOUUID, MOPT_SET | MOPT_2},
 	{Opt_debug, EXT4_MOUNT_DEBUG, MOPT_SET},
 	{Opt_quota, EXT4_MOUNT_QUOTA | EXT4_MOUNT_USRQUOTA, MOPT_SET | MOPT_Q},
 	{Opt_usrquota, EXT4_MOUNT_QUOTA | EXT4_MOUNT_USRQUOTA,
@@ -2389,6 +2391,9 @@ static int ext4_parse_param(struct fs_context *fc, struct fs_parameter *param)
 			return -EINVAL;
 		}
 		return 0;
+	case Opt_nouuid:
+		ctx_set_mount_opt2(ctx, EXT4_MOUNT2_NOUUID);
+		return 0;
 	}
 
 	/*
@@ -6941,7 +6946,10 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf)
 	buf->f_files = le32_to_cpu(es->s_inodes_count);
 	buf->f_ffree = percpu_counter_sum_positive(&sbi->s_freeinodes_counter);
 	buf->f_namelen = EXT4_NAME_LEN;
-	buf->f_fsid = uuid_to_fsid(es->s_uuid);
+	if (test_opt2(sb, NOUUID))
+		buf->f_fsid = u64_to_fsid(huge_encode_dev(sb->s_bdev->bd_dev));
+	else
+		buf->f_fsid = uuid_to_fsid(es->s_uuid);
 
 #ifdef CONFIG_QUOTA
 	if (ext4_test_inode_flag(dentry->d_inode, EXT4_INODE_PROJINHERIT) &&
Signature · 1 line
2.43.0
maintainer
#4 lore raw

Re: [PATCH v2 3/3] ext4: derive f_fsid from block device to avoid collisions

Quoted 8 lines · Anand Jain

statfs() currently reports f_fsid derived from the on-disk UUID. Cloned block devices share the same UUID, so distinct ext4 instances can return identical f_fsid values. This leads to collisions in fanotify.

Encode sb->s_dev into f_fsid instead of using the superblock UUID. This provides a per-device identifier and avoids conflicts when filesystem is cloned, matching the behavior with xfs.

As I observed in [1] this leads to collisions when for removable block devices which can be used to mount different file systems.

[1] https://lore.kernel.org/all/[email protected]/

Quoted 2 lines

Place this change behind the new mount option "-o nouuid" for ABI compatibility.

I *really* hate this mount option. It's not at all obvious what it means for a system administrator who hasn't had the context of reading the e-mail discussion on this subject.

As I stated in [1], I think the f_fsid is a terrible interface that was promulgated by history, and future usage should be strongly discouraged, and the wise programmer won't use it because it has significant compatibility issues.

As such, my personal preference is that we not try to condition it on a mount option, which in all likelihood almost no one will use, and instead just change it so that we hash the file system's UUID and block device number together and use that for ext4's f_fsid.

Thoughts, comments?

- Ted

#5 lore raw

Re: [PATCH v2 3/3] ext4: derive f_fsid from block device to avoid collisions

Quoted 13 lines · Theodore Tso
Quoted 8 lines · Anand Jain

statfs() currently reports f_fsid derived from the on-disk UUID. Cloned block devices share the same UUID, so distinct ext4 instances can return identical f_fsid values. This leads to collisions in fanotify.

Encode sb->s_dev into f_fsid instead of using the superblock UUID. This provides a per-device identifier and avoids conflicts when filesystem is cloned, matching the behavior with xfs.

As I observed in [1] this leads to collisions when for removable block devices which can be used to mount different file systems.

Quoted 8 lines

[1] https://lore.kernel.org/all/[email protected]/

Quoted 2 lines

Place this change behind the new mount option "-o nouuid" for ABI compatibility.

I *really* hate this mount option. It's not at all obvious what it means for a system administrator who hasn't had the context of reading the e-mail discussion on this subject.

I don't love 'nouuid' either, because it means something completely different in XFS. 'fsid_from_dev' or something would at least be clearer about what it's doing...

Quoted 9 lines

As I stated in [1], I think the f_fsid is a terrible interface that was promulgated by history, and future usage should be strongly discouraged, and the wise programmer won't use it because it has significant compatibility issues.

As such, my personal preference is that we not try to condition it on a mount option, which in all likelihood almost no one will use, and instead just change it so that we hash the file system's UUID and block device number together and use that for ext4's f_fsid.

...but why not just set fsid to some approximation of the dev_t like XFS and be done with it?

	st->f_fsid = u64_to_fsid(huge_encode_dev(mp->m_ddev_targp->bt_dev))

There are a few other single-bdev filesystems that do this.

--D

Quoted 4 lines

Thoughts, comments?

- Ted

#6 lore raw

Re: [PATCH v2 3/3] ext4: derive f_fsid from block device to avoid collisions

Quoted 37 lines · Darrick J. Wong
Quoted 13 lines · Theodore Tso
Quoted 8 lines · Anand Jain

statfs() currently reports f_fsid derived from the on-disk UUID. Cloned block devices share the same UUID, so distinct ext4 instances can return identical f_fsid values. This leads to collisions in fanotify.

Encode sb->s_dev into f_fsid instead of using the superblock UUID. This provides a per-device identifier and avoids conflicts when filesystem is cloned, matching the behavior with xfs.

As I observed in [1] this leads to collisions when for removable block devices which can be used to mount different file systems.

Quoted 8 lines

[1] https://lore.kernel.org/all/[email protected]/

Quoted 2 lines

Place this change behind the new mount option "-o nouuid" for ABI compatibility.

I *really* hate this mount option. It's not at all obvious what it means for a system administrator who hasn't had the context of reading the e-mail discussion on this subject.

I don't love 'nouuid' either, because it means something completely different in XFS. 'fsid_from_dev' or something would at least be clearer about what it's doing...

Quoted 9 lines

As I stated in [1], I think the f_fsid is a terrible interface that was promulgated by history, and future usage should be strongly discouraged, and the wise programmer won't use it because it has significant compatibility issues.

As such, my personal preference is that we not try to condition it on a mount option, which in all likelihood almost no one will use, and instead just change it so that we hash the file system's UUID and block device number together and use that for ext4's f_fsid.

Quoted 6 lines

...but why not just set fsid to some approximation of the dev_t like XFS and be done with it?

	st->f_fsid = u64_to_fsid(huge_encode_dev(mp->m_ddev_targp->bt_dev))

There are a few other single-bdev filesystems that do this.

/me reads the rest of both threads, realizes the answer is "because you can eject media, mount another media with the same fs, and bizarrely they produce the same fsid."

I'll point out that for the filesystems that base fsid off of a block device, perhaps we should mix in the diskseq to prevent that problem?

But then someone said the magic words "IMA and fanotify also use fsid" and /me backs away from yet another opportunity to argue about open-coded file handles from legacy Unix.

--D

#7 lore raw

Re: [PATCH v2 3/3] ext4: derive f_fsid from block device to avoid collisions

In reply to Darrick J. Wong
Quoted 38 lines · Darrick J. Wong
Quoted 13 lines · Theodore Tso
Quoted 8 lines · Anand Jain

statfs() currently reports f_fsid derived from the on-disk UUID. Cloned block devices share the same UUID, so distinct ext4 instances can return identical f_fsid values. This leads to collisions in fanotify.

Encode sb->s_dev into f_fsid instead of using the superblock UUID. This provides a per-device identifier and avoids conflicts when filesystem is cloned, matching the behavior with xfs.

As I observed in [1] this leads to collisions when for removable block devices which can be used to mount different file systems.

Quoted 8 lines

[1] https://lore.kernel.org/all/[email protected]/

Quoted 2 lines

Place this change behind the new mount option "-o nouuid" for ABI compatibility.

I *really* hate this mount option. It's not at all obvious what it means for a system administrator who hasn't had the context of reading the e-mail discussion on this subject.

I don't love 'nouuid' either, because it means something completely different in XFS. 'fsid_from_dev' or something would at least be clearer about what it's doing...

Quoted 9 lines

As I stated in [1], I think the f_fsid is a terrible interface that was promulgated by history, and future usage should be strongly discouraged, and the wise programmer won't use it because it has significant compatibility issues.

As such, my personal preference is that we not try to condition it on a mount option, which in all likelihood almost no one will use, and instead just change it so that we hash the file system's UUID and block device number together and use that for ext4's f_fsid.

Quoted 6 lines

...but why not just set fsid to some approximation of the dev_t like XFS and be done with it?

st->f_fsid = u64_to_fsid(huge_encode_dev(mp->m_ddev_targp->bt_dev))

There are a few other single-bdev filesystems that do this.

On the flip side, if the fsid of a filesystem changes because a new disk was installed on a server and the old disk gets a new device number or an upgraded kernel with different device driver load ordering, that would also be a big problem, as it would break NFS file handles over a reboot.

The whole point of generating the fsid from the persistent storage is that it is persistent across reboots. It seems like the real issue here is cloning filesystem images and not assigning a new UUID to the cloned image.

Cheers, Andreas

#8 lore raw

Re: [PATCH v2 3/3] ext4: derive f_fsid from block device to avoid collisions

Quoted 46 lines · Andreas Dilger
Quoted 38 lines · Darrick J. Wong
Quoted 13 lines · Theodore Tso
Quoted 8 lines · Anand Jain

statfs() currently reports f_fsid derived from the on-disk UUID. Cloned block devices share the same UUID, so distinct ext4 instances can return identical f_fsid values. This leads to collisions in fanotify.

Encode sb->s_dev into f_fsid instead of using the superblock UUID. This provides a per-device identifier and avoids conflicts when filesystem is cloned, matching the behavior with xfs.

As I observed in [1] this leads to collisions when for removable block devices which can be used to mount different file systems.

Quoted 8 lines

[1] https://lore.kernel.org/all/[email protected]/

Quoted 2 lines

Place this change behind the new mount option "-o nouuid" for ABI compatibility.

I *really* hate this mount option. It's not at all obvious what it means for a system administrator who hasn't had the context of reading the e-mail discussion on this subject.

I don't love 'nouuid' either, because it means something completely different in XFS. 'fsid_from_dev' or something would at least be clearer about what it's doing...

Quoted 9 lines

As I stated in [1], I think the f_fsid is a terrible interface that was promulgated by history, and future usage should be strongly discouraged, and the wise programmer won't use it because it has significant compatibility issues.

As such, my personal preference is that we not try to condition it on a mount option, which in all likelihood almost no one will use, and instead just change it so that we hash the file system's UUID and block device number together and use that for ext4's f_fsid.

Quoted 6 lines

...but why not just set fsid to some approximation of the dev_t like XFS and be done with it?

st->f_fsid = u64_to_fsid(huge_encode_dev(mp->m_ddev_targp->bt_dev))

There are a few other single-bdev filesystems that do this.

Quoted 9 lines

On the flip side, if the fsid of a filesystem changes because a new disk was installed on a server and the old disk gets a new device number or an upgraded kernel with different device driver load ordering, that would also be a big problem, as it would break NFS file handles over a reboot.

The whole point of generating the fsid from the persistent storage is that it is persistent across reboots. It seems like the real issue here is cloning filesystem images and not assigning a new UUID to the cloned image.

IMO, sb->s_uuid (as used by overlayfs)
Represents a filesystem UUID that is persistent.
It is derived from on-disk metadata.

statfs()->f_fsid is..
A kind of runtime filesystem identifier used to distinguish mounted filesystems within a running system.
It may be stable across reboots or device removal and reinsertion, but this is not guaranteed. It may change if the device dev_t changes.

I have posted a set of five test cases to the mailing list to help verify these behaviors, for your review. Another test case to verify device reinsertion with a different dev_t is a WIP; it will be submitted along with v3.

Thanks.

Quoted 1 line

Cheers, Andreas

maintainer
#9 lore raw

Re: [PATCH v2 3/3] ext4: derive f_fsid from block device to avoid collisions

Quoted 10 lines · Anand Jain

IMO, sb->s_uuid (as used by overlayfs)
Represents a filesystem UUID that is persistent.
It is derived from on-disk metadata.

statfs()->f_fsid is..
A kind of runtime filesystem identifier used to distinguish mounted filesystems within a running system.
It may be stable across reboots or device removal and reinsertion, but this is not guaranteed. It may change if the device dev_t changes.

I always worry about "it might be stable, but it might not; ¯\_(ツ)_/¯"

The problem with that is that people might starting using this kinda-of-guarantee-but-maybe-not in scripts or in programs, and then when people try to run that script or program on a different system, or on a different file system, things goes *boom*.

So if we want to say that it is stable so long as dev_t and the file system the same, that's a well defined semantic.

If it's that it has no guarantees whatsoever; cloud change across reboots; could change across remounts, then maybe it should just be a global mount sequence number that starts with a random number at boot. So you can use it to distinguish between different mounted file systems, but that's *all* you can do with the thing. That would also be a well defined semantic.

Cheers,

- Ted

#10 lore raw

Re: [PATCH v2 3/3] ext4: derive f_fsid from block device to avoid collisions

Quoted 14 lines · Theodore Tso
Quoted 10 lines · Anand Jain

IMO, sb->s_uuid (as used by overlayfs)
Represents a filesystem UUID that is persistent.
It is derived from on-disk metadata.

statfs()->f_fsid is..
A kind of runtime filesystem identifier used to distinguish mounted filesystems within a running system.
It may be stable across reboots or device removal and reinsertion, but this is not guaranteed. It may change if the device dev_t changes.

I always worry about "it might be stable, but it might not; ¯\_(ツ)_/¯"

Quoted 8 lines

The problem with that is that people might starting using this kinda-of-guarantee-but-maybe-not in scripts or in programs, and then when people try to run that script or program on a different system, or on a different file system, things goes *boom*.

So if we want to say that it is stable so long as dev_t and the file system the same, that's a well defined semantic.

Yeah, agreed. Avoid misuse. Document that f_fsid is stable as long as dev_t and the underlying filesystem identity don't change.

Quoted 7 lines

If it's that it has no guarantees whatsoever; cloud change across reboots; could change across remounts, then maybe it should just be a global mount sequence number that starts with a random number at boot. So you can use it to distinguish between different mounted file systems, but that's *all* you can do with the thing. That would also be a well defined semantic.

Per-mount random value (or global mount sequence) is also a well-defined semantic, but it comes with trade-offs: we lose consistency across mount cycles and need to carry per-mount state.

IMHO, it's better to stick with a deterministic id:

f_fsid = f(dev_t, fsid)

predictable and aligned with XFS/btrfs and avoids additional state. Bottom line, it fixes the cloned filesystem case without regressing the existing semantics.

#11 lore raw

Re: [PATCH v2 3/3] ext4: derive f_fsid from block device to avoid collisions

In reply to Theodore Tso

Thanks for the feedback. I'll try to address the points raised here and in your earlier email [1].

[1] https://lore.kernel.org/all/[email protected]/

This work originally came out of a Btrfs issue where a cloned filesystem ended up using a dynamically generated, mount-time UUID for sb->s_uuid instead of the on-disk UUID. As a result, OverlayFS (with index enabled) started failing mount-recycle tests [2] for the cloned filesystem.

[2]
https://lore.kernel.org/lkml/[email protected]/

While looking into that problem, I also noticed that different filesystems derive f_fsid in inconsistent ways, and in practice many of them base it on dev_t.

On the question of the 64-bit limit: although a 64-bit value is not globally unique in the way a 128-bit UUID is, f_fsid has historically been derived from dev_t. Since dev_t must be unique within a running kernel instance, 64 bits are enough to safely encode its effective ~32-bit dev_t without collisions. The number of concurrently addressable block devices is also bounded by the 12-bit major / 20-bit minor limits and /proc/sys/fs/mount-max. IMO, within a single boot, 64 bits should provide a collision-free identifier.

I've also submitted new test cases that validate expectations around both sb->s_uuid and statfs::f_fsid here [3].

[3] https://lore.kernel.org/fstests/[email protected]/

Quoted 4 lines

As I observed in [1] this leads to collisions when for removable block devices which can be used to mount different file systems.

[1] https://lore.kernel.org/all/[email protected]/

I agree. A straightforward f_fsid = f(dev_t) will collide if a removable device is swapped but ends up reusing the same dev_t. Theoretically, I see this can be reproduced with XFS, and with my current patchset on Ext4. That’s clearly a blocker, and I plan to revise, btw Btrfs does well for this test scenario.

Quoted 4 lines

And even as you've proposed to change
things, it's not consistent across file systems. In particular, your proposed solution mixes s_uuid into btrfs-patched, but not ext4-patched. Why?

The discrepancy exists because Btrfs must distinguish subvolume mounts as separate logical entities. For Btrfs, the derivation requires f(s_uuid, root_id, dev_t) to ensure that two different subvolumes on the same device report distinct f_fsid values. For Ext4, a simpler f(s_uuid, dev_t) should suffice to ensure both cross-device uniqueness and persistent across media swaps.

Quoted 12 lines
Quoted 2 lines

Place this change behind the new mount option "-o nouuid" for ABI compatibility.

I *really* hate this mount option. It's not at all obvious what it means for a system administrator who hasn't had the context of reading the e-mail discussion on this subject.

As I stated in [1], I think the f_fsid is a terrible interface that was promulgated by history, and future usage should be strongly discouraged, and the wise programmer won't use it because it has significant compatibility issues.

Quoted 4 lines

As such, my personal preference is that we not try to condition it on a mount option, which in all likelihood almost no one will use, and instead just change it so that we hash the file system's UUID and block device number together and use that for ext4's f_fsid.

The decision to gate this behind a mount option followed feedback from Christoph Hellwig. The concern is binary compatibility:
applications that manually derive an ID based on existing behavior might break if the kernel changes its derivation logic.

I agree that -o nouuid is a poor name. If we must keep the mount option for ABI stability, I am open to better nomenclature.

If we agree that f_fsid is already a problematic interface and should simply be fixed without any special options for example by always hashing the filesystem UUID together with the block device number for Ext4, that would be my preference.

Thanks, Anand

#12 lore raw

Re: [PATCH v2 3/3] ext4: derive f_fsid from block device to avoid collisions

Hi Ted, Christoph, Darrick,

As I prepare v3, I'd appreciate your final thoughts on the mount option naming and its necessity for ext4.

For the new option, I am considering:

-o nodup_f_fsid

-o unique_f_fsid

Context:
Currently, ext4's f_fsid is consistent across reboots but fails to be unique when dealing with cloned filesystems (sharing the same UUID). Per statfs(2) [1], the primary requirement is that the (f_fsid, ino) pair uniquely identifies a file. The man page makes no explicit guarantee regarding consistency across mount cycles or reboots.

Proposal:
With this fix, f_fsid becomes f(uuid, dev_t). This ensures OS-wide uniqueness and maintains consistency as long as the underlying dev_t remains stable.

Dilemma:
While statfs(2) [1] suggests f_fsid is "some random stuff," we know userspace (NFS, systemd) often treats it as a persistent handle.

Do you prefer one of the names above, or is there a more idiomatic ext4 naming convention I should follow?

Given the ambiguity in the man page, is gating this behind an -o option necessary, or should we consider making uniqueness the default behavior?

[1]
----------
statfs(2)

<snap>
Nobody knows what f_fsid is supposed to contain (but see below).

<snap>
The f_fsid field
Solaris, Irix, and POSIX have a system call statvfs(2)
that returns a struct statvfs (defined in <sys/statvfs.h>) containing an unsigned long f_fsid. Linux, SunOS, HP-UX, 4.4BSD have a system
call statfs() that returns a struct statfs (defined in <sys/vfs.h>)
containing a fsid_t f_fsid, where fsid_t is defined as struct { int val[2]; }. The same holds for FreeBSD, except that it uses the include file <sys/mount.h>.

The general idea is that f_fsid contains some random stuff such
that the pair (f_fsid,ino) uniquely determines a file. Some operating systems use (a variation on) the device number, or the device number combined with the filesystem type. Several operating systems restrict giving out the f_fsid field to the superuser only (and zero it for unprivileged users), because this field is used in the filehandle of the filesystem when NFS-exported, and giving it out is a security concern.

Under some operating systems, the fsid can be used as the second
argument to the sysfs(2) system call.
----------

Thanks, Anand

#13 lore raw

Re: [PATCH v2 3/3] ext4: derive f_fsid from block device to avoid collisions

Quoted 16 lines · Anand Jain

Context:
Currently, ext4's f_fsid is consistent across reboots but fails to be unique when dealing with cloned filesystems (sharing the same UUID). Per statfs(2) [1], the primary requirement is that the (f_fsid, ino) pair uniquely identifies a file. The man page makes no explicit guarantee regarding consistency across mount cycles or reboots.

Proposal:
With this fix, f_fsid becomes f(uuid, dev_t). This ensures OS-wide uniqueness and maintains consistency as long as the underlying dev_t remains stable.

Dilemma:
While statfs(2) [1] suggests f_fsid is "some random stuff," we know userspace (NFS, systemd) often treats it as a persistent handle.

Quoted 6 lines

Do you prefer one of the names above, or is there a more idiomatic ext4 naming convention I should follow?

Given the ambiguity in the man page, is gating this behind an -o option necessary, or should we consider making uniqueness the default behavior?

My take is that anything that should persist should be an on-disk feature flag, not a mount option. But I'm not in charge for ext4.

maintainer
#14 lore raw

Re: [PATCH v2 3/3] ext4: derive f_fsid from block device to avoid collisions

Quoted 10 lines · Christoph Hellwig
Quoted 7 lines

Dilemma:
While statfs(2) [1] suggests f_fsid is "some random stuff," we know userspace (NFS, systemd) often treats it as a persistent handle.

Do you prefer one of the names above, or is there a more idiomatic ext4 naming convention I should follow?

My take is that anything that should persist should be an on-disk feature flag, not a mount option. But I'm not in charge for ext4

My take is that f_fsid is random stuff, as documented by the specification, so anyone who tries to depend on it needs to be kept in a padding room where they can't hurt themselves or their users.

And as far as NFS is concerned, file handles should be based on the super block UUID, not statfs's f_fsid, and anyone who wants to mount a snapshot as an NFS exported file system at the same time that the original file system is mounted is _also_ should be gently coaxed into a padding room where they can't hurt themselves or their users.

The solution that we've used for people who are cloning block devices for things like cloud images has been for *years* has been to use "tune2fs -U random /dev/sda1". And this works on mounted file system, and (for example) built into various cloud images for Google Cloud Engine.

If we want to change statfs's f_fsid, from one set of "Random stuff" to another set of "Random stuff", I don't really mind, but I don't think it's worth *either* a mount option, *or* a feature flag, as either would be confusing for system adminsitrators when some file systems behave one way, and other file systems behave another.

- Ted

#15 lore raw

Re: [PATCH v2 3/3] ext4: derive f_fsid from block device to avoid collisions

Quoted 23 lines · Theodore Tso
Quoted 10 lines · Christoph Hellwig
Quoted 7 lines

Dilemma:
While statfs(2) [1] suggests f_fsid is "some random stuff," we know userspace (NFS, systemd) often treats it as a persistent handle.

Do you prefer one of the names above, or is there a more idiomatic ext4 naming convention I should follow?

My take is that anything that should persist should be an on-disk feature flag, not a mount option. But I'm not in charge for ext4

My take is that f_fsid is random stuff, as documented by the specification, so anyone who tries to depend on it needs to be kept in a padding room where they can't hurt themselves or their users.

And as far as NFS is concerned, file handles should be based on the super block UUID, not statfs's f_fsid, and anyone who wants to mount a snapshot as an NFS exported file system at the same time that the original file system is mounted is _also_ should be gently coaxed into a padding room where they can't hurt themselves or their users.

Quoted 5 lines

The solution that we've used for people who are cloning block devices for things like cloud images has been for *years* has been to use "tune2fs -U random /dev/sda1". And this works on mounted file system, and (for example) built into various cloud images for Google Cloud Engine.

Ted,

Thanks for the feedback.
Some A/B testing use cases require the filesystem to remain byte-for-byte identical. In those scenarios, changing the UUID isn't an option. This was discussed on the mailing list a year or two ago (I don't have the link handy), and is similar to [1].

[1] https://source.android.com/docs/core/ota/ab/ab_implement.

Quoted 5 lines

If we want to change statfs's f_fsid, from one set of "Random stuff" to another set of "Random stuff", I don't really mind, but I don't think it's worth *either* a mount option, *or* a feature flag, as either would be confusing for system adminsitrators when some file systems behave one way, and other file systems behave another.

I agree that a new mount option or flag is too heavy, and I wasn't a fan of that approach either. Let's drop the ext4 patch for now. The f_fsid collision in cloned ext4 filesystems is currently only theoretical; we can revisit this if it becomes necessary.

Thanks, Anand

maintainer
#16 lore raw

Re: [PATCH v2 3/3] ext4: derive f_fsid from block device to avoid collisions

Quoted 3 lines · Anand Jain

Some A/B testing use cases require the filesystem to remain byte-for-byte identical. In those scenarios, changing the UUID isn't an option.

But in that case, where the file systems A and B are bit-fot-bit identical, why do we care whether statfs returns different fsid's for statfs(A) and statfs(B). After all, f_fsid is only defined as "File system ID", and there is no other definition. Which is why I say that people *really* shouldn't depending on its semantics, because it's not well defined.

Quoting from the statfs(2) man page:

Nobody knows what f_fsid is supposed to contain (but see below).

...

The general idea is that f_fsid contains some random stuff such that the pair (f_fsid,ino) uniquely determines a file. Some operating systems use (a variation on) the device number, or the device number combined with the filesystem type. Several operating systems restrict giving out the f_fsid field to the superuser only (and zero it for unprivileged users), because this field is used in the filehandle of the filesystem when NFS-exported, and giving it out is a security concern.

So if the two file systems are identical, the (f_fsid, ino) will uniquely determines a file. And that's *fine* if f_fsid is the same for statfs(A) and statfs(B).

No?

- Ted

#17 lore raw

Re: [PATCH v2 3/3] ext4: derive f_fsid from block device to avoid collisions

Quoted 5 lines

So if the two file systems are identical, the (f_fsid, ino) will uniquely determines a file. And that's *fine* if f_fsid is the same for statfs(A) and statfs(B).

Got it. Do you mean that since both filesystems are identical, statfs(A) and statfs(B) can legitimately return the same values?

And if users want them to diverge, the expectation is that they should update the UUID (via tune2fs), after which f_fsid would also differ. If the UUID isn't changed, then the ambiguity is effectively a user responsibility.

I'm not entirely sure what the correct expectation for f_fsid should be.

My initial idea was to make f_fsid behavior consistent across major filesystems so that user space benefits from predictable semantics.

Currently, XFS and Btrfs provide f_fsid values that are unique per filesystem, including clones, while ext4 provides uniqueness only if the UUID is changed by the user.

That said, it may be fine for ext4 to retain this behavior, since statfs(2) itself has some inherent ambiguity.

If there are no further concerns, I'll update the submitted test case generic/791 accordingly.

Thanks, Anand

maintainer
#18 lore raw

Re: [PATCH v2 3/3] ext4: derive f_fsid from block device to avoid collisions

Quoted 3 lines · Anand Jain

Got it. Do you mean that since both filesystems are identical, statfs(A) and statfs(B) can legitimately return the same values?

Yes. f_Fsid can legitimately always be zero (which I believe is the case for FreeBSD, but I understand that there are some programs, like systemd, which subscribe to the heresy, "All the World's Linux", which is a variant of the "All the World's a Vax" or "All the World's SunOS" at the beginning of my career :-).

Quoted 2 lines

I'm not entirely sure what the correct expectation for f_fsid should be.

That's my point, there *is* no correct expectation, and I don't believe there can or should be. What we should be doing instead is actively discouraging people from using f_fsid. I suspect that's one of the reasons why FreeBSD may have chosen to just return zero.

Which is why I don't think we should be testing this in xfstests's generic/791, either. (Unless we get consensus across file system developers abnd willing to make it be a documented behavior as of a particular kernel version, and we then adjust the test to skip it if it's older than that kernel version, so it doesn't break LTS kernel tests. See below....)

Quoted 3 lines

My initial idea was to make f_fsid behavior consistent across major filesystems so that user space benefits from predictable semantics.

I'm OK with that, so long as it's unconditional across all file system types (ideally) or unconditionally across all major file systems (xfs, btrfs, ext4, f2fs) as of a particular kernel version (which is probably much more realistic), *and* it is documented in the Linux man pages as this is the standard behavior starting with 7.1 (or whatever), and that the man page further cautions that programs that expect to be portable to other OS's (MacOS, FreeBSD, Solaris, etc.) should not count on this behavior.

But given that you originally stumbled across this with Overlayfs, because it was originally using s_uuid, and that didn't work well for btrfs, why not change overlayfs to just use s_uuid plus kdev_t in its xattr, and just fix the problem for overlayfs? That has the benefit that it will work for all file system types in Linux, not just for those where we have changed what f_fsid does.

Cheers,

- Ted

#19 lore raw

Re: [PATCH v2 3/3] ext4: derive f_fsid from block device to avoid collisions

Quoted 19 lines · Theodore Tso
Quoted 3 lines · Anand Jain

Got it. Do you mean that since both filesystems are identical, statfs(A) and statfs(B) can legitimately return the same values?

Yes. f_Fsid can legitimately always be zero (which I believe is the case for FreeBSD, but I understand that there are some programs, like systemd, which subscribe to the heresy, "All the World's Linux", which is a variant of the "All the World's a Vax" or "All the World's SunOS" at the beginning of my career :-).

Quoted 2 lines

I'm not entirely sure what the correct expectation for f_fsid should be.

That's my point, there *is* no correct expectation, and I don't believe there can or should be. What we should be doing instead is actively discouraging people from using f_fsid. I suspect that's one of the reasons why FreeBSD may have chosen to just return zero.

Quoted 7 lines

Which is why I don't think we should be testing this in xfstests's generic/791, either. (Unless we get consensus across file system developers abnd willing to make it be a documented behavior as of a particular kernel version, and we then adjust the test to skip it if it's older than that kernel version, so it doesn't break LTS kernel tests. See below....)

Yes, the idea for generic/79[0-5] was really just to make sure we don't accidentally change s_uuid or f_fsid behavior without realizing it. It gives us a baseline for current and LTS kernels if f_fsid/s_uuid is changed. (Some of the submitted test cases may still need revision).

Quoted 4 lines
Quoted 3 lines

My initial idea was to make f_fsid behavior consistent across major filesystems so that user space benefits from predictable semantics.

Quoted 9 lines

I'm OK with that, so long as it's unconditional across all file system types (ideally) or unconditionally across all major file systems (xfs, btrfs, ext4, f2fs) as of a particular kernel version (which is probably much more realistic), *and* it is documented in the Linux man pages as this is the standard behavior starting with 7.1 (or whatever), and that the man page further cautions that programs that expect to be portable to other OS's (MacOS, FreeBSD, Solaris, etc.) should not count on this behavior.

On second thought, we should perhaps consider a more robust ID, let's call it f_fsid_v2. More on f_fsid_v2 below.

Quoted 6 lines

But given that you originally stumbled across this with Overlayfs, because it was originally using s_uuid, and that didn't work well for btrfs, why not change overlayfs to just use s_uuid plus kdev_t in its xattr, and just fix the problem for overlayfs? That has the benefit that it will work for all file system types in Linux, not just for those where we have changed what f_fsid does.

Using kdev_t (or any derivation of it) for persistent storage, such as Overlayfs xattrs, is problematic. Since kdev_t is transient and inconsistent across reboots or device re-discovery, it could lead to broken associations.

It seems we've reached the functional limits of f_fsid. If we want to solve this properly for Overlayfs, NFS handles, or a complex system monitoring..etc, we need a new identifier let's call it f_fsid_v2, that meets the following requirements:

System-wide Uniqueness: Must distinguish between cloned filesystems.

Persistence: Must remain consistent across reboots/HW re-enumeration.

Non-On-Disk: Must not be stored on-disk.

One possible implementation for f_fsid_v2 could be:

f_fsid_v2 = hash(s_uuid, block_device_serial, [subvol_id])

For pseudo block devices (virtio-blk, loop, nbd, brd,..), the serial could be derived recursively:

serial_number = hash(backing_file.f_fsid_v2, backing_file.ino)

Note on Hardware Serials:
Standard storage protocols (T10, NVMe, SAS) mandate unique, persistent serials per LUN. While I've seen T10 protocol violations during my time authoring Solaris HBA drivers, I believe these outliers shouldn't dictate the design.

This approach provides a system-wide unique ID that is persistent without being stored on-disk. Effectively solving the cloned filesystem identity crisis.

Thoughts ?

Thanks, Anand

#20 lore raw

Re: [PATCH v2 3/3] ext4: derive f_fsid from block device to avoid collisions

Quoted 11 lines · Anand Jain
Quoted 6 lines

But given that you originally stumbled across this with Overlayfs, because it was originally using s_uuid, and that didn't work well for btrfs, why not change overlayfs to just use s_uuid plus kdev_t in its xattr, and just fix the problem for overlayfs? That has the benefit that it will work for all file system types in Linux, not just for those where we have changed what f_fsid does.

Using kdev_t (or any derivation of it) for persistent storage, such as Overlayfs xattrs, is problematic. Since kdev_t is transient and inconsistent across reboots or device re-discovery, it could lead to broken associations.

Yes, using a dev_t in anything persistent is a really bad ida.

Quoted 10 lines

It seems we've reached the functional limits of f_fsid. If we want to solve this properly for Overlayfs, NFS handles, or a complex system monitoring..etc, we need a new identifier let's call it f_fsid_v2, that meets the following requirements:

System-wide Uniqueness: Must distinguish between cloned filesystems.

Persistence: Must remain consistent across reboots/HW re-enumeration.

Non-On-Disk: Must not be stored on-disk.

The third requirement doesn't make much sense to me. If it is persistent it. or something it can be derived from must be stored on-disk.

Quoted 10 lines

One possible implementation for f_fsid_v2 could be:

f_fsid_v2 = hash(s_uuid, block_device_serial, [subvol_id])

For pseudo block devices (virtio-blk, loop, nbd, brd,..), the serial could be derived recursively:

serial_number = hash(backing_file.f_fsid_v2, backing_file.ino)

What i the point in this? All of this seems to be better served by s_uuid.

Quoted 5 lines

Note on Hardware Serials:
Standard storage protocols (T10, NVMe, SAS) mandate unique, persistent serials per LUN. While I've seen T10 protocol violations during my time authoring Solaris HBA drivers, I believe these outliers shouldn't dictate the design.

No, T10 does not actually mandate unique identifiers, NVMe does, but the implementations are often totally broken.

#21 lore raw

Re: [PATCH v2 3/3] ext4: derive f_fsid from block device to avoid collisions

Quoted 10 lines
Quoted 10 lines

It seems we've reached the functional limits of f_fsid. If we want to solve this properly for Overlayfs, NFS handles, or a complex system monitoring..etc, we need a new identifier let's call it f_fsid_v2, that meets the following requirements:

System-wide Uniqueness: Must distinguish between cloned filesystems.

Persistence: Must remain consistent across reboots/HW re-enumeration.

My mistake- this should be:

Consistency: Must remain consistent across reboots/HW re-enumeration.

Quoted 6 lines
Quoted 2 lines

Non-On-Disk: Must not be stored on-disk.

The third requirement doesn't make much sense to me. If it is persistent it. or something it can be derived from must be stored on-disk.

I hope it make sense now with "Persistence" replaced by "Consistency" for the 2nd requirement (above).

Quoted 11 lines
Quoted 8 lines

One possible implementation for f_fsid_v2 could be:

f_fsid_v2 = hash(s_uuid, block_device_serial, [subvol_id])

For pseudo block devices (virtio-blk, loop, nbd, brd,..), the serial could be derived recursively:

serial_number = hash(backing_file.f_fsid_v2, backing_file.ino)

What i the point in this? All of this seems to be better served by s_uuid.

The goal is to fix duplicate f_fsid issues in cloned filesystems by creating a unique, reboot-consistent ID. This allows the source and clone to remain identical (sharing same uuid) while still being individually identifiable.

Quoted 8 lines
Quoted 5 lines

Note on Hardware Serials:
Standard storage protocols (T10, NVMe, SAS) mandate unique, persistent serials per LUN. While I've seen T10 protocol violations during my time authoring Solaris HBA drivers, I believe these outliers shouldn't dictate the design.

No, T10 does not actually mandate unique identifiers, NVMe does, but the implementations are often totally broken.

Right. Newer SPC-3 (and above) compliant devices must support the Inquiry CDB EVPD flag and provide page 0x83 for identification, which is what we typically use for multipathing.
These are globally unique. And, we can overlook legacy drives, as they've probably been past their EOSL for a while now.

We can tweak the algorithm as follows:

ID = hash(s_uuid, device_identifier_id,

            partition_start_lba, partition_end_lba,
            [subvol_id], [file.ino])

This is an ID which remains consistent across reboots while staying unique within the system, which we can use it for f_fsid.

Thanks.

#22 lore raw

Re: [PATCH v2 3/3] ext4: derive f_fsid from block device to avoid collisions

Quoted 6 lines · Anand Jain
Quoted 2 lines

No, T10 does not actually mandate unique identifiers, NVMe does, but the implementations are often totally broken.

Right. Newer SPC-3 (and above) compliant devices must support the Inquiry CDB EVPD flag and provide page 0x83 for identification, which is what we typically use for multipathing.

But there is no requirement for it to contain something useful.

Quoted 2 lines

These are globally unique. And, we can overlook legacy drives, as they've probably been past their EOSL for a while now.

We have absolutely no useful identifiers for most USB devices. NVMe devices have broken identifiers all the time as well.

So no, you can't.

#23 lore raw

Re: [PATCH v2 3/3] ext4: derive f_fsid from block device to avoid collisions

Quoted 10 lines · Christoph Hellwig
Quoted 6 lines · Anand Jain
Quoted 2 lines

No, T10 does not actually mandate unique identifiers, NVMe does, but the implementations are often totally broken.

Right. Newer SPC-3 (and above) compliant devices must support the Inquiry CDB EVPD flag and provide page 0x83 for identification, which is what we typically use for multipathing.

But there is no requirement for it to contain something useful.

Quoted 7 lines
Quoted 2 lines

These are globally unique. And, we can overlook legacy drives, as they've probably been past their EOSL for a while now.

We have absolutely no useful identifiers for most USB devices. NVMe devices have broken identifiers all the time as well.

So no, you can't.

Agreed. I have dropped the plan to rely on hardware identifiers; the lack of consistency in USB/NVMe firmware makes them a non-starter for a stable identifier.

The updated patch set, excluding the ext4 changes, has been submitted to the mailing list. Fstests test case updated as well.

Thanks, Anand