aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifsglob.h2
-rw-r--r--fs/cifs/smb2ops.c44
-rw-r--r--fs/cifs/smb2pdu.c12
-rw-r--r--fs/cifs/smb2pdu.h22
4 files changed, 76 insertions, 4 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 670da1e55be7..26b1c1dc93f6 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -853,6 +853,8 @@ struct cifs_tcon {
853 __u32 maximal_access; 853 __u32 maximal_access;
854 __u32 vol_serial_number; 854 __u32 vol_serial_number;
855 __le64 vol_create_time; 855 __le64 vol_create_time;
856 __u32 ss_flags; /* sector size flags */
857 __u32 perf_sector_size; /* best sector size for perf */
856#endif /* CONFIG_CIFS_SMB2 */ 858#endif /* CONFIG_CIFS_SMB2 */
857#ifdef CONFIG_CIFS_FSCACHE 859#ifdef CONFIG_CIFS_FSCACHE
858 u64 resource_id; /* server resource id */ 860 u64 resource_id; /* server resource id */
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 79084d67f3fb..25759c89619a 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -210,6 +210,36 @@ smb2_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
210} 210}
211 211
212static void 212static void
213smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
214{
215 int rc;
216 __le16 srch_path = 0; /* Null - open root of share */
217 u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
218 struct cifs_open_parms oparms;
219 struct cifs_fid fid;
220
221 oparms.tcon = tcon;
222 oparms.desired_access = FILE_READ_ATTRIBUTES;
223 oparms.disposition = FILE_OPEN;
224 oparms.create_options = 0;
225 oparms.fid = &fid;
226 oparms.reconnect = false;
227
228 rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL);
229 if (rc)
230 return;
231
232 SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
233 FS_ATTRIBUTE_INFORMATION);
234 SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
235 FS_DEVICE_INFORMATION);
236 SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
237 FS_SECTOR_SIZE_INFORMATION); /* SMB3 specific */
238 SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
239 return;
240}
241
242static void
213smb2_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon) 243smb2_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
214{ 244{
215 int rc; 245 int rc;
@@ -332,7 +362,19 @@ smb2_dump_share_caps(struct seq_file *m, struct cifs_tcon *tcon)
332 seq_puts(m, " ASYMMETRIC,"); 362 seq_puts(m, " ASYMMETRIC,");
333 if (tcon->capabilities == 0) 363 if (tcon->capabilities == 0)
334 seq_puts(m, " None"); 364 seq_puts(m, " None");
365 if (tcon->ss_flags & SSINFO_FLAGS_ALIGNED_DEVICE)
366 seq_puts(m, " Aligned,");
367 if (tcon->ss_flags & SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE)
368 seq_puts(m, " Partition Aligned,");
369 if (tcon->ss_flags & SSINFO_FLAGS_NO_SEEK_PENALTY)
370 seq_puts(m, " SSD,");
371 if (tcon->ss_flags & SSINFO_FLAGS_TRIM_ENABLED)
372 seq_puts(m, " TRIM-support,");
373
335 seq_printf(m, "\tShare Flags: 0x%x", tcon->share_flags); 374 seq_printf(m, "\tShare Flags: 0x%x", tcon->share_flags);
375 if (tcon->perf_sector_size)
376 seq_printf(m, "\tOptimal sector size: 0x%x",
377 tcon->perf_sector_size);
336} 378}
337 379
338static void 380static void
@@ -1048,7 +1090,7 @@ struct smb_version_operations smb30_operations = {
1048 .logoff = SMB2_logoff, 1090 .logoff = SMB2_logoff,
1049 .tree_connect = SMB2_tcon, 1091 .tree_connect = SMB2_tcon,
1050 .tree_disconnect = SMB2_tdis, 1092 .tree_disconnect = SMB2_tdis,
1051 .qfs_tcon = smb2_qfs_tcon, 1093 .qfs_tcon = smb3_qfs_tcon,
1052 .is_path_accessible = smb2_is_path_accessible, 1094 .is_path_accessible = smb2_is_path_accessible,
1053 .can_echo = smb2_can_echo, 1095 .can_echo = smb2_can_echo,
1054 .echo = SMB2_echo, 1096 .echo = SMB2_echo,
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 7887cf50e5fb..8ab05b0d6778 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -2373,8 +2373,11 @@ SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon,
2373 } else if (level == FS_ATTRIBUTE_INFORMATION) { 2373 } else if (level == FS_ATTRIBUTE_INFORMATION) {
2374 max_len = sizeof(FILE_SYSTEM_ATTRIBUTE_INFO); 2374 max_len = sizeof(FILE_SYSTEM_ATTRIBUTE_INFO);
2375 min_len = MIN_FS_ATTR_INFO_SIZE; 2375 min_len = MIN_FS_ATTR_INFO_SIZE;
2376 } else if (level == FS_SECTOR_SIZE_INFORMATION) {
2377 max_len = sizeof(struct smb3_fs_ss_info);
2378 min_len = sizeof(struct smb3_fs_ss_info);
2376 } else { 2379 } else {
2377 cifs_dbg(FYI, "Invalid qfsinfo level %d", level); 2380 cifs_dbg(FYI, "Invalid qfsinfo level %d\n", level);
2378 return -EINVAL; 2381 return -EINVAL;
2379 } 2382 }
2380 2383
@@ -2403,6 +2406,13 @@ SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon,
2403 else if (level == FS_DEVICE_INFORMATION) 2406 else if (level == FS_DEVICE_INFORMATION)
2404 memcpy(&tcon->fsDevInfo, 4 /* RFC1001 len */ + offset 2407 memcpy(&tcon->fsDevInfo, 4 /* RFC1001 len */ + offset
2405 + (char *)&rsp->hdr, sizeof(FILE_SYSTEM_DEVICE_INFO)); 2408 + (char *)&rsp->hdr, sizeof(FILE_SYSTEM_DEVICE_INFO));
2409 else if (level == FS_SECTOR_SIZE_INFORMATION) {
2410 struct smb3_fs_ss_info *ss_info = (struct smb3_fs_ss_info *)
2411 (4 /* RFC1001 len */ + offset + (char *)&rsp->hdr);
2412 tcon->ss_flags = le32_to_cpu(ss_info->Flags);
2413 tcon->perf_sector_size =
2414 le32_to_cpu(ss_info->PhysicalBytesPerSectorForPerf);
2415 }
2406 2416
2407qfsattr_exit: 2417qfsattr_exit:
2408 free_rsp_buf(resp_buftype, iov.iov_base); 2418 free_rsp_buf(resp_buftype, iov.iov_base);
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
index c7c3c8294d1a..7e44f18cc169 100644
--- a/fs/cifs/smb2pdu.h
+++ b/fs/cifs/smb2pdu.h
@@ -877,14 +877,16 @@ struct smb2_lease_ack {
877 877
878/* File System Information Classes */ 878/* File System Information Classes */
879#define FS_VOLUME_INFORMATION 1 /* Query */ 879#define FS_VOLUME_INFORMATION 1 /* Query */
880#define FS_LABEL_INFORMATION 2 /* Set */ 880#define FS_LABEL_INFORMATION 2 /* Local only */
881#define FS_SIZE_INFORMATION 3 /* Query */ 881#define FS_SIZE_INFORMATION 3 /* Query */
882#define FS_DEVICE_INFORMATION 4 /* Query */ 882#define FS_DEVICE_INFORMATION 4 /* Query */
883#define FS_ATTRIBUTE_INFORMATION 5 /* Query */ 883#define FS_ATTRIBUTE_INFORMATION 5 /* Query */
884#define FS_CONTROL_INFORMATION 6 /* Query, Set */ 884#define FS_CONTROL_INFORMATION 6 /* Query, Set */
885#define FS_FULL_SIZE_INFORMATION 7 /* Query */ 885#define FS_FULL_SIZE_INFORMATION 7 /* Query */
886#define FS_OBJECT_ID_INFORMATION 8 /* Query, Set */ 886#define FS_OBJECT_ID_INFORMATION 8 /* Query, Set */
887#define FS_DRIVER_PATH_INFORMATION 9 /* Query */ 887#define FS_DRIVER_PATH_INFORMATION 9 /* Local only */
888#define FS_VOLUME_FLAGS_INFORMATION 10 /* Local only */
889#define FS_SECTOR_SIZE_INFORMATION 11 /* SMB3 or later. Query */
888 890
889struct smb2_fs_full_size_info { 891struct smb2_fs_full_size_info {
890 __le64 TotalAllocationUnits; 892 __le64 TotalAllocationUnits;
@@ -894,6 +896,22 @@ struct smb2_fs_full_size_info {
894 __le32 BytesPerSector; 896 __le32 BytesPerSector;
895} __packed; 897} __packed;
896 898
899#define SSINFO_FLAGS_ALIGNED_DEVICE 0x00000001
900#define SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE 0x00000002
901#define SSINFO_FLAGS_NO_SEEK_PENALTY 0x00000004
902#define SSINFO_FLAGS_TRIM_ENABLED 0x00000008
903
904/* sector size info struct */
905struct smb3_fs_ss_info {
906 __le32 LogicalBytesPerSector;
907 __le32 PhysicalBytesPerSectorForAtomicity;
908 __le32 PhysicalBytesPerSectorForPerf;
909 __le32 FileSystemEffectivePhysicalBytesPerSectorForAtomicity;
910 __le32 Flags;
911 __le32 ByteOffsetForSectorAlignment;
912 __le32 ByteOffsetForPartitionAlignment;
913} __packed;
914
897/* partial list of QUERY INFO levels */ 915/* partial list of QUERY INFO levels */
898#define FILE_DIRECTORY_INFORMATION 1 916#define FILE_DIRECTORY_INFORMATION 1
899#define FILE_FULL_DIRECTORY_INFORMATION 2 917#define FILE_FULL_DIRECTORY_INFORMATION 2