summaryrefslogtreecommitdiff
path: root/usr/src/uts
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts')
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb2_qinfo_file.c52
-rw-r--r--usr/src/uts/common/smbsrv/ntifs.h6
2 files changed, 58 insertions, 0 deletions
diff --git a/usr/src/uts/common/fs/smbsrv/smb2_qinfo_file.c b/usr/src/uts/common/fs/smbsrv/smb2_qinfo_file.c
index 00198aa31f..1683904e33 100644
--- a/usr/src/uts/common/fs/smbsrv/smb2_qinfo_file.c
+++ b/usr/src/uts/common/fs/smbsrv/smb2_qinfo_file.c
@@ -45,6 +45,7 @@ static uint32_t smb2_qif_pipe_rem(smb_request_t *, smb_queryinfo_t *);
static uint32_t smb2_qif_compr(smb_request_t *, smb_queryinfo_t *);
static uint32_t smb2_qif_opens(smb_request_t *, smb_queryinfo_t *);
static uint32_t smb2_qif_tags(smb_request_t *, smb_queryinfo_t *);
+static uint32_t smb2_qif_id_info(smb_request_t *, smb_queryinfo_t *);
uint32_t
@@ -99,6 +100,11 @@ smb2_qinfo_file(smb_request_t *sr, smb_queryinfo_t *qi)
case FileNetworkOpenInformation:
mask = SMB_AT_BASIC | SMB_AT_STANDARD;
+ break;
+
+ case FileIdInformation:
+ mask = SMB_AT_NODEID;
+ break;
default:
break;
@@ -180,6 +186,9 @@ smb2_qinfo_file(smb_request_t *sr, smb_queryinfo_t *qi)
case FileAttributeTagInformation:
status = smb2_qif_tags(sr, qi);
break;
+ case FileIdInformation:
+ status = smb2_qif_id_info(sr, qi);
+ break;
default:
status = NT_STATUS_INVALID_INFO_CLASS;
break;
@@ -645,3 +654,46 @@ smb2_qif_tags(smb_request_t *sr, smb_queryinfo_t *qi)
return (0);
}
+
+/*
+ * FileIdInformation
+ *
+ * Returns a A FILE_ID_INFORMATION
+ * VolumeSerialNumber (8 bytes)
+ * FileId (16 bytes)
+ *
+ * Take the volume serial from the share root,
+ * and compose the FileId from the nodeid and fsid
+ * of the file (in case we crossed mounts)
+ */
+static uint32_t
+smb2_qif_id_info(smb_request_t *sr, smb_queryinfo_t *qi)
+{
+ smb_attr_t *sa = &qi->qi_attr;
+ smb_ofile_t *of = sr->fid_ofile;
+ smb_tree_t *tree = sr->tid_tree;
+ vfs_t *f_vfs; // file
+ vfs_t *s_vfs; // share
+ uint64_t nodeid;
+ int rc;
+
+ ASSERT((sa->sa_mask & SMB_AT_NODEID) != 0);
+ if (of->f_ftype != SMB_FTYPE_DISK)
+ return (NT_STATUS_INVALID_INFO_CLASS);
+
+ s_vfs = SMB_NODE_VFS(tree->t_snode);
+ f_vfs = SMB_NODE_VFS(of->f_node);
+ nodeid = (uint64_t)sa->sa_vattr.va_nodeid;
+
+ rc = smb_mbc_encodef(
+ &sr->raw_data, "llqll",
+ s_vfs->vfs_fsid.val[0], /* l */
+ s_vfs->vfs_fsid.val[1], /* l */
+ nodeid, /* q */
+ f_vfs->vfs_fsid.val[0], /* l */
+ f_vfs->vfs_fsid.val[1]); /* l */
+ if (rc != 0)
+ return (NT_STATUS_INFO_LENGTH_MISMATCH);
+
+ return (0);
+}
diff --git a/usr/src/uts/common/smbsrv/ntifs.h b/usr/src/uts/common/smbsrv/ntifs.h
index 7c1d837c08..6057cd95c6 100644
--- a/usr/src/uts/common/smbsrv/ntifs.h
+++ b/usr/src/uts/common/smbsrv/ntifs.h
@@ -24,6 +24,7 @@
*
* Copyright 2017 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2016 by Delphix. All rights reserved.
+ * Copyright 2022 RackTop Systems, Inc.
*/
#ifndef _SMBSRV_NTIFS_H
@@ -274,6 +275,11 @@ typedef enum _FILE_INFORMATION_CLASS {
FileInformationReserved52, /* 52 */
FileInformationReserved53, /* 53 */
FileStandardLinkInformation, /* 54 */
+ FileInformationReserved55, /* 55 */
+ FileInformationReserved56, /* 56 */
+ FileInformationReserved57, /* 57 */
+ FileInformationReserved58, /* 58 */
+ FileIdInformation, /* 59 */
FileMaximumInformation
} FILE_INFORMATION_CLASS;