aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven French <smfrench@gmail.com>2013-10-09 21:55:53 -0400
committerSteve French <smfrench@gmail.com>2013-11-02 13:52:41 -0400
commitaf6a12ea8d4bb39a87527835b943bde4215897e5 (patch)
treea237a3054cd667520b22e4bf27009a1f36e79160
parent2167114c6ea6e76fd84e368bae5389d37dd156aa (diff)
Query File System Alignment
In SMB3 it is now possible to query the file system alignment info, and the preferred (for performance) sector size and whether the underlying disk has no seek penalty (like SSD). Query this information at mount time for SMB3, and make it visible in /proc/fs/cifs/DebugData for debugging purposes. This alignment information and preferred sector size info will be helpful for the copy offload patches to setup the right chunks in the CopyChunk requests. Presumably the knowledge that the underlying disk is SSD could also help us make better readahead and writebehind decisions (something to look at in the future). Signed-off-by: Steve French <smfrench@gmail.com>
-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