xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb2_qinfo_fs.c (revision 25a9a7aaf35c7e4a2b5a57d3875af906147710d5)
1a90cf9f2SGordon Ross /*
2a90cf9f2SGordon Ross  * CDDL HEADER START
3a90cf9f2SGordon Ross  *
4a90cf9f2SGordon Ross  * The contents of this file are subject to the terms of the
5a90cf9f2SGordon Ross  * Common Development and Distribution License (the "License").
6a90cf9f2SGordon Ross  * You may not use this file except in compliance with the License.
7a90cf9f2SGordon Ross  *
8a90cf9f2SGordon Ross  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9a90cf9f2SGordon Ross  * or http://www.opensolaris.org/os/licensing.
10a90cf9f2SGordon Ross  * See the License for the specific language governing permissions
11a90cf9f2SGordon Ross  * and limitations under the License.
12a90cf9f2SGordon Ross  *
13a90cf9f2SGordon Ross  * When distributing Covered Code, include this CDDL HEADER in each
14a90cf9f2SGordon Ross  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15a90cf9f2SGordon Ross  * If applicable, add the following below this CDDL HEADER, with the
16a90cf9f2SGordon Ross  * fields enclosed by brackets "[]" replaced with your own identifying
17a90cf9f2SGordon Ross  * information: Portions Copyright [yyyy] [name of copyright owner]
18a90cf9f2SGordon Ross  *
19a90cf9f2SGordon Ross  * CDDL HEADER END
20a90cf9f2SGordon Ross  */
21a90cf9f2SGordon Ross /*
22a90cf9f2SGordon Ross  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23*25a9a7aaSGordon Ross  * Copyright 2019 Nexenta by DDN, Inc. All rights reserved.
24a90cf9f2SGordon Ross  */
25a90cf9f2SGordon Ross 
26a90cf9f2SGordon Ross /*
27a90cf9f2SGordon Ross  * Dispatch function for SMB2_QUERY_INFO
28a90cf9f2SGordon Ross  *
29a90cf9f2SGordon Ross  * [MS-FSCC 2.5] If a file system does not implement ...
30a90cf9f2SGordon Ross  * an Information Classs, NT_STATUS_INVALID_PARAMETER...
31a90cf9f2SGordon Ross  */
32a90cf9f2SGordon Ross 
33a90cf9f2SGordon Ross #include <smbsrv/smb2_kproto.h>
34a90cf9f2SGordon Ross #include <smbsrv/smb_fsops.h>
35a90cf9f2SGordon Ross #include <smbsrv/ntifs.h>
36a90cf9f2SGordon Ross 
37a90cf9f2SGordon Ross uint32_t smb2_qfs_volume(smb_request_t *);
38a90cf9f2SGordon Ross uint32_t smb2_qfs_size(smb_request_t *);
39a90cf9f2SGordon Ross uint32_t smb2_qfs_device(smb_request_t *);
40a90cf9f2SGordon Ross uint32_t smb2_qfs_attr(smb_request_t *);
41a90cf9f2SGordon Ross uint32_t smb2_qfs_control(smb_request_t *);
42a90cf9f2SGordon Ross uint32_t smb2_qfs_fullsize(smb_request_t *);
43a90cf9f2SGordon Ross uint32_t smb2_qfs_obj_id(smb_request_t *);
44252bc4b2SGordon Ross uint32_t smb2_qfs_sectorsize(smb_request_t *);
45a90cf9f2SGordon Ross 
46a90cf9f2SGordon Ross uint32_t
smb2_qinfo_fs(smb_request_t * sr,smb_queryinfo_t * qi)47a90cf9f2SGordon Ross smb2_qinfo_fs(smb_request_t *sr, smb_queryinfo_t *qi)
48a90cf9f2SGordon Ross {
49a90cf9f2SGordon Ross 	uint32_t status;
50a90cf9f2SGordon Ross 
51a90cf9f2SGordon Ross 	switch (qi->qi_InfoClass) {
52a90cf9f2SGordon Ross 
53a90cf9f2SGordon Ross 	/* pg 153 */
54a90cf9f2SGordon Ross 	case FileFsVolumeInformation:	/* 1 */
55a90cf9f2SGordon Ross 		status = smb2_qfs_volume(sr);
56a90cf9f2SGordon Ross 		break;
57a90cf9f2SGordon Ross 	case FileFsSizeInformation:	/* 3 */
58a90cf9f2SGordon Ross 		status = smb2_qfs_size(sr);
59a90cf9f2SGordon Ross 		break;
60a90cf9f2SGordon Ross 	case FileFsDeviceInformation:	/* 4 */
61a90cf9f2SGordon Ross 		status = smb2_qfs_device(sr);
62a90cf9f2SGordon Ross 		break;
63a90cf9f2SGordon Ross 	case FileFsAttributeInformation: /* 5 */
64a90cf9f2SGordon Ross 		status = smb2_qfs_attr(sr);
65a90cf9f2SGordon Ross 		break;
66a90cf9f2SGordon Ross 	case FileFsControlInformation:	/* 6 */
67a90cf9f2SGordon Ross 		status = smb2_qfs_control(sr);
68a90cf9f2SGordon Ross 		break;
69a90cf9f2SGordon Ross 	case FileFsFullSizeInformation:	/* 7 */
70a90cf9f2SGordon Ross 		status = smb2_qfs_fullsize(sr);
71a90cf9f2SGordon Ross 		break;
72a90cf9f2SGordon Ross 	case FileFsObjectIdInformation:	/* 8 */
73a90cf9f2SGordon Ross 		status = smb2_qfs_obj_id(sr);
74a90cf9f2SGordon Ross 		break;
75252bc4b2SGordon Ross 	case FileFsDriverPathInformation:	/* 9 */
76252bc4b2SGordon Ross 	case FileFsVolumeFlagsInformation:	/* A */
77a90cf9f2SGordon Ross 		status = NT_STATUS_INVALID_INFO_CLASS;
78a90cf9f2SGordon Ross 		break;
79252bc4b2SGordon Ross 	case FileFsSectorSizeInformation:	/* B */
80252bc4b2SGordon Ross 		status = smb2_qfs_sectorsize(sr);
81252bc4b2SGordon Ross 		break;
82252bc4b2SGordon Ross 	default: /* there are some infoclasses we don't yet handle */
83252bc4b2SGordon Ross 		status = NT_STATUS_INVALID_INFO_CLASS;
84252bc4b2SGordon Ross #ifdef	DEBUG
85252bc4b2SGordon Ross 		cmn_err(CE_NOTE, "unknown InfoClass 0x%x", qi->qi_InfoClass);
86252bc4b2SGordon Ross #endif
87252bc4b2SGordon Ross 		break;
88a90cf9f2SGordon Ross 	}
89a90cf9f2SGordon Ross 
90a90cf9f2SGordon Ross 	return (status);
91a90cf9f2SGordon Ross }
92a90cf9f2SGordon Ross 
93a90cf9f2SGordon Ross /*
94a90cf9f2SGordon Ross  * FileFsVolumeInformation
95a90cf9f2SGordon Ross  */
96a90cf9f2SGordon Ross uint32_t
smb2_qfs_volume(smb_request_t * sr)97a90cf9f2SGordon Ross smb2_qfs_volume(smb_request_t *sr)
98a90cf9f2SGordon Ross {
99a90cf9f2SGordon Ross 	smb_tree_t *tree = sr->tid_tree;
100a90cf9f2SGordon Ross 	smb_node_t *snode;
101a90cf9f2SGordon Ross 	fsid_t fsid;
102a90cf9f2SGordon Ross 	uint32_t LabelLength;
103*25a9a7aaSGordon Ross 	int rc;
104a90cf9f2SGordon Ross 
105a90cf9f2SGordon Ross 	if (!STYPE_ISDSK(tree->t_res_type))
106a90cf9f2SGordon Ross 		return (NT_STATUS_INVALID_PARAMETER);
107a90cf9f2SGordon Ross 
108a90cf9f2SGordon Ross 	snode = tree->t_snode;
109a90cf9f2SGordon Ross 	fsid = SMB_NODE_FSID(snode);
110a90cf9f2SGordon Ross 
111a90cf9f2SGordon Ross 	LabelLength = smb_wcequiv_strlen(tree->t_volume);
112a90cf9f2SGordon Ross 
113a90cf9f2SGordon Ross 	/*
114a90cf9f2SGordon Ross 	 * NT has the "supports objects" flag set to 1.
115a90cf9f2SGordon Ross 	 */
116*25a9a7aaSGordon Ross 	rc = smb_mbc_encodef(
117*25a9a7aaSGordon Ross 	    &sr->raw_data, "Tllb.U",
118*25a9a7aaSGordon Ross 	    &tree->t_create_time,	/*	(T) */
119a90cf9f2SGordon Ross 	    fsid.val[0],	/* serial no.   (l) */
120a90cf9f2SGordon Ross 	    LabelLength,		/*	(l) */
121a90cf9f2SGordon Ross 	    0,		/* Supports objects	(b) */
122a90cf9f2SGordon Ross 	    /* reserved				(.) */
123a90cf9f2SGordon Ross 	    tree->t_volume);		/*	(U) */
124*25a9a7aaSGordon Ross 	if (rc != 0)
125*25a9a7aaSGordon Ross 		return (NT_STATUS_BUFFER_OVERFLOW);
126a90cf9f2SGordon Ross 
127a90cf9f2SGordon Ross 	return (0);
128a90cf9f2SGordon Ross }
129a90cf9f2SGordon Ross 
130a90cf9f2SGordon Ross /*
131a90cf9f2SGordon Ross  * FileFsSizeInformation
132a90cf9f2SGordon Ross  */
133a90cf9f2SGordon Ross uint32_t
smb2_qfs_size(smb_request_t * sr)134a90cf9f2SGordon Ross smb2_qfs_size(smb_request_t *sr)
135a90cf9f2SGordon Ross {
136a90cf9f2SGordon Ross 	smb_fssize_t		fssize;
137a90cf9f2SGordon Ross 	smb_tree_t *tree = sr->tid_tree;
138a90cf9f2SGordon Ross 	int rc;
139a90cf9f2SGordon Ross 
140a90cf9f2SGordon Ross 	if (!STYPE_ISDSK(tree->t_res_type))
141a90cf9f2SGordon Ross 		return (NT_STATUS_INVALID_PARAMETER);
142a90cf9f2SGordon Ross 
143a90cf9f2SGordon Ross 	rc = smb_fssize(sr, &fssize);
144a90cf9f2SGordon Ross 	if (rc)
145a90cf9f2SGordon Ross 		return (smb_errno2status(rc));
146a90cf9f2SGordon Ross 
147*25a9a7aaSGordon Ross 	rc = smb_mbc_encodef(
148a90cf9f2SGordon Ross 	    &sr->raw_data, "qqll",
149a90cf9f2SGordon Ross 	    fssize.fs_caller_units,
150a90cf9f2SGordon Ross 	    fssize.fs_caller_avail,
151a90cf9f2SGordon Ross 	    fssize.fs_sectors_per_unit,
152a90cf9f2SGordon Ross 	    fssize.fs_bytes_per_sector);
153*25a9a7aaSGordon Ross 	if (rc != 0)
154*25a9a7aaSGordon Ross 		return (NT_STATUS_BUFFER_OVERFLOW);
155a90cf9f2SGordon Ross 
156a90cf9f2SGordon Ross 	return (0);
157a90cf9f2SGordon Ross }
158a90cf9f2SGordon Ross 
159a90cf9f2SGordon Ross /*
160a90cf9f2SGordon Ross  * FileFsFullSizeInformation
161a90cf9f2SGordon Ross  */
162a90cf9f2SGordon Ross uint32_t
smb2_qfs_fullsize(smb_request_t * sr)163a90cf9f2SGordon Ross smb2_qfs_fullsize(smb_request_t *sr)
164a90cf9f2SGordon Ross {
165a90cf9f2SGordon Ross 	smb_fssize_t		fssize;
166a90cf9f2SGordon Ross 	smb_tree_t *tree = sr->tid_tree;
167a90cf9f2SGordon Ross 	int rc;
168a90cf9f2SGordon Ross 
169a90cf9f2SGordon Ross 	if (!STYPE_ISDSK(tree->t_res_type))
170a90cf9f2SGordon Ross 		return (NT_STATUS_INVALID_PARAMETER);
171a90cf9f2SGordon Ross 
172a90cf9f2SGordon Ross 	rc = smb_fssize(sr, &fssize);
173a90cf9f2SGordon Ross 	if (rc)
174a90cf9f2SGordon Ross 		return (smb_errno2status(rc));
175a90cf9f2SGordon Ross 
176*25a9a7aaSGordon Ross 	rc = smb_mbc_encodef(
177a90cf9f2SGordon Ross 	    &sr->raw_data, "qqqll",
178a90cf9f2SGordon Ross 	    fssize.fs_caller_units,
179a90cf9f2SGordon Ross 	    fssize.fs_caller_avail,
180a90cf9f2SGordon Ross 	    fssize.fs_volume_avail,
181a90cf9f2SGordon Ross 	    fssize.fs_sectors_per_unit,
182a90cf9f2SGordon Ross 	    fssize.fs_bytes_per_sector);
183*25a9a7aaSGordon Ross 	if (rc != 0)
184*25a9a7aaSGordon Ross 		return (NT_STATUS_BUFFER_OVERFLOW);
185a90cf9f2SGordon Ross 
186a90cf9f2SGordon Ross 	return (0);
187a90cf9f2SGordon Ross }
188a90cf9f2SGordon Ross 
189a90cf9f2SGordon Ross /*
190a90cf9f2SGordon Ross  * FileFsDeviceInformation
191a90cf9f2SGordon Ross  */
192a90cf9f2SGordon Ross uint32_t
smb2_qfs_device(smb_request_t * sr)193a90cf9f2SGordon Ross smb2_qfs_device(smb_request_t *sr)
194a90cf9f2SGordon Ross {
195a90cf9f2SGordon Ross 	smb_tree_t *tree = sr->tid_tree;
196a90cf9f2SGordon Ross 	uint32_t DeviceType;
197a90cf9f2SGordon Ross 	uint32_t Characteristics;
198*25a9a7aaSGordon Ross 	int rc;
199a90cf9f2SGordon Ross 
200a90cf9f2SGordon Ross 	if (!STYPE_ISDSK(tree->t_res_type))
201a90cf9f2SGordon Ross 		return (NT_STATUS_INVALID_PARAMETER);
202a90cf9f2SGordon Ross 
203a90cf9f2SGordon Ross 	DeviceType = FILE_DEVICE_DISK;
204a90cf9f2SGordon Ross 	Characteristics = FILE_DEVICE_IS_MOUNTED;
205a90cf9f2SGordon Ross 
206*25a9a7aaSGordon Ross 	rc = smb_mbc_encodef(
207a90cf9f2SGordon Ross 	    &sr->raw_data, "ll",
208a90cf9f2SGordon Ross 	    DeviceType,
209a90cf9f2SGordon Ross 	    Characteristics);
210*25a9a7aaSGordon Ross 	if (rc != 0)
211*25a9a7aaSGordon Ross 		return (NT_STATUS_BUFFER_OVERFLOW);
212a90cf9f2SGordon Ross 
213a90cf9f2SGordon Ross 	return (0);
214a90cf9f2SGordon Ross }
215a90cf9f2SGordon Ross 
216a90cf9f2SGordon Ross /*
217a90cf9f2SGordon Ross  * FileFsAttributeInformation
218a90cf9f2SGordon Ross  */
219a90cf9f2SGordon Ross uint32_t
smb2_qfs_attr(smb_request_t * sr)220a90cf9f2SGordon Ross smb2_qfs_attr(smb_request_t *sr)
221a90cf9f2SGordon Ross {
222a90cf9f2SGordon Ross 	smb_tree_t *tree = sr->tid_tree;
223a90cf9f2SGordon Ross 	char *fsname;
224a90cf9f2SGordon Ross 	uint32_t namelen;
225a90cf9f2SGordon Ross 	uint32_t FsAttr;
226*25a9a7aaSGordon Ross 	int rc;
227a90cf9f2SGordon Ross 
228a90cf9f2SGordon Ross 	/* This call is OK on all tree types. */
229a90cf9f2SGordon Ross 	switch (tree->t_res_type & STYPE_MASK) {
230a90cf9f2SGordon Ross 	case STYPE_IPC:
231a90cf9f2SGordon Ross 		fsname = "PIPE";
232a90cf9f2SGordon Ross 		break;
233a90cf9f2SGordon Ross 	case STYPE_DISKTREE:
234a90cf9f2SGordon Ross 		fsname = "NTFS"; /* A lie, but compatible... */
235a90cf9f2SGordon Ross 		break;
236a90cf9f2SGordon Ross 	case STYPE_PRINTQ:
237a90cf9f2SGordon Ross 	case STYPE_DEVICE:
238a90cf9f2SGordon Ross 	default: /* gcc -Wuninitialized */
239a90cf9f2SGordon Ross 		return (NT_STATUS_INVALID_PARAMETER);
240a90cf9f2SGordon Ross 	}
241a90cf9f2SGordon Ross 	namelen = smb_wcequiv_strlen(fsname);
242a90cf9f2SGordon Ross 
243a90cf9f2SGordon Ross 	/*
244a90cf9f2SGordon Ross 	 * Todo: Store the FsAttributes in the tree object,
245a90cf9f2SGordon Ross 	 * then just return that directly here.
246a90cf9f2SGordon Ross 	 */
247a90cf9f2SGordon Ross 	FsAttr = FILE_CASE_PRESERVED_NAMES;
248a90cf9f2SGordon Ross 	if (tree->t_flags & SMB_TREE_UNICODE_ON_DISK)
249a90cf9f2SGordon Ross 		FsAttr |= FILE_UNICODE_ON_DISK;
250a90cf9f2SGordon Ross 	if (tree->t_flags & SMB_TREE_SUPPORTS_ACLS)
251a90cf9f2SGordon Ross 		FsAttr |= FILE_PERSISTENT_ACLS;
252a90cf9f2SGordon Ross 	if ((tree->t_flags & SMB_TREE_CASEINSENSITIVE) == 0)
253a90cf9f2SGordon Ross 		FsAttr |= FILE_CASE_SENSITIVE_SEARCH;
254a90cf9f2SGordon Ross 	if (tree->t_flags & SMB_TREE_STREAMS)
255a90cf9f2SGordon Ross 		FsAttr |= FILE_NAMED_STREAMS;
256a90cf9f2SGordon Ross 	if (tree->t_flags & SMB_TREE_QUOTA)
257a90cf9f2SGordon Ross 		FsAttr |= FILE_VOLUME_QUOTAS;
258a90cf9f2SGordon Ross 	if (tree->t_flags & SMB_TREE_SPARSE)
259a90cf9f2SGordon Ross 		FsAttr |= FILE_SUPPORTS_SPARSE_FILES;
260a90cf9f2SGordon Ross 
261*25a9a7aaSGordon Ross 	rc = smb_mbc_encodef(
262a90cf9f2SGordon Ross 	    &sr->raw_data, "lllU",
263a90cf9f2SGordon Ross 	    FsAttr,
264a90cf9f2SGordon Ross 	    MAXNAMELEN-1,
265a90cf9f2SGordon Ross 	    namelen,
266a90cf9f2SGordon Ross 	    fsname);
267*25a9a7aaSGordon Ross 	if (rc != 0)
268*25a9a7aaSGordon Ross 		return (NT_STATUS_BUFFER_OVERFLOW);
269a90cf9f2SGordon Ross 
270a90cf9f2SGordon Ross 	return (0);
271a90cf9f2SGordon Ross }
272a90cf9f2SGordon Ross 
273a90cf9f2SGordon Ross /*
274a90cf9f2SGordon Ross  * FileFsControlInformation
275a90cf9f2SGordon Ross  */
276a90cf9f2SGordon Ross uint32_t
smb2_qfs_control(smb_request_t * sr)277a90cf9f2SGordon Ross smb2_qfs_control(smb_request_t *sr)
278a90cf9f2SGordon Ross {
279a90cf9f2SGordon Ross 	smb_tree_t *tree = sr->tid_tree;
280*25a9a7aaSGordon Ross 	int rc;
281a90cf9f2SGordon Ross 
282a90cf9f2SGordon Ross 	if (!STYPE_ISDSK(tree->t_res_type))
283a90cf9f2SGordon Ross 		return (NT_STATUS_INVALID_PARAMETER);
284a90cf9f2SGordon Ross 	if (!smb_tree_has_feature(sr->tid_tree, SMB_TREE_QUOTA)) {
285a90cf9f2SGordon Ross 		/*
286a90cf9f2SGordon Ross 		 * Strange error per. [MS-FSCC 2.5.2]
287a90cf9f2SGordon Ross 		 * which means quotas not supported.
288a90cf9f2SGordon Ross 		 */
289a90cf9f2SGordon Ross 		return (NT_STATUS_VOLUME_NOT_UPGRADED);
290a90cf9f2SGordon Ross 	}
291a90cf9f2SGordon Ross 
292*25a9a7aaSGordon Ross 	rc = smb_mbc_encodef(
293a90cf9f2SGordon Ross 	    &sr->raw_data, "qqqqqll",
294a90cf9f2SGordon Ross 	    0,		/* free space start filtering - MUST be 0 */
295a90cf9f2SGordon Ross 	    0,		/* free space threshold - MUST be 0 */
296a90cf9f2SGordon Ross 	    0,		/* free space stop filtering - MUST be 0 */
297a90cf9f2SGordon Ross 	    SMB_QUOTA_UNLIMITED,	/* default quota threshold */
298a90cf9f2SGordon Ross 	    SMB_QUOTA_UNLIMITED,	/* default quota limit */
299a90cf9f2SGordon Ross 	    FILE_VC_QUOTA_ENFORCE,	/* fs control flag */
300a90cf9f2SGordon Ross 	    0);				/* pad bytes */
301*25a9a7aaSGordon Ross 	if (rc != 0)
302*25a9a7aaSGordon Ross 		return (NT_STATUS_BUFFER_OVERFLOW);
303a90cf9f2SGordon Ross 
304a90cf9f2SGordon Ross 	return (0);
305a90cf9f2SGordon Ross }
306a90cf9f2SGordon Ross 
307a90cf9f2SGordon Ross /*
308a90cf9f2SGordon Ross  * FileFsObjectIdInformation
309a90cf9f2SGordon Ross  */
310a90cf9f2SGordon Ross /* ARGSUSED */
311a90cf9f2SGordon Ross uint32_t
smb2_qfs_obj_id(smb_request_t * sr)312a90cf9f2SGordon Ross smb2_qfs_obj_id(smb_request_t *sr)
313a90cf9f2SGordon Ross {
314a90cf9f2SGordon Ross 	return (NT_STATUS_INVALID_PARAMETER);
315a90cf9f2SGordon Ross }
316252bc4b2SGordon Ross 
317252bc4b2SGordon Ross /*
318252bc4b2SGordon Ross  * Not sure yet where these should go.
319252bc4b2SGordon Ross  * Flags in FileFsSectorSizeInformation
320252bc4b2SGordon Ross  */
321252bc4b2SGordon Ross 
322252bc4b2SGordon Ross #define	SSINFO_FLAGS_ALIGNED_DEVICE	0x00000001
323252bc4b2SGordon Ross // When set, this flag indicates that the first physical sector of the device
324252bc4b2SGordon Ross // is aligned with the first logical sector. When not set, the first physical
325252bc4b2SGordon Ross // sector of the device is misaligned with the first logical sector.
326252bc4b2SGordon Ross 
327252bc4b2SGordon Ross #define	SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE	0x00000002
328252bc4b2SGordon Ross // When set, this flag indicates that the partition is aligned to physical
329252bc4b2SGordon Ross // sector boundaries on the storage device.
330252bc4b2SGordon Ross 
331252bc4b2SGordon Ross #define	SSINFO_FLAGS_NO_SEEK_PENALTY	0x00000004
332252bc4b2SGordon Ross // When set, the device reports that it does not incur a seek penalty (this
333252bc4b2SGordon Ross // typically indicates that the device does not have rotating media, such as
334252bc4b2SGordon Ross // flash-based disks).
335252bc4b2SGordon Ross 
336252bc4b2SGordon Ross #define	SSINFO_FLAGS_TRIM_ENABLED	0x00000008
337252bc4b2SGordon Ross // When set, the device supports TRIM operations, either T13 (ATA) TRIM or
338252bc4b2SGordon Ross // T10 (SCSI/SAS) UNMAP.
339252bc4b2SGordon Ross 
340252bc4b2SGordon Ross #define	SSINFO_OFFSET_UNKNOWN		0xffffffff
341252bc4b2SGordon Ross // For "Alignment" fields below
342252bc4b2SGordon Ross 
343252bc4b2SGordon Ross /*
344252bc4b2SGordon Ross  * We have to lie to Windows Hyper-V about our logical record size,
345252bc4b2SGordon Ross  * because with larger sizes it fails setting up a virtual disk.
346252bc4b2SGordon Ross  */
347252bc4b2SGordon Ross int smb2_max_logical_sector_size = 4096;
348252bc4b2SGordon Ross 
349252bc4b2SGordon Ross /*
350252bc4b2SGordon Ross  * FileFsSectorSizeInformation
351252bc4b2SGordon Ross  *
352252bc4b2SGordon Ross  * Returns a FILE_FS_SECTOR_SIZE_INFORMATION
353252bc4b2SGordon Ross  * See: [MS-FSCC] 2.5.8 FileFsSizeInformation
354252bc4b2SGordon Ross  *
355252bc4b2SGordon Ross  * LogicalBytesPerSector (4 bytes): ... number of bytes in a logical sector
356252bc4b2SGordon Ross  *   for the device backing the volume. This field is the unit of logical
357252bc4b2SGordon Ross  *   addressing for the device and is not the unit of atomic write.
358252bc4b2SGordon Ross  * PhysicalBytesPerSectorForAtomicity (4 bytes): ... number of bytes in a
359252bc4b2SGordon Ross  *   physical sector for the device backing the volume.  This is the reported
360252bc4b2SGordon Ross  *   physical sector size of the device and is the unit of atomic write.
361252bc4b2SGordon Ross  * PhysicalBytesPerSectorForPerformance (4 bytes): ... number of bytes in a
362252bc4b2SGordon Ross  *   physical sector for the device backing the volume. This is the reported
363252bc4b2SGordon Ross  *   physical sector size of the device and is the unit of performance.
364252bc4b2SGordon Ross  * FileSystemEffectivePhysicalBytesPerSectorForAtomicity (4 bytes): unit, in
365252bc4b2SGordon Ross  *   bytes, that the file system on the volume will use for internal operations
366252bc4b2SGordon Ross  *   that require alignment and atomicity.
367252bc4b2SGordon Ross  * Flags (4 bytes): See ...
368252bc4b2SGordon Ross  * ByteOffsetForSectorAlignment (4 bytes): ... logical sector offset within the
369252bc4b2SGordon Ross  *   first physical sector where the first logical sector is placed, in bytes.
370252bc4b2SGordon Ross  *   If this value is set to SSINFO_OFFSET_UNKNOWN (0xffffffff), there was
371252bc4b2SGordon Ross  *   insufficient information to compute this field.
372252bc4b2SGordon Ross  * ByteOffsetForPartitionAlignment (4 bytes): ... byte offset from the first
373252bc4b2SGordon Ross  *   physical sector where the first partition is placed. If this value is
374252bc4b2SGordon Ross  *   set to SSINFO_OFFSET_UNKNOWN (0xffffffff), there was either insufficient
375252bc4b2SGordon Ross  *   information or an error was encountered in computing this field.
376252bc4b2SGordon Ross  */
377252bc4b2SGordon Ross uint32_t
smb2_qfs_sectorsize(smb_request_t * sr)378252bc4b2SGordon Ross smb2_qfs_sectorsize(smb_request_t *sr)
379252bc4b2SGordon Ross {
380252bc4b2SGordon Ross 	smb_fssize_t		fssize;
381252bc4b2SGordon Ross 	smb_tree_t *tree = sr->tid_tree;
382252bc4b2SGordon Ross 	uint32_t lbps, pbps;
383*25a9a7aaSGordon Ross 	uint32_t flags, unk;
384252bc4b2SGordon Ross 	int rc;
385252bc4b2SGordon Ross 
386252bc4b2SGordon Ross 	if (!STYPE_ISDSK(tree->t_res_type))
387252bc4b2SGordon Ross 		return (NT_STATUS_INVALID_PARAMETER);
388252bc4b2SGordon Ross 
389252bc4b2SGordon Ross 	rc = smb_fssize(sr, &fssize);
390252bc4b2SGordon Ross 	if (rc)
391252bc4b2SGordon Ross 		return (smb_errno2status(rc));
392*25a9a7aaSGordon Ross 
393*25a9a7aaSGordon Ross 	// PhysicalBytesPerSector
394252bc4b2SGordon Ross 	pbps = fssize.fs_bytes_per_sector;
395*25a9a7aaSGordon Ross 
396*25a9a7aaSGordon Ross 	// LogicalBytesPerSector
397252bc4b2SGordon Ross 	lbps = fssize.fs_sectors_per_unit * pbps;
398252bc4b2SGordon Ross 	if (lbps > smb2_max_logical_sector_size)
399252bc4b2SGordon Ross 		lbps = smb2_max_logical_sector_size;
400252bc4b2SGordon Ross 
401252bc4b2SGordon Ross 	// Flags
402252bc4b2SGordon Ross 	// We include "no seek penalty" because our files are
403252bc4b2SGordon Ross 	// always ZFS-backed, which can reorder things on disk.
404252bc4b2SGordon Ross 	// Leaving out SSINFO_FLAGS_TRIM_ENABLED for now.
405252bc4b2SGordon Ross 	flags = SSINFO_FLAGS_ALIGNED_DEVICE |
406252bc4b2SGordon Ross 		SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE |
407252bc4b2SGordon Ross 		SSINFO_FLAGS_NO_SEEK_PENALTY;
408252bc4b2SGordon Ross 
409252bc4b2SGordon Ross 	// ByteOffsetForSectorAlignment
410252bc4b2SGordon Ross 	// ByteOffsetForPartitionAlignment
411252bc4b2SGordon Ross 	// Just say "unknown" for these two.
412*25a9a7aaSGordon Ross 	unk = SSINFO_OFFSET_UNKNOWN;
413*25a9a7aaSGordon Ross 
414*25a9a7aaSGordon Ross 	rc = smb_mbc_encodef(
415*25a9a7aaSGordon Ross 	    &sr->raw_data,
416*25a9a7aaSGordon Ross 	    "lllllll",
417*25a9a7aaSGordon Ross 	    lbps, // LogicalBytesPerSector
418*25a9a7aaSGordon Ross 	    pbps, // PhysicalBytesPerSectorForAtomicity
419*25a9a7aaSGordon Ross 	    lbps, // PhysicalBytesPerSectorForPerformance
420*25a9a7aaSGordon Ross 	    pbps, // FileSystemEffectivePhysicalBytesPerSectorForAtomicity
421*25a9a7aaSGordon Ross 	    flags,
422*25a9a7aaSGordon Ross 	    unk, unk);
423*25a9a7aaSGordon Ross 
424*25a9a7aaSGordon Ross 	if (rc != 0)
425*25a9a7aaSGordon Ross 		return (NT_STATUS_BUFFER_OVERFLOW);
426252bc4b2SGordon Ross 
427252bc4b2SGordon Ross 	return (0);
428252bc4b2SGordon Ross }
429