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