From patchwork Mon Oct 14 02:19:02 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve French X-Patchwork-Id: 3034161 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 EEB7FBF924 for ; Mon, 14 Oct 2013 02:19:07 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 17D402015B for ; Mon, 14 Oct 2013 02:19:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9B2A12011B for ; Mon, 14 Oct 2013 02:19:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755672Ab3JNCTF (ORCPT ); Sun, 13 Oct 2013 22:19:05 -0400 Received: from mail-pa0-f50.google.com ([209.85.220.50]:59915 "EHLO mail-pa0-f50.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755611Ab3JNCTE (ORCPT ); Sun, 13 Oct 2013 22:19:04 -0400 Received: by mail-pa0-f50.google.com with SMTP id fb1so6930151pad.37 for ; Sun, 13 Oct 2013 19:19:03 -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=bTEVLjL+SXy12r9nu1+QwyDn2e3fFWoaDza1xzulxEQ=; b=DqaVE4wfwvv5lCNGudv/+Yqs13EFp9cDdAEU6usCX0foXKDZjxMh46RTgPSQySDzho KwTSfbl6pbjjr9HttdS5mNaAITRyEdia191UqOVABAiS+8leemtzP5sIwR0pJdFfc+Xk PeDwZr7J7riNU2Br5/KCdsKhs36qvGbL3ng1FndZw+foXewsRDSjZpb6QjpR3MhyV/Nw ZLEmY2YR+t+7JjpTKBRCOAklfciu/Mu8HLcQmluXCJCpCls+wXz+gKl1CYi1UrSkopS7 BpONU83vzrL7oHfiKOPizR3quRR0BynKCr68n3ih977jjkVhbi6yT4LcGGoScKuwVy9s lDjQ== MIME-Version: 1.0 X-Received: by 10.67.1.228 with SMTP id bj4mr244082pad.157.1381717142948; Sun, 13 Oct 2013 19:19:02 -0700 (PDT) Received: by 10.68.143.10 with HTTP; Sun, 13 Oct 2013 19:19:02 -0700 (PDT) Date: Sun, 13 Oct 2013 21:19:02 -0500 Message-ID: Subject: [PATCH] [CIFS] Allow setting per-file compression via CIFS protocol From: Steve French To: "linux-cifs@vger.kernel.org" , samba-technical , "Stefan (metze) Metzmacher" 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.3 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 An earlier patch allowed setting the per-file compression flag "chattr +c filename" on an smb2 or smb3 mount, and also allowed lsattr to return whether a file on a cifs, or smb2/smb3 mount was compressed. As suggested by Metze, this patch extends the ability to set the per-file compression flag to the cifs protocol, which uses a somewhat different IOCTL mechanism than SMB2, although the payload (the flags stored in the compression_state) are the same. Signed-off-by: Steve French --- fs/cifs/cifspdu.h | 24 ++++++++++++++++++++++++ fs/cifs/cifsproto.h | 2 ++ fs/cifs/cifssmb.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/cifs/smb1ops.c | 8 ++++++++ 4 files changed, 87 insertions(+) diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index d40bd77..d963429 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -1352,6 +1352,30 @@ typedef struct smb_com_transaction_ioctl_req { __u8 Data[1]; } __attribute__((packed)) TRANSACT_IOCTL_REQ; +typedef struct smb_com_transaction_compr_ioctl_req { + struct smb_hdr hdr; /* wct = 23 */ + __u8 MaxSetupCount; + __u16 Reserved; + __le32 TotalParameterCount; + __le32 TotalDataCount; + __le32 MaxParameterCount; + __le32 MaxDataCount; + __le32 ParameterCount; + __le32 ParameterOffset; + __le32 DataCount; + __le32 DataOffset; + __u8 SetupCount; /* four setup words follow subcommand */ + /* SNIA spec incorrectly included spurious pad here */ + __le16 SubCommand; /* 2 = IOCTL/FSCTL */ + __le32 FunctionCode; + __u16 Fid; + __u8 IsFsctl; /* 1 = File System Control 0 = device control (IOCTL) */ + __u8 IsRootFlag; /* 1 = apply command to root of share (must be DFS) */ + __le16 ByteCount; + __u8 Pad[3]; + __le16 compression_state; /* See similar SMB2 IOCTL for valid flags */ +} __attribute__((packed)) TRANSACT_COMPR_IOCTL_REQ; + typedef struct smb_com_transaction_ioctl_rsp { struct smb_hdr hdr; /* wct = 19 */ __u8 Reserved[3]; diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index b5ec2a2..aa33976 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -360,6 +360,8 @@ extern int CIFSSMBUnixQuerySymLink(const unsigned int xid, extern int CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, char **symlinkinfo, const struct nls_table *nls_codepage); +extern int CIFSSMB_set_compression(const unsigned int xid, + struct cifs_tcon *tcon, __u16 fid); extern int CIFSSMBOpen(const unsigned int xid, struct cifs_tcon *tcon, const char *fileName, const int disposition, const int access_flags, const int omode, diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index ccd31ab..ec57dde 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -3199,6 +3199,59 @@ qreparse_out: return rc; } +int +CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon, + __u16 fid) +{ + int rc = 0; + int bytes_returned; + struct smb_com_transaction_compr_ioctl_req *pSMB; + struct smb_com_transaction_ioctl_rsp *pSMBr; + + cifs_dbg(FYI, "Set compression for %u\n", fid); + rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB, + (void **) &pSMBr); + if (rc) + return rc; + + pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT); + + pSMB->TotalParameterCount = 0; + pSMB->TotalDataCount = cpu_to_le32(2); + pSMB->MaxParameterCount = 0; + pSMB->MaxDataCount = 0; + pSMB->MaxSetupCount = 4; + pSMB->Reserved = 0; + pSMB->ParameterOffset = 0; + pSMB->DataCount = cpu_to_le32(2); + pSMB->DataOffset = + cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req, + compression_state) - 4); /* 84 */ + pSMB->SetupCount = 4; + pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL); + pSMB->ParameterCount = 0; + pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION); + pSMB->IsFsctl = 1; /* FSCTL */ + pSMB->IsRootFlag = 0; + pSMB->Fid = fid; /* file handle always le */ + pSMB->ByteCount = cpu_to_le16(5); /* 3 byte pad 2 byte compress state */ + inc_rfc1001_len(pSMB, 5); + + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + (struct smb_hdr *) pSMBr, &bytes_returned, 0); + if (rc) + cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc); + + cifs_buf_release(pSMB); + + /* + * Note: On -EAGAIN error only caller can retry on handle based calls + * since file handle passed in no longer valid. + */ + return rc; +} + + #ifdef CONFIG_CIFS_POSIX /*Convert an Access Control Entry from wire format to local POSIX xattr format*/ diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index 8233b17..ea99efe 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c @@ -807,6 +807,13 @@ out: } static int +cifs_set_compression(const unsigned int xid, struct cifs_tcon *tcon, + struct cifsFileInfo *cfile) +{ + return CIFSSMB_set_compression(xid, tcon, cfile->fid.netfid); +} + +static int cifs_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon, const char *path, struct cifs_sb_info *cifs_sb, struct cifs_fid *fid, __u16 search_flags, @@ -956,6 +963,7 @@ struct smb_version_operations smb1_operations = { .set_path_size = CIFSSMBSetEOF, .set_file_size = CIFSSMBSetFileSize, .set_file_info = smb_set_file_info, + .set_compression = cifs_set_compression, .echo = CIFSSMBEcho, .mkdir = CIFSSMBMkDir, .mkdir_setinfo = cifs_mkdir_setinfo,