Print this page
NEX-15680 Implement SMB2 getinfo FS level FileFsSectorSizeInformation
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15680 Implement SMB2 getinfo FS level FileFsSectorSizeInformation
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5598 SMB needs a few more ioctls for Hyper-V
Reviewed by: Gordon Ross <gwr@nexenta.com>
SMB-11 SMB2 message parse & dispatch
SMB-12 SMB2 Negotiate Protocol
SMB-13 SMB2 Session Setup
SMB-14 SMB2 Logoff
SMB-15 SMB2 Tree Connect
SMB-16 SMB2 Tree Disconnect
SMB-17 SMB2 Create
SMB-18 SMB2 Close
SMB-19 SMB2 Flush
SMB-20 SMB2 Read
SMB-21 SMB2 Write
SMB-22 SMB2 Lock/Unlock
SMB-23 SMB2 Ioctl
SMB-24 SMB2 Cancel
SMB-25 SMB2 Echo
SMB-26 SMB2 Query Dir
SMB-27 SMB2 Change Notify
SMB-28 SMB2 Query Info
SMB-29 SMB2 Set Info
SMB-30 SMB2 Oplocks
SMB-53 SMB2 Create Context options
(SMB2 code review cleanup 1, 2, 3)

*** 18,28 **** * * CDDL HEADER END */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2013 Nexenta Systems, Inc. All rights reserved. */ /* * Dispatch function for SMB2_QUERY_INFO * --- 18,28 ---- * * CDDL HEADER END */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ /* * Dispatch function for SMB2_QUERY_INFO *
*** 39,48 **** --- 39,49 ---- uint32_t smb2_qfs_device(smb_request_t *); uint32_t smb2_qfs_attr(smb_request_t *); uint32_t smb2_qfs_control(smb_request_t *); uint32_t smb2_qfs_fullsize(smb_request_t *); uint32_t smb2_qfs_obj_id(smb_request_t *); + uint32_t smb2_qfs_sectorsize(smb_request_t *); uint32_t smb2_qinfo_fs(smb_request_t *sr, smb_queryinfo_t *qi) { uint32_t status;
*** 69,82 **** status = smb2_qfs_fullsize(sr); break; case FileFsObjectIdInformation: /* 8 */ status = smb2_qfs_obj_id(sr); break; ! ! default: status = NT_STATUS_INVALID_INFO_CLASS; break; } return (status); } --- 70,91 ---- status = smb2_qfs_fullsize(sr); break; case FileFsObjectIdInformation: /* 8 */ status = smb2_qfs_obj_id(sr); break; ! case FileFsVolumeFlagsInformation: /* A */ status = NT_STATUS_INVALID_INFO_CLASS; break; + case FileFsSectorSizeInformation: /* B */ + status = smb2_qfs_sectorsize(sr); + break; + default: /* there are some infoclasses we don't yet handle */ + status = NT_STATUS_INVALID_INFO_CLASS; + #ifdef DEBUG + cmn_err(CE_NOTE, "unknown InfoClass 0x%x", qi->qi_InfoClass); + #endif + break; } return (status); }
*** 284,289 **** --- 293,408 ---- /* ARGSUSED */ uint32_t smb2_qfs_obj_id(smb_request_t *sr) { return (NT_STATUS_INVALID_PARAMETER); + } + + /* + * Not sure yet where these should go. + * Flags in FileFsSectorSizeInformation + */ + + #define SSINFO_FLAGS_ALIGNED_DEVICE 0x00000001 + // When set, this flag indicates that the first physical sector of the device + // is aligned with the first logical sector. When not set, the first physical + // sector of the device is misaligned with the first logical sector. + + #define SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE 0x00000002 + // When set, this flag indicates that the partition is aligned to physical + // sector boundaries on the storage device. + + #define SSINFO_FLAGS_NO_SEEK_PENALTY 0x00000004 + // When set, the device reports that it does not incur a seek penalty (this + // typically indicates that the device does not have rotating media, such as + // flash-based disks). + + #define SSINFO_FLAGS_TRIM_ENABLED 0x00000008 + // When set, the device supports TRIM operations, either T13 (ATA) TRIM or + // T10 (SCSI/SAS) UNMAP. + + #define SSINFO_OFFSET_UNKNOWN 0xffffffff + // For "Alignment" fields below + + /* We have to lie to Windows Hyper-V about our logical record size. */ + int smb2_max_logical_sector_size = 4096; + + /* + * FileFsSectorSizeInformation + * + * Returns a FILE_FS_SECTOR_SIZE_INFORMATION + * See: [MS-FSCC] 2.5.8 FileFsSizeInformation + * + * LogicalBytesPerSector (4 bytes): ... number of bytes in a logical sector + * for the device backing the volume. This field is the unit of logical + * addressing for the device and is not the unit of atomic write. + * PhysicalBytesPerSectorForAtomicity (4 bytes): ... number of bytes in a + * physical sector for the device backing the volume. This is the reported + * physical sector size of the device and is the unit of atomic write. + * PhysicalBytesPerSectorForPerformance (4 bytes): ... number of bytes in a + * physical sector for the device backing the volume. This is the reported + * physical sector size of the device and is the unit of performance. + * FileSystemEffectivePhysicalBytesPerSectorForAtomicity (4 bytes): unit, in + * bytes, that the file system on the volume will use for internal operations + * that require alignment and atomicity. + * Flags (4 bytes): See ... + * ByteOffsetForSectorAlignment (4 bytes): ... logical sector offset within the + * first physical sector where the first logical sector is placed, in bytes. + * If this value is set to SSINFO_OFFSET_UNKNOWN (0xffffffff), there was + * insufficient information to compute this field. + * ByteOffsetForPartitionAlignment (4 bytes): ... byte offset from the first + * physical sector where the first partition is placed. If this value is + * set to SSINFO_OFFSET_UNKNOWN (0xffffffff), there was either insufficient + * information or an error was encountered in computing this field. + */ + uint32_t + smb2_qfs_sectorsize(smb_request_t *sr) + { + smb_fssize_t fssize; + smb_tree_t *tree = sr->tid_tree; + uint32_t lbps, pbps; + uint32_t flags; + int rc; + + if (!STYPE_ISDSK(tree->t_res_type)) + return (NT_STATUS_INVALID_PARAMETER); + + rc = smb_fssize(sr, &fssize); + if (rc) + return (smb_errno2status(rc)); + pbps = fssize.fs_bytes_per_sector; + lbps = fssize.fs_sectors_per_unit * pbps; + if (lbps > smb2_max_logical_sector_size) + lbps = smb2_max_logical_sector_size; + + // LogicalBytesPerSector + (void) smb_mbc_encodef(&sr->raw_data, "l", lbps); + + // PhysicalBytesPerSectorForAtomicity + (void) smb_mbc_encodef(&sr->raw_data, "l", pbps); + + // PhysicalBytesPerSectorForPerformance + // Using logical size here. + (void) smb_mbc_encodef(&sr->raw_data, "l", lbps); + + // FileSystemEffectivePhysicalBytesPerSectorForAtomicity + (void) smb_mbc_encodef(&sr->raw_data, "l", pbps); + + // Flags + // We include "no seek penalty" because our files are + // always ZFS-backed, which can reorder things on disk. + // Leaving out SSINFO_FLAGS_TRIM_ENABLED for now. + flags = SSINFO_FLAGS_ALIGNED_DEVICE | + SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE | + SSINFO_FLAGS_NO_SEEK_PENALTY; + (void) smb_mbc_encodef(&sr->raw_data, "l", flags); + + // ByteOffsetForSectorAlignment + // ByteOffsetForPartitionAlignment + // Just say "unknown" for these two. + (void) smb_mbc_encodef( + &sr->raw_data, "l", + SSINFO_OFFSET_UNKNOWN, + SSINFO_OFFSET_UNKNOWN); + + return (0); }