From patchwork Mon Sep 3 06:57:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ronnie Sahlberg X-Patchwork-Id: 10585507 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1771D13BB for ; Mon, 3 Sep 2018 06:57:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0BB00292A4 for ; Mon, 3 Sep 2018 06:57:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F2FEB292D6; Mon, 3 Sep 2018 06:57:44 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 83552292A4 for ; Mon, 3 Sep 2018 06:57:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725947AbeICLQ3 (ORCPT ); Mon, 3 Sep 2018 07:16:29 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:52376 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1725927AbeICLQ3 (ORCPT ); Mon, 3 Sep 2018 07:16:29 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3EA1A40216E5; Mon, 3 Sep 2018 06:57:42 +0000 (UTC) Received: from test1135.test.redhat.com (vpn2-54-85.bne.redhat.com [10.64.54.85]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4EE4A1055535; Mon, 3 Sep 2018 06:57:40 +0000 (UTC) From: Ronnie Sahlberg To: linux-cifs Cc: Steve French Subject: [PATCH] cifs: add ioctl for SRV_COPYCHUNK range Date: Mon, 3 Sep 2018 16:57:33 +1000 Message-Id: <20180903065733.28037-1-lsahlber@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Mon, 03 Sep 2018 06:57:42 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Mon, 03 Sep 2018 06:57:42 +0000 (UTC) for IP:'10.11.54.3' DOMAIN:'int-mx03.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'lsahlber@redhat.com' RCPT:'' Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add a new ioctl for COPYCHUNK that copies a region. The existing COPYCHUNK can only be used to copy a whole file. Signed-off-by: Ronnie Sahlberg Signed-off-by: Ronnie Sahlberg --- fs/cifs/cifs_ioctl.h | 8 ++++++++ fs/cifs/ioctl.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/fs/cifs/cifs_ioctl.h b/fs/cifs/cifs_ioctl.h index 57ff0756e30c..b40b9b608dde 100644 --- a/fs/cifs/cifs_ioctl.h +++ b/fs/cifs/cifs_ioctl.h @@ -43,8 +43,16 @@ struct smb_snapshot_array { /* snapshots[]; */ } __packed; +struct smb_srv_copychunk { + __u32 src_fd; + __u32 length; + __u64 src_offset; + __u64 dst_offset; +} __packed; + #define CIFS_IOCTL_MAGIC 0xCF #define CIFS_IOC_COPYCHUNK_FILE _IOW(CIFS_IOCTL_MAGIC, 3, int) #define CIFS_IOC_SET_INTEGRITY _IO(CIFS_IOCTL_MAGIC, 4) #define CIFS_IOC_GET_MNT_INFO _IOR(CIFS_IOCTL_MAGIC, 5, struct smb_mnt_fs_info) #define CIFS_ENUMERATE_SNAPSHOTS _IOR(CIFS_IOCTL_MAGIC, 6, struct smb_snapshot_array) +#define CIFS_IOC_COPYCHUNK _IOW(CIFS_IOCTL_MAGIC, 7, struct smb_srv_copychunk) diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index 54f32f9143a9..91f87ea01be0 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c @@ -34,14 +34,13 @@ #include "cifs_ioctl.h" #include -static long cifs_ioctl_copychunk(unsigned int xid, struct file *dst_file, - unsigned long srcfd) +static long _cifs_ioctl_copychunk(unsigned int xid, struct file *dst_file, + struct smb_srv_copychunk *cc) { int rc; struct fd src_file; struct inode *src_inode; - cifs_dbg(FYI, "ioctl copychunk range\n"); /* the destination must be opened for writing */ if (!(dst_file->f_mode & FMODE_WRITE)) { cifs_dbg(FYI, "file target not open for write\n"); @@ -55,7 +54,7 @@ static long cifs_ioctl_copychunk(unsigned int xid, struct file *dst_file, return rc; } - src_file = fdget(srcfd); + src_file = fdget(cc->src_fd); if (!src_file.file) { rc = -EBADF; goto out_drop_write; @@ -72,8 +71,9 @@ static long cifs_ioctl_copychunk(unsigned int xid, struct file *dst_file, if (S_ISDIR(src_inode->i_mode)) goto out_fput; - rc = cifs_file_copychunk_range(xid, src_file.file, 0, dst_file, 0, - src_inode->i_size, 0); + rc = cifs_file_copychunk_range(xid, src_file.file, cc->src_offset, + dst_file, cc->dst_offset, + cc->length, 0); if (rc > 0) rc = 0; out_fput: @@ -83,6 +83,44 @@ static long cifs_ioctl_copychunk(unsigned int xid, struct file *dst_file, return rc; } +static long cifs_ioctl_copychunk(unsigned int xid, struct file *dst_file, + unsigned long p) +{ + void __user *arg = (void __user *)p; + struct smb_srv_copychunk cc; + + cifs_dbg(FYI, "ioctl copychunk range\n"); + + if (copy_from_user(&cc, arg, sizeof(cc))) + return -EFAULT; + + return _cifs_ioctl_copychunk(xid, dst_file, &cc); +} + +static long cifs_ioctl_copychunk_file(unsigned int xid, struct file *dst_file, + unsigned long srcfd) +{ + struct smb_srv_copychunk cc; + struct fd src_file; + struct inode *src_inode; + + cifs_dbg(FYI, "ioctl copychunk file\n"); + + src_file = fdget(srcfd); + if (!src_file.file) { + mnt_drop_write_file(dst_file); + return -EBADF; + } + src_inode = file_inode(src_file.file); + + memset(&cc, 0, sizeof(struct smb_srv_copychunk)); + cc.src_fd = srcfd; + cc.length = src_inode->i_size; + fdput(src_file); + + return _cifs_ioctl_copychunk(xid, dst_file, &cc); +} + static long smb_mnt_get_fsinfo(unsigned int xid, struct cifs_tcon *tcon, void __user *arg) { @@ -194,6 +232,9 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) } break; case CIFS_IOC_COPYCHUNK_FILE: + rc = cifs_ioctl_copychunk_file(xid, filep, arg); + break; + case CIFS_IOC_COPYCHUNK: rc = cifs_ioctl_copychunk(xid, filep, arg); break; case CIFS_IOC_SET_INTEGRITY: