diff options
| -rw-r--r-- | fs/cifs/cifsglob.h | 2 | ||||
| -rw-r--r-- | fs/cifs/smb2ops.c | 44 | ||||
| -rw-r--r-- | fs/cifs/smb2pdu.c | 12 | ||||
| -rw-r--r-- | fs/cifs/smb2pdu.h | 22 |
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 | ||
| 212 | static void | 212 | static void |
| 213 | smb3_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 | |||
| 242 | static void | ||
| 213 | smb2_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon) | 243 | smb2_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 | ||
| 338 | static void | 380 | static 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 | ||
| 2407 | qfsattr_exit: | 2417 | qfsattr_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 | ||
| 889 | struct smb2_fs_full_size_info { | 891 | struct 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 */ | ||
| 905 | struct 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 |
