diff mbox series

[WIP] populate superblock uuid at mount time

Message ID CAH2r5muYgYr=kxSkzCmNQLaF0br_QZ2s=BLPd_TnOnPmTUz_WQ@mail.gmail.com
State New
Headers show
Series [WIP] populate superblock uuid at mount time | expand

Commit Message

Steve French March 29, 2024, 6:30 a.m. UTC
In order to get the unique id for the volume (the 8 byte
VolumeSerialNumber) we need to issue a QUERY_INFO level 59
(FILE_ID_INFORMATION).  Today we only query the older 4 byte (not
guaranteed to be unique serial number).   See section 2.4.21 of
MS-FSCC.  Looks like Samba and ksmbd do not support this info level
though - although Windows does support it.

Any thoughts on ksmbd or Samba support for FILE_ID_INFORMATION query?

See attached work in progress patch

Comments

Jeremy Allison March 29, 2024, 10:07 p.m. UTC | #1
On Fri, Mar 29, 2024 at 01:30:42AM -0500, Steve French wrote:
>In order to get the unique id for the volume (the 8 byte
>VolumeSerialNumber) we need to issue a QUERY_INFO level 59
>(FILE_ID_INFORMATION).  Today we only query the older 4 byte (not
>guaranteed to be unique serial number).   See section 2.4.21 of
>MS-FSCC.  Looks like Samba and ksmbd do not support this info level
>though - although Windows does support it.
>
>Any thoughts on ksmbd or Samba support for FILE_ID_INFORMATION query?
>
>See attached work in progress patch

2.4.21 wants a 64-bit volume ID, and a 128-bit file id.

How do you want this synthesized from a 64-bit inode ?

Can we get a standard mapping for this ?
diff mbox series

Patch

From a5f90b46b17d20af4cdbfae6ac43dabc1e58e87e Mon Sep 17 00:00:00 2001
From: Steve French <stfrench@microsoft.com>
Date: Fri, 29 Mar 2024 00:30:49 -0500
Subject: [PATCH] smb3: update sb uuid when full id information available

Some servers like Windows and Azure report the larger (16 byte)
unique volume serial number.  For those that return full_id_information
populate the sb->s_uuid

This will also allow the new ioctl FS_IOC_GETFSUUID to work

Signed-off-by: Steve French <stfrench@microsoft.com>
---
 fs/smb/client/cifsfs.c    |  2 ++
 fs/smb/client/cifsglob.h  |  1 +
 fs/smb/client/smb2ops.c   |  2 ++
 fs/smb/client/smb2pdu.c   | 18 ++++++++++++++++++
 fs/smb/client/smb2proto.h |  2 ++
 5 files changed, 25 insertions(+)

diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c
index aa6f1ecb7c0e..c6445f93d954 100644
--- a/fs/smb/client/cifsfs.c
+++ b/fs/smb/client/cifsfs.c
@@ -269,6 +269,8 @@  cifs_read_super(struct super_block *sb)
 		goto out_no_root;
 	}
 
+	if (tcon->vol_uuid != 0)
+		super_set_uuid(sb, (void *)&tcon->vol_uuid, sizeof(tcon->vol_uuid));
 #ifdef CONFIG_CIFS_NFSD_EXPORT
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
 		cifs_dbg(FYI, "export ops supported\n");
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
index 7ed9d05f6890..dae11166eb6f 100644
--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -1264,6 +1264,7 @@  struct cifs_tcon {
 	__u32 share_flags;
 	__u32 maximal_access;
 	__u32 vol_serial_number;
+	__u64 vol_uuid; /* full (64 bit, unique) serial number */
 	__le64 vol_create_time;
 	__u64 snapshot_time; /* for timewarp tokens - timestamp of snapshot */
 	__u32 handle_timeout; /* persistent and durable handle timeout in ms */
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 2ed456948f34..84d2f3f1c89a 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -831,6 +831,8 @@  smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
 	if (rc)
 		return;
 
+	SMB2_get_vol_serial_num(xid, tcon, fid.persistent_fid, fid.volatile_fid);
+
 	SMB3_request_interfaces(xid, tcon, true /* called during  mount */);
 
 	SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index 3ea688558e6c..f262b8251b2e 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -3908,6 +3908,24 @@  SMB2_query_acl(const unsigned int xid, struct cifs_tcon *tcon,
 			  SMB2_MAX_BUFFER_SIZE, MIN_SEC_DESC_LEN, data, plen);
 }
 
+int
+SMB2_get_vol_serial_num(const unsigned int xid, struct cifs_tcon *tcon,
+			u64 persistent_fid, u64 volatile_fid)
+{
+	int rc;
+	struct smb2_file_id_information vol_info;
+
+	rc = query_info(xid, tcon, persistent_fid, volatile_fid,
+			  FILE_ID_INFORMATION, SMB2_O_INFO_FILE, 0,
+			  sizeof(struct smb2_file_id_information),
+			  sizeof(struct smb2_file_id_information),
+			  (void **)&vol_info, NULL);
+	if (!rc)
+		tcon->vol_uuid = le64_to_cpu(vol_info.VolumeSerialNumber);
+
+	return rc;
+}
+
 int
 SMB2_get_srv_num(const unsigned int xid, struct cifs_tcon *tcon,
 		 u64 persistent_fid, u64 volatile_fid, __le64 *uniqueid)
diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h
index 732169d8a67a..b518f1fdedcf 100644
--- a/fs/smb/client/smb2proto.h
+++ b/fs/smb/client/smb2proto.h
@@ -207,6 +207,8 @@  extern void SMB2_query_info_free(struct smb_rqst *rqst);
 extern int SMB2_query_acl(const unsigned int xid, struct cifs_tcon *tcon,
 			  u64 persistent_file_id, u64 volatile_file_id,
 			  void **data, unsigned int *plen, u32 info);
+extern int SMB2_get_vol_serial_num(const unsigned int xid, struct cifs_tcon *tcon,
+			    u64 persistent_fid, u64 volatile_fid);
 extern int SMB2_get_srv_num(const unsigned int xid, struct cifs_tcon *tcon,
 			    u64 persistent_fid, u64 volatile_fid,
 			    __le64 *uniqueid);
-- 
2.40.1