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 |