From patchwork Thu Oct 10 02:11:44 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve French X-Patchwork-Id: 3013721 Return-Path: X-Original-To: patchwork-cifs-client@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id F044CBF924 for ; Thu, 10 Oct 2013 02:11:56 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1335B201F9 for ; Thu, 10 Oct 2013 02:11:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2124F20138 for ; Thu, 10 Oct 2013 02:11:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752199Ab3JJCLq (ORCPT ); Wed, 9 Oct 2013 22:11:46 -0400 Received: from mail-pd0-f177.google.com ([209.85.192.177]:37993 "EHLO mail-pd0-f177.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752050Ab3JJCLp (ORCPT ); Wed, 9 Oct 2013 22:11:45 -0400 Received: by mail-pd0-f177.google.com with SMTP id y10so1847084pdj.36 for ; Wed, 09 Oct 2013 19:11:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=CIbZxnWzlyNUM0OH8zYZ9WF6WoiIQeNRgtxA8CGC4yM=; b=eCk+ogtYFSDG9wFtBOtp4ItmK0QoWYi3pwaCpoC4mOG5HgB1wkNqFCUMadoFAaOxq0 tKF9X+lPCA8S87m59IZTq++OSuqV+RDD4Y46KRjkRvkNu8hW5ZdKuTmBdIBI2UlU1LR1 hAizki7bUkNjNh/TIRFrz/JifBjiIF3STWp2fe1/jN4+T47oEG52Zp7wQ/iJSnorrBof /DpK5D18q9609PjC2eSmkn62fpVjpi+FuXku3R/LxvS9qPu4W7Cf/5gpB2oUNcWlSB5V UETqynOEvr56YpXMPEjC3pkdHYK5uGAM2tr4yMVl/9j17bxdC7Vd+LuG8gluU5yR2azw f4tQ== MIME-Version: 1.0 X-Received: by 10.67.23.199 with SMTP id ic7mr12920571pad.73.1381371104359; Wed, 09 Oct 2013 19:11:44 -0700 (PDT) Received: by 10.68.125.106 with HTTP; Wed, 9 Oct 2013 19:11:44 -0700 (PDT) Date: Wed, 9 Oct 2013 21:11:44 -0500 Message-ID: Subject: [PATCH] [CIFS] Query File System Alignment From: Steve French To: "linux-cifs@vger.kernel.org" , linux-fsdevel , samba-technical Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Spam-Status: No, score=-7.0 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, T_TVD_MIME_EPI,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- fs/cifs/cifsglob.h | 2 ++ fs/cifs/smb2ops.c | 44 +++++++++++++++++++++++++++++++++++++++++++- fs/cifs/smb2pdu.c | 12 +++++++++++- 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 06e8947..de3e3e0 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -830,6 +830,8 @@ struct cifs_tcon { __u32 maximal_access; __u32 vol_serial_number; __le64 vol_create_time; + __u32 ss_flags; /* sector size flags */ + __u32 perf_sector_size; /* best sector size for perf */ #endif /* CONFIG_CIFS_SMB2 */ #ifdef CONFIG_CIFS_FSCACHE u64 resource_id; /* server resource id */ diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 79084d6..25759c8 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) } static void +smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon) +{ + int rc; + __le16 srch_path = 0; /* Null - open root of share */ + u8 oplock = SMB2_OPLOCK_LEVEL_NONE; + struct cifs_open_parms oparms; + struct cifs_fid fid; + + oparms.tcon = tcon; + oparms.desired_access = FILE_READ_ATTRIBUTES; + oparms.disposition = FILE_OPEN; + oparms.create_options = 0; + oparms.fid = &fid; + oparms.reconnect = false; + + rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL); + if (rc) + return; + + SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid, + FS_ATTRIBUTE_INFORMATION); + SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid, + FS_DEVICE_INFORMATION); + SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid, + FS_SECTOR_SIZE_INFORMATION); /* SMB3 specific */ + SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); + return; +} + +static void smb2_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon) { int rc; @@ -332,7 +362,19 @@ smb2_dump_share_caps(struct seq_file *m, struct cifs_tcon *tcon) seq_puts(m, " ASYMMETRIC,"); if (tcon->capabilities == 0) seq_puts(m, " None"); + if (tcon->ss_flags & SSINFO_FLAGS_ALIGNED_DEVICE) + seq_puts(m, " Aligned,"); + if (tcon->ss_flags & SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE) + seq_puts(m, " Partition Aligned,"); + if (tcon->ss_flags & SSINFO_FLAGS_NO_SEEK_PENALTY) + seq_puts(m, " SSD,"); + if (tcon->ss_flags & SSINFO_FLAGS_TRIM_ENABLED) + seq_puts(m, " TRIM-support,"); + seq_printf(m, "\tShare Flags: 0x%x", tcon->share_flags); + if (tcon->perf_sector_size) + seq_printf(m, "\tOptimal sector size: 0x%x", + tcon->perf_sector_size); } static void @@ -1048,7 +1090,7 @@ struct smb_version_operations smb30_operations = { .logoff = SMB2_logoff, .tree_connect = SMB2_tcon, .tree_disconnect = SMB2_tdis, - .qfs_tcon = smb2_qfs_tcon, + .qfs_tcon = smb3_qfs_tcon, .is_path_accessible = smb2_is_path_accessible, .can_echo = smb2_can_echo, .echo = SMB2_echo, diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index f6449ba..31ac96c 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -2362,8 +2362,11 @@ SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon, } else if (level == FS_ATTRIBUTE_INFORMATION) { max_len = sizeof(FILE_SYSTEM_ATTRIBUTE_INFO); min_len = MIN_FS_ATTR_INFO_SIZE; + } else if (level == FS_SECTOR_SIZE_INFORMATION) { + max_len = sizeof(struct smb3_fs_ss_info); + min_len = sizeof(struct smb3_fs_ss_info); } else { - cifs_dbg(FYI, "Invalid qfsinfo level %d", level); + cifs_dbg(FYI, "Invalid qfsinfo level %d\n", level); return -EINVAL; } @@ -2392,6 +2395,13 @@ SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon, else if (level == FS_DEVICE_INFORMATION) memcpy(&tcon->fsDevInfo, 4 /* RFC1001 len */ + offset + (char *)&rsp->hdr, sizeof(FILE_SYSTEM_DEVICE_INFO)); + else if (level == FS_SECTOR_SIZE_INFORMATION) { + struct smb3_fs_ss_info *ss_info = (struct smb3_fs_ss_info *) + (4 /* RFC1001 len */ + offset + (char *)&rsp->hdr); + tcon->ss_flags = le32_to_cpu(ss_info->Flags); + tcon->perf_sector_size = + le32_to_cpu(ss_info->PhysicalBytesPerSectorForPerf); + } qfsattr_exit: free_rsp_buf(resp_buftype, iov.iov_base); diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index c7c3c82..7e44f18 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h @@ -877,14 +877,16 @@ struct smb2_lease_ack { /* File System Information Classes */ #define FS_VOLUME_INFORMATION 1 /* Query */ -#define FS_LABEL_INFORMATION 2 /* Set */ +#define FS_LABEL_INFORMATION 2 /* Local only */ #define FS_SIZE_INFORMATION 3 /* Query */ #define FS_DEVICE_INFORMATION 4 /* Query */ #define FS_ATTRIBUTE_INFORMATION 5 /* Query */ #define FS_CONTROL_INFORMATION 6 /* Query, Set */ #define FS_FULL_SIZE_INFORMATION 7 /* Query */ #define FS_OBJECT_ID_INFORMATION 8 /* Query, Set */ -#define FS_DRIVER_PATH_INFORMATION 9 /* Query */ +#define FS_DRIVER_PATH_INFORMATION 9 /* Local only */ +#define FS_VOLUME_FLAGS_INFORMATION 10 /* Local only */ +#define FS_SECTOR_SIZE_INFORMATION 11 /* SMB3 or later. Query */ struct smb2_fs_full_size_info { __le64 TotalAllocationUnits; @@ -894,6 +896,22 @@ struct smb2_fs_full_size_info { __le32 BytesPerSector; } __packed; +#define SSINFO_FLAGS_ALIGNED_DEVICE 0x00000001 +#define SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE 0x00000002 +#define SSINFO_FLAGS_NO_SEEK_PENALTY 0x00000004 +#define SSINFO_FLAGS_TRIM_ENABLED 0x00000008 + +/* sector size info struct */ +struct smb3_fs_ss_info { + __le32 LogicalBytesPerSector; + __le32 PhysicalBytesPerSectorForAtomicity; + __le32 PhysicalBytesPerSectorForPerf; + __le32 FileSystemEffectivePhysicalBytesPerSectorForAtomicity; + __le32 Flags; + __le32 ByteOffsetForSectorAlignment; + __le32 ByteOffsetForPartitionAlignment; +} __packed; + /* partial list of QUERY INFO levels */ #define FILE_DIRECTORY_INFORMATION 1 #define FILE_FULL_DIRECTORY_INFORMATION 2