From patchwork Wed Oct 9 07:11:43 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve French X-Patchwork-Id: 3007251 Return-Path: X-Original-To: patchwork-cifs-client@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 13EBE9F1E1 for ; Wed, 9 Oct 2013 07:11:59 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id EE8282018C for ; Wed, 9 Oct 2013 07:11:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 56A1420160 for ; Wed, 9 Oct 2013 07:11:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756261Ab3JIHLq (ORCPT ); Wed, 9 Oct 2013 03:11:46 -0400 Received: from mail-pb0-f47.google.com ([209.85.160.47]:46183 "EHLO mail-pb0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756237Ab3JIHLo (ORCPT ); Wed, 9 Oct 2013 03:11:44 -0400 Received: by mail-pb0-f47.google.com with SMTP id rr4so474886pbb.6 for ; Wed, 09 Oct 2013 00:11:43 -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=i95WvlWIicDHAC4+LV71W69DMF9CNWjAzPVvXwGV8OE=; b=BEz1x3CxabZiTJswqQgtcq9LtrxAuEID8+hwkczOMh7xTT4WuwZJFGOHiIyIUIrFCC JP7X8nn7cdZ73uE2mYXubhSE88WecWsQY/bhzvF2xT17FsRRKVTTyPlBDDCfKyJbyCIR X28LU72jLmQ/KEgsSbWBmyLHxRRfAL7E3I7s2n2lUwS+bZAaptlzdfDLSoEWzB5rdiRz OvTYlg8ATeA4n6afhi1HmzVo1E/juAOXB+b3gT+v9l/D/fBHtkafuZyib+OV9xNbkBas YDqur9EK2Kk+hWq7qomUCb3/vra88ZorM7L3VY9IK+MIeAbDsQA9nC64nLqm49lNPoQL uAjg== MIME-Version: 1.0 X-Received: by 10.68.219.33 with SMTP id pl1mr6112992pbc.147.1381302703504; Wed, 09 Oct 2013 00:11:43 -0700 (PDT) Received: by 10.68.125.106 with HTTP; Wed, 9 Oct 2013 00:11:43 -0700 (PDT) Date: Wed, 9 Oct 2013 02:11:43 -0500 Message-ID: Subject: [PATCH] [CIFS] Query file system attributes from server on SMB2, not just cifs, mounts From: Steve French To: "linux-cifs@vger.kernel.org" , 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 Currently SMB2 and SMB3 mounts do not query the file system attributes from the server at mount time as is done for cifs. These can be useful for debugging. These could be used in the future to determine when we are able to request certain optional features (compressed files e.g.) of the protocol. Signed-off-by: Steve French --- fs/cifs/cifspdu.h | 3 +++ fs/cifs/smb2ops.c | 28 ++++++++++++++++++++++++++++ fs/cifs/smb2pdu.c | 42 ++++++++++++++++++++++++++++++++++++++++-- fs/cifs/smb2proto.h | 2 ++ 4 files changed, 73 insertions(+), 2 deletions(-) const __u32 pid, const __u64 length, const __u64 offset, diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 08f9dfb..d40bd77 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -2215,6 +2215,9 @@ typedef struct { __le32 DeviceCharacteristics; } __attribute__((packed)) FILE_SYSTEM_DEVICE_INFO; /* device info level 0x104 */ +/* minimum includes first three fields, and empty FS Name */ +#define MIN_FS_ATTR_INFO_SIZE 12 + typedef struct { __le32 Attributes; __le32 MaxPathNameComponentLength; diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index b96bacc..a53e205 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -209,6 +209,31 @@ smb2_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info) return rsize; } +static void +smb2_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); + SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); + return; +} + static int smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, const char *full_path) @@ -873,6 +898,7 @@ struct smb_version_operations smb20_operations = { .logoff = SMB2_logoff, .tree_connect = SMB2_tcon, .tree_disconnect = SMB2_tdis, + .qfs_tcon = smb2_qfs_tcon, .is_path_accessible = smb2_is_path_accessible, .can_echo = smb2_can_echo, .echo = SMB2_echo, @@ -945,6 +971,7 @@ struct smb_version_operations smb21_operations = { .logoff = SMB2_logoff, .tree_connect = SMB2_tcon, .tree_disconnect = SMB2_tdis, + .qfs_tcon = smb2_qfs_tcon, .is_path_accessible = smb2_is_path_accessible, .can_echo = smb2_can_echo, .echo = SMB2_echo, @@ -1018,6 +1045,7 @@ struct smb_version_operations smb30_operations = { .logoff = SMB2_logoff, .tree_connect = SMB2_tcon, .tree_disconnect = SMB2_tdis, + .qfs_tcon = smb2_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 fb19ad8..2ade58b 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -2328,7 +2328,7 @@ SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, rc = SendReceive2(xid, ses, &iov, 1, &resp_buftype, 0); if (rc) { cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); - goto qinf_exit; + goto qfsinf_exit; } rsp = (struct smb2_query_info_rsp *)iov.iov_base; @@ -2340,7 +2340,45 @@ SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, if (!rc) copy_fs_info_to_kstatfs(info, fsdata); -qinf_exit: +qfsinf_exit: + free_rsp_buf(resp_buftype, iov.iov_base); + return rc; +} + +int +SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_fid, u64 volatile_fid) +{ + struct smb2_query_info_rsp *rsp = NULL; + struct kvec iov; + int rc = 0; + int resp_buftype; + struct cifs_ses *ses = tcon->ses; + unsigned int rsp_len, offset; + + rc = build_qfs_info_req(&iov, tcon, SMB_QUERY_FS_ATTRIBUTE_INFO, + sizeof(FILE_SYSTEM_ATTRIBUTE_INFO), + persistent_fid, volatile_fid); + if (rc) + return rc; + + rc = SendReceive2(xid, ses, &iov, 1, &resp_buftype, 0); + if (rc) { + cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); + goto qfsattr_exit; + } + rsp = (struct smb2_query_info_rsp *)iov.iov_base; + + rsp_len = le32_to_cpu(rsp->OutputBufferLength); + offset = le16_to_cpu(rsp->OutputBufferOffset); + rc = validate_buf(offset, rsp_len, &rsp->hdr, MIN_FS_ATTR_INFO_SIZE); + if (!rc) { + memcpy(&tcon->fsAttrInfo, 4 /* RFC1001 len */ + offset + + (char *)&rsp->hdr, min_t(unsigned int, + rsp_len, sizeof(FILE_SYSTEM_ATTRIBUTE_INFO))); + } + +qfsattr_exit: free_rsp_buf(resp_buftype, iov.iov_base); return rc; } diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index 3cf22e3..68dc00d 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h @@ -150,6 +150,8 @@ extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, extern int SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_file_id, u64 volatile_file_id, struct kstatfs *FSData); +extern int SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_file_id, u64 volatile_file_id); extern int SMB2_lock(const unsigned int xid, struct cifs_tcon *tcon, const __u64 persist_fid, const __u64 volatile_fid,