From patchwork Thu Jun 21 07:26:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve French X-Patchwork-Id: 932611 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-cifs-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="C0D3mXb2"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41BCvL5nCMz9s2L for ; Thu, 21 Jun 2018 17:27:10 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754210AbeFUH1J (ORCPT ); Thu, 21 Jun 2018 03:27:09 -0400 Received: from mail-pf0-f179.google.com ([209.85.192.179]:40464 "EHLO mail-pf0-f179.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754166AbeFUH1I (ORCPT ); Thu, 21 Jun 2018 03:27:08 -0400 Received: by mail-pf0-f179.google.com with SMTP id z24-v6so1081389pfe.7 for ; Thu, 21 Jun 2018 00:27:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to:cc; bh=HseMtW8KN4yeqckRLR1k80UYvWXLk6tDdo2uAOR1Ow0=; b=C0D3mXb20MDjOt8VOP0r+KZ0iXGdztwF9CYyAglbhMetLMlLB01xDgrPhJ4qH8zVlF FAnS3XkqSb6eYs9lXa0Bx/ZnGXFvhB7Ojt7caQyUAZJ9IIfogvJLMWRMI7VBDZB5OoFp UnrqSp0qToRmjAZmZebzW//At08647zEV/NmOHkr0L9oRsZ1LjiY9o0hscAfbohEFIcp RbxOpJl5cTPk/XG58x8+1CkYF4cBhnR0CgszW7WMpyXxfzJpZP/U6ejj5W8I7eH3fWxw Z3591FYLzStesG5slSjiLR30wgH+2zEpw7x0aHlQ64onS9LhkN+myXhYIIxG8kdMjpx8 l2fg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to:cc; bh=HseMtW8KN4yeqckRLR1k80UYvWXLk6tDdo2uAOR1Ow0=; b=IdVNKIJQZY9wtbqJ1yAyi2CyXNV3ZvDCBUyOf5aSXTEfZoAEm65LVaCzf79y8Ir+Wd j2Z0qFzCa8oBUpVgLAYKRfWjT7LGfQBSipOJmnlYOCWL7COLZCAvFpHMkZu9PbPRaqHV yTE++o+m8H2L090qNazvQs71JQ36aSGqsSMuWkFMdX1/l6L7CDRVwVT5/d3l5RXnX0F9 r2VrnjtJINxW84pinPPtcXraJZAPm/4LlrivuiOfn7ap8mGnBbhCjwTt6fpDM+aCmqCg eTcdCvl/RJO/bTj9QT6t2pv7NafkgWtpk8/h7DSFP6r6JqJreCGZ/ZbTb5Ua4SLjau6f yIXA== X-Gm-Message-State: APt69E04rXV3A8mcEAxpcj5gAYSbUJKeilucmT9qInBnFatoNuMZt4Gn 5GrOJ61EbPVklMt2tkSkrH7fwLmIL1R++xn2V/167g3e X-Google-Smtp-Source: ADUXVKK4RFOFNG2wzRmndcYTf7srSVIOSEbnPNhoTbB+3Y3f849e2DLWyyKBqpkUetULdNVexm+QOOO2V0p46VDNXCw= X-Received: by 2002:a65:4a90:: with SMTP id b16-v6mr21343109pgu.136.1529566027729; Thu, 21 Jun 2018 00:27:07 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:a17:90a:80cc:0:0:0:0 with HTTP; Thu, 21 Jun 2018 00:26:46 -0700 (PDT) From: Steve French Date: Thu, 21 Jun 2018 02:26:46 -0500 Message-ID: Subject: SMB3.1.1 POSIX Extensions: statfs To: CIFS , samba-technical Cc: =?utf-8?q?Aur=C3=A9lien_Aptel?= , Jeremy Allison Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Output for "stat -f" (statfs) experiment with POSIX SMB3.11 extensions against jra's current tree (without the extensions, data looks very different) root@smf-Thinkpad-P51:~/cifs-2.6# cat /proc/mounts | grep smb3 //127.0.0.1/scratch /mnt1 smb3 rw,relatime,vers=3.1.1,cache=strict,username=testuser,domain=,uid=0,noforceuid,gid=0,noforcegid,addr=127.0.0.1,file_mode=0755,dir_mode=0755,soft,posix,posixpaths,serverino,mapposix,noperm,rsize=1048576,wsize=1048576,echo_interval=60,actimeo=1 0 0 root@smf-Thinkpad-P51:~/cifs-2.6# stat -f /mnt1 File: "/mnt1" ID: 0 Namelen: 4096 Type: smb2 Block size: 4096 Fundamental block size: 4096 Blocks: Total: 58701044 Free: 10080249 Available: 7080966 Inodes: Total: 14983168 Free: 13901538 Compare with the actual "stat -f" output against the local directory: root@smf-Thinkpad-P51:~/cifs-2.6# stat -f /scratch File: "/scratch" ID: e94471edc7140504 Namelen: 255 Type: ext2/ext3 Block size: 4096 Fundamental block size: 4096 Blocks: Total: 58701044 Free: 10080127 Available: 7080844 Inodes: Total: 14983168 Free: 13901536 From 6391cdc801f7f0984ca511dc9224e72decbc0b51 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 21 Jun 2018 02:21:10 -0500 Subject: [PATCH] smb3: add support for statfs for smb3.1.1 posix extensions Output now matches expected stat -f output for all fields except for Namelen and ID Signed-off-by: Steve French --- fs/cifs/smb2ops.c | 33 ++++++++++++++++++- fs/cifs/smb2pdu.c | 77 +++++++++++++++++++++++++++++++++++++++++++++ fs/cifs/smb2pdu.h | 1 + fs/cifs/smb2proto.h | 3 ++ 4 files changed, 113 insertions(+), 1 deletion(-) diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 5cd16ae605b8..8ac40cf4c115 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -1529,6 +1529,37 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon, return rc; } +static int +smb311_queryfs(const unsigned int xid, struct cifs_tcon *tcon, + struct kstatfs *buf) +{ + 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; + + if (!tcon->posix_extensions) + return smb2_queryfs(xid, tcon, buf); + + 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, NULL); + if (rc) + return rc; + + rc = SMB311_posix_qfs_info(xid, tcon, fid.persistent_fid, + fid.volatile_fid, buf); + buf->f_type = SMB2_MAGIC_NUMBER; + SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); + return rc; +} + static bool smb2_compare_fids(struct cifsFileInfo *ob1, struct cifsFileInfo *ob2) { @@ -3337,7 +3368,7 @@ struct smb_version_operations smb311_operations = { .is_status_pending = smb2_is_status_pending, .is_session_expired = smb2_is_session_expired, .oplock_response = smb2_oplock_response, - .queryfs = smb2_queryfs, + .queryfs = smb311_queryfs, .mand_lock = smb2_mand_lock, .mand_unlock_range = smb2_unlock_range, .push_mand_locks = smb2_push_mandatory_locks, diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 062a2a59beb3..619899903bd3 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -3928,6 +3928,35 @@ copy_fs_info_to_kstatfs(struct smb2_fs_full_size_info *pfs_inf, return; } +static void +copy_posix_fs_info_to_kstatfs(FILE_SYSTEM_POSIX_INFO *response_data, + struct kstatfs *kst) +{ + kst->f_bsize = le32_to_cpu(response_data->BlockSize); + kst->f_blocks = le64_to_cpu(response_data->TotalBlocks); + kst->f_bfree = le64_to_cpu(response_data->BlocksAvail); + if (response_data->UserBlocksAvail == cpu_to_le64(-1)) + kst->f_bavail = kst->f_bfree; + else + kst->f_bavail = le64_to_cpu(response_data->UserBlocksAvail); + if (response_data->TotalFileNodes != cpu_to_le64(-1)) + kst->f_files = le64_to_cpu(response_data->TotalFileNodes); + if (response_data->FreeFileNodes != cpu_to_le64(-1)) + kst->f_ffree = le64_to_cpu(response_data->FreeFileNodes); + kst->f_bsize = le32_to_cpu(response_data->BlockSize); + kst->f_blocks = le64_to_cpu(response_data->TotalBlocks); + kst->f_bfree = le64_to_cpu(response_data->BlocksAvail); + if (response_data->UserBlocksAvail == cpu_to_le64(-1)) + kst->f_bavail = kst->f_bfree; + else + kst->f_bavail = le64_to_cpu(response_data->UserBlocksAvail); + if (response_data->TotalFileNodes != cpu_to_le64(-1)) + kst->f_files = le64_to_cpu(response_data->TotalFileNodes); + if (response_data->FreeFileNodes != cpu_to_le64(-1)) + kst->f_ffree = le64_to_cpu(response_data->FreeFileNodes); + return; +} + static int build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon, int level, int outbuf_len, u64 persistent_fid, u64 volatile_fid) @@ -3964,6 +3993,54 @@ build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon, int level, return 0; } +int +SMB311_posix_qfs_info(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_fid, u64 volatile_fid, struct kstatfs *fsdata) +{ + struct smb_rqst rqst; + struct smb2_query_info_rsp *rsp = NULL; + struct kvec iov; + struct kvec rsp_iov; + int rc = 0; + int resp_buftype; + struct cifs_ses *ses = tcon->ses; + FILE_SYSTEM_POSIX_INFO *info = NULL; + int flags = 0; + + rc = build_qfs_info_req(&iov, tcon, FS_POSIX_INFORMATION, + sizeof(FILE_SYSTEM_POSIX_INFO), + persistent_fid, volatile_fid); + if (rc) + return rc; + + if (smb3_encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + + memset(&rqst, 0, sizeof(struct smb_rqst)); + rqst.rq_iov = &iov; + rqst.rq_nvec = 1; + + rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); + cifs_small_buf_release(iov.iov_base); + if (rc) { + cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); + goto posix_qfsinf_exit; + } + rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base; + + info = (FILE_SYSTEM_POSIX_INFO *)( + le16_to_cpu(rsp->OutputBufferOffset) + (char *)rsp); + rc = validate_iov(le16_to_cpu(rsp->OutputBufferOffset), + le32_to_cpu(rsp->OutputBufferLength), &rsp_iov, + sizeof(FILE_SYSTEM_POSIX_INFO)); + if (!rc) + copy_posix_fs_info_to_kstatfs(info, fsdata); + +posix_qfsinf_exit: + free_rsp_buf(resp_buftype, rsp_iov.iov_base); + return rc; +} + int SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, u64 volatile_fid, struct kstatfs *fsdata) diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index 824dddeee3f2..eea20d79496d 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h @@ -1225,6 +1225,7 @@ struct smb2_lease_ack { #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 */ +#define FS_POSIX_INFORMATION 100 /* SMB3.1.1 POSIx. Query */ struct smb2_fs_full_size_info { __le64 TotalAllocationUnits; diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index 3ae208ac2a77..4cf77fec61a9 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h @@ -197,6 +197,9 @@ void smb2_cancelled_close_fid(struct work_struct *work); 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 SMB311_posix_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, int lvl); extern int SMB2_lock(const unsigned int xid, struct cifs_tcon *tcon, -- 2.17.1