3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  24  */
  25 
  26 /*
  27  * Dispatch function for SMB2_QUERY_INFO
  28  *
  29  * [MS-FSCC 2.5] If a file system does not implement ...
  30  * an Information Classs, NT_STATUS_INVALID_PARAMETER...
  31  */
  32 
  33 #include <smbsrv/smb2_kproto.h>
  34 #include <smbsrv/smb_fsops.h>
  35 #include <smbsrv/ntifs.h>
  36 
  37 uint32_t smb2_qfs_volume(smb_request_t *);
  38 uint32_t smb2_qfs_size(smb_request_t *);
  39 uint32_t smb2_qfs_device(smb_request_t *);
  40 uint32_t smb2_qfs_attr(smb_request_t *);
  41 uint32_t smb2_qfs_control(smb_request_t *);
  42 uint32_t smb2_qfs_fullsize(smb_request_t *);
  43 uint32_t smb2_qfs_obj_id(smb_request_t *);
  44 
  45 uint32_t
  46 smb2_qinfo_fs(smb_request_t *sr, smb_queryinfo_t *qi)
  47 {
  48         uint32_t status;
  49 
  50         switch (qi->qi_InfoClass) {
  51 
  52         /* pg 153 */
  53         case FileFsVolumeInformation:   /* 1 */
  54                 status = smb2_qfs_volume(sr);
  55                 break;
  56         case FileFsSizeInformation:     /* 3 */
  57                 status = smb2_qfs_size(sr);
  58                 break;
  59         case FileFsDeviceInformation:   /* 4 */
  60                 status = smb2_qfs_device(sr);
  61                 break;
  62         case FileFsAttributeInformation: /* 5 */
  63                 status = smb2_qfs_attr(sr);
  64                 break;
  65         case FileFsControlInformation:  /* 6 */
  66                 status = smb2_qfs_control(sr);
  67                 break;
  68         case FileFsFullSizeInformation: /* 7 */
  69                 status = smb2_qfs_fullsize(sr);
  70                 break;
  71         case FileFsObjectIdInformation: /* 8 */
  72                 status = smb2_qfs_obj_id(sr);
  73                 break;
  74 
  75         default:
  76                 status = NT_STATUS_INVALID_INFO_CLASS;
  77                 break;
  78         }
  79 
  80         return (status);
  81 }
  82 
  83 /*
  84  * FileFsVolumeInformation
  85  */
  86 uint32_t
  87 smb2_qfs_volume(smb_request_t *sr)
  88 {
  89         smb_tree_t *tree = sr->tid_tree;
  90         smb_node_t *snode;
  91         fsid_t fsid;
  92         uint32_t LabelLength;
  93 
  94         if (!STYPE_ISDSK(tree->t_res_type))
  95                 return (NT_STATUS_INVALID_PARAMETER);
  96 
  97         snode = tree->t_snode;
 
 269             &sr->raw_data, "qqqqqll",
 270             0,          /* free space start filtering - MUST be 0 */
 271             0,          /* free space threshold - MUST be 0 */
 272             0,          /* free space stop filtering - MUST be 0 */
 273             SMB_QUOTA_UNLIMITED,        /* default quota threshold */
 274             SMB_QUOTA_UNLIMITED,        /* default quota limit */
 275             FILE_VC_QUOTA_ENFORCE,      /* fs control flag */
 276             0);                         /* pad bytes */
 277 
 278         return (0);
 279 }
 280 
 281 /*
 282  * FileFsObjectIdInformation
 283  */
 284 /* ARGSUSED */
 285 uint32_t
 286 smb2_qfs_obj_id(smb_request_t *sr)
 287 {
 288         return (NT_STATUS_INVALID_PARAMETER);
 289 }
 | 
 
 
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  24  */
  25 
  26 /*
  27  * Dispatch function for SMB2_QUERY_INFO
  28  *
  29  * [MS-FSCC 2.5] If a file system does not implement ...
  30  * an Information Classs, NT_STATUS_INVALID_PARAMETER...
  31  */
  32 
  33 #include <smbsrv/smb2_kproto.h>
  34 #include <smbsrv/smb_fsops.h>
  35 #include <smbsrv/ntifs.h>
  36 
  37 uint32_t smb2_qfs_volume(smb_request_t *);
  38 uint32_t smb2_qfs_size(smb_request_t *);
  39 uint32_t smb2_qfs_device(smb_request_t *);
  40 uint32_t smb2_qfs_attr(smb_request_t *);
  41 uint32_t smb2_qfs_control(smb_request_t *);
  42 uint32_t smb2_qfs_fullsize(smb_request_t *);
  43 uint32_t smb2_qfs_obj_id(smb_request_t *);
  44 uint32_t smb2_qfs_sectorsize(smb_request_t *);
  45 
  46 uint32_t
  47 smb2_qinfo_fs(smb_request_t *sr, smb_queryinfo_t *qi)
  48 {
  49         uint32_t status;
  50 
  51         switch (qi->qi_InfoClass) {
  52 
  53         /* pg 153 */
  54         case FileFsVolumeInformation:   /* 1 */
  55                 status = smb2_qfs_volume(sr);
  56                 break;
  57         case FileFsSizeInformation:     /* 3 */
  58                 status = smb2_qfs_size(sr);
  59                 break;
  60         case FileFsDeviceInformation:   /* 4 */
  61                 status = smb2_qfs_device(sr);
  62                 break;
  63         case FileFsAttributeInformation: /* 5 */
  64                 status = smb2_qfs_attr(sr);
  65                 break;
  66         case FileFsControlInformation:  /* 6 */
  67                 status = smb2_qfs_control(sr);
  68                 break;
  69         case FileFsFullSizeInformation: /* 7 */
  70                 status = smb2_qfs_fullsize(sr);
  71                 break;
  72         case FileFsObjectIdInformation: /* 8 */
  73                 status = smb2_qfs_obj_id(sr);
  74                 break;
  75         case FileFsVolumeFlagsInformation:      /* A */
  76                 status = NT_STATUS_INVALID_INFO_CLASS;
  77                 break;
  78         case FileFsSectorSizeInformation:       /* B */
  79                 status = smb2_qfs_sectorsize(sr);
  80                 break;
  81         default: /* there are some infoclasses we don't yet handle */
  82                 status = NT_STATUS_INVALID_INFO_CLASS;
  83 #ifdef  DEBUG
  84                 cmn_err(CE_NOTE, "unknown InfoClass 0x%x", qi->qi_InfoClass);
  85 #endif
  86                 break;
  87         }
  88 
  89         return (status);
  90 }
  91 
  92 /*
  93  * FileFsVolumeInformation
  94  */
  95 uint32_t
  96 smb2_qfs_volume(smb_request_t *sr)
  97 {
  98         smb_tree_t *tree = sr->tid_tree;
  99         smb_node_t *snode;
 100         fsid_t fsid;
 101         uint32_t LabelLength;
 102 
 103         if (!STYPE_ISDSK(tree->t_res_type))
 104                 return (NT_STATUS_INVALID_PARAMETER);
 105 
 106         snode = tree->t_snode;
 
 278             &sr->raw_data, "qqqqqll",
 279             0,          /* free space start filtering - MUST be 0 */
 280             0,          /* free space threshold - MUST be 0 */
 281             0,          /* free space stop filtering - MUST be 0 */
 282             SMB_QUOTA_UNLIMITED,        /* default quota threshold */
 283             SMB_QUOTA_UNLIMITED,        /* default quota limit */
 284             FILE_VC_QUOTA_ENFORCE,      /* fs control flag */
 285             0);                         /* pad bytes */
 286 
 287         return (0);
 288 }
 289 
 290 /*
 291  * FileFsObjectIdInformation
 292  */
 293 /* ARGSUSED */
 294 uint32_t
 295 smb2_qfs_obj_id(smb_request_t *sr)
 296 {
 297         return (NT_STATUS_INVALID_PARAMETER);
 298 }
 299 
 300 /*
 301  * Not sure yet where these should go.
 302  * Flags in FileFsSectorSizeInformation
 303  */
 304 
 305 #define SSINFO_FLAGS_ALIGNED_DEVICE     0x00000001
 306 // When set, this flag indicates that the first physical sector of the device
 307 // is aligned with the first logical sector. When not set, the first physical
 308 // sector of the device is misaligned with the first logical sector.
 309 
 310 #define SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE        0x00000002
 311 // When set, this flag indicates that the partition is aligned to physical
 312 // sector boundaries on the storage device.
 313 
 314 #define SSINFO_FLAGS_NO_SEEK_PENALTY    0x00000004
 315 // When set, the device reports that it does not incur a seek penalty (this
 316 // typically indicates that the device does not have rotating media, such as
 317 // flash-based disks).
 318 
 319 #define SSINFO_FLAGS_TRIM_ENABLED       0x00000008
 320 // When set, the device supports TRIM operations, either T13 (ATA) TRIM or
 321 // T10 (SCSI/SAS) UNMAP.
 322 
 323 #define SSINFO_OFFSET_UNKNOWN           0xffffffff
 324 // For "Alignment" fields below
 325 
 326 /* We have to lie to Windows Hyper-V about our logical record size. */
 327 int smb2_max_logical_sector_size = 4096;
 328 
 329 /*
 330  * FileFsSectorSizeInformation
 331  *
 332  * Returns a FILE_FS_SECTOR_SIZE_INFORMATION
 333  * See: [MS-FSCC] 2.5.8 FileFsSizeInformation
 334  *
 335  * LogicalBytesPerSector (4 bytes): ... number of bytes in a logical sector
 336  *   for the device backing the volume. This field is the unit of logical
 337  *   addressing for the device and is not the unit of atomic write.
 338  * PhysicalBytesPerSectorForAtomicity (4 bytes): ... number of bytes in a
 339  *   physical sector for the device backing the volume.  This is the reported
 340  *   physical sector size of the device and is the unit of atomic write.
 341  * PhysicalBytesPerSectorForPerformance (4 bytes): ... number of bytes in a
 342  *   physical sector for the device backing the volume. This is the reported
 343  *   physical sector size of the device and is the unit of performance.
 344  * FileSystemEffectivePhysicalBytesPerSectorForAtomicity (4 bytes): unit, in
 345  *   bytes, that the file system on the volume will use for internal operations
 346  *   that require alignment and atomicity.
 347  * Flags (4 bytes): See ...
 348  * ByteOffsetForSectorAlignment (4 bytes): ... logical sector offset within the
 349  *   first physical sector where the first logical sector is placed, in bytes.
 350  *   If this value is set to SSINFO_OFFSET_UNKNOWN (0xffffffff), there was
 351  *   insufficient information to compute this field.
 352  * ByteOffsetForPartitionAlignment (4 bytes): ... byte offset from the first
 353  *   physical sector where the first partition is placed. If this value is
 354  *   set to SSINFO_OFFSET_UNKNOWN (0xffffffff), there was either insufficient
 355  *   information or an error was encountered in computing this field.
 356  */
 357 uint32_t
 358 smb2_qfs_sectorsize(smb_request_t *sr)
 359 {
 360         smb_fssize_t            fssize;
 361         smb_tree_t *tree = sr->tid_tree;
 362         uint32_t lbps, pbps;
 363         uint32_t flags;
 364         int rc;
 365 
 366         if (!STYPE_ISDSK(tree->t_res_type))
 367                 return (NT_STATUS_INVALID_PARAMETER);
 368 
 369         rc = smb_fssize(sr, &fssize);
 370         if (rc)
 371                 return (smb_errno2status(rc));
 372         pbps = fssize.fs_bytes_per_sector;
 373         lbps = fssize.fs_sectors_per_unit * pbps;
 374         if (lbps > smb2_max_logical_sector_size)
 375                 lbps = smb2_max_logical_sector_size;
 376 
 377         // LogicalBytesPerSector
 378         (void) smb_mbc_encodef(&sr->raw_data, "l", lbps);
 379 
 380         // PhysicalBytesPerSectorForAtomicity
 381         (void) smb_mbc_encodef(&sr->raw_data, "l", pbps);
 382 
 383         // PhysicalBytesPerSectorForPerformance
 384         // Using logical size here.
 385         (void) smb_mbc_encodef(&sr->raw_data, "l", lbps);
 386 
 387         // FileSystemEffectivePhysicalBytesPerSectorForAtomicity
 388         (void) smb_mbc_encodef(&sr->raw_data, "l", pbps);
 389 
 390         // Flags
 391         // We include "no seek penalty" because our files are
 392         // always ZFS-backed, which can reorder things on disk.
 393         // Leaving out SSINFO_FLAGS_TRIM_ENABLED for now.
 394         flags = SSINFO_FLAGS_ALIGNED_DEVICE |
 395                 SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE |
 396                 SSINFO_FLAGS_NO_SEEK_PENALTY;
 397         (void) smb_mbc_encodef(&sr->raw_data, "l", flags);
 398 
 399         // ByteOffsetForSectorAlignment
 400         // ByteOffsetForPartitionAlignment
 401         // Just say "unknown" for these two.
 402         (void) smb_mbc_encodef(
 403             &sr->raw_data, "l",
 404             SSINFO_OFFSET_UNKNOWN,
 405             SSINFO_OFFSET_UNKNOWN);
 406 
 407         return (0);
 408 }
 |