From patchwork Fri Jul 19 21:03:46 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan Schumaker X-Patchwork-Id: 2830698 Return-Path: X-Original-To: patchwork-linux-nfs@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 68468C0319 for ; Fri, 19 Jul 2013 21:03:59 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7E5692030D for ; Fri, 19 Jul 2013 21:03:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 928192030A for ; Fri, 19 Jul 2013 21:03:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752339Ab3GSVDy (ORCPT ); Fri, 19 Jul 2013 17:03:54 -0400 Received: from mx12.netapp.com ([216.240.18.77]:10414 "EHLO mx12.netapp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752316Ab3GSVDy (ORCPT ); Fri, 19 Jul 2013 17:03:54 -0400 X-IronPort-AV: E=Sophos;i="4.89,704,1367996400"; d="scan'208";a="74608543" Received: from vmwexceht04-prd.hq.netapp.com ([10.106.77.34]) by mx12-out.netapp.com with ESMTP; 19 Jul 2013 14:03:53 -0700 Received: from smtp1.corp.netapp.com (10.57.156.124) by VMWEXCEHT04-PRD.hq.netapp.com (10.106.77.34) with Microsoft SMTP Server id 14.3.123.3; Fri, 19 Jul 2013 14:03:53 -0700 Received: from davros.hq.netapp.com (davros.vpn.netapp.com [10.63.226.147]) by smtp1.corp.netapp.com (8.13.1/8.13.1/NTAP-1.6) with ESMTP id r6JL3peR024405; Fri, 19 Jul 2013 14:03:52 -0700 (PDT) From: To: CC: Subject: [RFC 1/5] Improve on the copyfile systemcall Date: Fri, 19 Jul 2013 17:03:46 -0400 Message-ID: <1374267830-30154-2-git-send-email-bjschuma@netapp.com> X-Mailer: git-send-email 1.8.3.3 In-Reply-To: <1374267830-30154-1-git-send-email-bjschuma@netapp.com> References: <1374267830-30154-1-git-send-email-bjschuma@netapp.com> MIME-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Spam-Status: No, score=-7.3 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable 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 From: Bryan Schumaker I added in a fallback to do_splice_direct() if the filesystem doesn't support the copy_range call. This is because the declaration of do_splice_direct() is now found in fs/internal.h and can't be used by other filesystems. I also had to add sys_copy_range to include/linux/syscalls.h to get my test program to recognize the new syscall. Other thoughts: - Pass count = 0 to mean "copy the entire file" - rw_verify_area() limits count to values that can fit in an int, so files larger than about 2GB cannot be copied. --- fs/copy_range.c | 10 +++++++--- include/linux/syscalls.h | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/copy_range.c b/fs/copy_range.c index 3000b9f..bcf6e67 100644 --- a/fs/copy_range.c +++ b/fs/copy_range.c @@ -10,6 +10,8 @@ #include #include +#include "internal.h" + /** * vfs_copy_range - copy range of bytes from source file to existing file * @file_in: source regular file @@ -52,7 +54,7 @@ ssize_t vfs_copy_range(struct file *file_in, loff_t pos_in, if (!(file_in->f_mode & FMODE_READ) || !(file_out->f_mode & FMODE_WRITE) || (file_out->f_flags & O_APPEND) || - !file_in->f_op || !file_in->f_op->copy_range) + !file_in->f_op) return -EINVAL; inode_in = file_inode(file_in); @@ -82,8 +84,10 @@ ssize_t vfs_copy_range(struct file *file_in, loff_t pos_in, if (ret) return ret; - ret = file_in->f_op->copy_range(file_in, pos_in, file_out, pos_out, - count); + if (file_in->f_op->copy_range) + ret = file_in->f_op->copy_range(file_in, pos_in, file_out, pos_out, count); + else + ret = do_splice_direct(file_in, &pos_in, file_out, &pos_out, count, 0); if (ret > 0) { fsnotify_access(file_in); add_rchar(current, ret); diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 4147d70..5afcd00 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -485,6 +485,7 @@ asmlinkage long sys_sendfile(int out_fd, int in_fd, off_t __user *offset, size_t count); asmlinkage long sys_sendfile64(int out_fd, int in_fd, loff_t __user *offset, size_t count); +asmlinkage long sys_copy_range(int, loff_t __user *, int, loff_t __user *, size_t); asmlinkage long sys_readlink(const char __user *path, char __user *buf, int bufsiz); asmlinkage long sys_creat(const char __user *pathname, umode_t mode);