From patchwork Sun May 26 06:10:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 10961389 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 EFC96912 for ; Sun, 26 May 2019 06:11:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E111E28A9B for ; Sun, 26 May 2019 06:11:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D598228AA7; Sun, 26 May 2019 06:11:47 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable 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 7C88728A9D for ; Sun, 26 May 2019 06:11:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727546AbfEZGLR (ORCPT ); Sun, 26 May 2019 02:11:17 -0400 Received: from mail-wr1-f68.google.com ([209.85.221.68]:40298 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726348AbfEZGLQ (ORCPT ); Sun, 26 May 2019 02:11:16 -0400 Received: by mail-wr1-f68.google.com with SMTP id t4so5380455wrx.7; Sat, 25 May 2019 23:11:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Klup2ajGNBsp1TUMEpHqQz9uQmHS/z24EFpQImKvOv4=; b=FDeYszfeH4Irc3xuyB+DqAbgZCUORXlYjeZn4d7Y+tjUjlMnUG7XrDqSrTZUrwQYr3 HFXa66Ce9IC0PekcO5UqvVVDiSYzcw2JaEcP94AmPKyBiWGg+t9uwIO3TpXrm9oFIe9y v8MHRb4sPJtNRBC25ZF5LOI0b5yZynVVVbNKG+5mJ2HO0brXaXLAEFWkkA53qSxnxYIU BC6E9EPB9MUz8zYBj71/eHXUsSdbEPXA2VThNzE0n8xlc6kdGXwwYzrzIBrz9A3R2Ee+ AhyNqQV85kboZpQkZ2LL8ZNN4C1I+jmLzc7PrdM/cwmP2Af2CwHmv+UPSJI0oKBjV8KE UrYA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Klup2ajGNBsp1TUMEpHqQz9uQmHS/z24EFpQImKvOv4=; b=pZEhK6GtVmtfeUb7fC153h7kvDi2Fdlmo5Zdufp/RY2Aw/7QUPQ6vrgbDa0YMu5FCQ m4BdxcU69EIkJCzpE0yPfEZMwKK2KNJx+4+jnsvxgPPaDhMqdb30IMg+GimbRSaM0yKH IUyVHZPLbF6e8G0mS4yJp9f1jnXiNpJPjpxk9NX7TK0bQlgCtI+RM9C9ADtvFJQppbf5 kNavz8+JzQ7ay35ISYhvZRE5EINTgNXWc62bOO98/J/JU96O61MwYNqp36YTIUbHaZK7 pdco5737yyOsASSvmoZ2ovmNr77WiEyaYrz1binTM/cOnbRNvCPmxxoJUg6Mon8jG+yQ 7F9g== X-Gm-Message-State: APjAAAUtpSmqqNcCisKuozzQ4w/RIAAhcCYtCnJo2TArHC8FqC7VZD81 sdloiOARDa0W++VJrKD4EJA= X-Google-Smtp-Source: APXvYqyMcIanlzcPtZWca9ywK7oPKEU2lKGbCtF54UJy4mwvocGQBow4pd9xtQeuKSQI2GWlTcH24A== X-Received: by 2002:adf:ed44:: with SMTP id u4mr9097074wro.242.1558851073736; Sat, 25 May 2019 23:11:13 -0700 (PDT) Received: from localhost.localdomain ([5.102.238.208]) by smtp.gmail.com with ESMTPSA id a124sm5302943wmh.3.2019.05.25.23.11.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 25 May 2019 23:11:13 -0700 (PDT) From: Amir Goldstein To: "Darrick J . Wong" Cc: Dave Chinner , Christoph Hellwig , Olga Kornievskaia , Luis Henriques , Al Viro , linux-fsdevel@vger.kernel.org, linux-xfs@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, linux-api@vger.kernel.org, Dave Chinner Subject: [PATCH v2 1/8] vfs: introduce generic_copy_file_range() Date: Sun, 26 May 2019 09:10:52 +0300 Message-Id: <20190526061100.21761-2-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190526061100.21761-1-amir73il@gmail.com> References: <20190526061100.21761-1-amir73il@gmail.com> 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 From: Dave Chinner Right now if vfs_copy_file_range() does not use any offload mechanism, it falls back to calling do_splice_direct(). This fails to do basic sanity checks on the files being copied. Before we start adding this necessarily functionality to the fallback path, separate it out into generic_copy_file_range(). generic_copy_file_range() has the same prototype as ->copy_file_range() so that filesystems can use it in their custom ->copy_file_range() method if they so choose. Signed-off-by: Dave Chinner Signed-off-by: Amir Goldstein Reviewed-by: Darrick J. Wong --- fs/read_write.c | 35 ++++++++++++++++++++++++++++++++--- include/linux/fs.h | 3 +++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/fs/read_write.c b/fs/read_write.c index c543d965e288..676b02fae589 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -1565,6 +1565,36 @@ COMPAT_SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd, } #endif +/** + * generic_copy_file_range - copy data between two files + * @file_in: file structure to read from + * @pos_in: file offset to read from + * @file_out: file structure to write data to + * @pos_out: file offset to write data to + * @len: amount of data to copy + * @flags: copy flags + * + * This is a generic filesystem helper to copy data from one file to another. + * It has no constraints on the source or destination file owners - the files + * can belong to different superblocks and different filesystem types. Short + * copies are allowed. + * + * This should be called from the @file_out filesystem, as per the + * ->copy_file_range() method. + * + * Returns the number of bytes copied or a negative error indicating the + * failure. + */ + +ssize_t generic_copy_file_range(struct file *file_in, loff_t pos_in, + struct file *file_out, loff_t pos_out, + size_t len, unsigned int flags) +{ + return do_splice_direct(file_in, &pos_in, file_out, &pos_out, + len > MAX_RW_COUNT ? MAX_RW_COUNT : len, 0); +} +EXPORT_SYMBOL(generic_copy_file_range); + /* * copy_file_range() differs from regular file read and write in that it * specifically allows return partial success. When it does so is up to @@ -1632,9 +1662,8 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in, goto done; } - ret = do_splice_direct(file_in, &pos_in, file_out, &pos_out, - len > MAX_RW_COUNT ? MAX_RW_COUNT : len, 0); - + ret = generic_copy_file_range(file_in, pos_in, file_out, pos_out, len, + flags); done: if (ret > 0) { fsnotify_access(file_in); diff --git a/include/linux/fs.h b/include/linux/fs.h index f7fdfe93e25d..ea17858310ff 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1889,6 +1889,9 @@ extern ssize_t vfs_readv(struct file *, const struct iovec __user *, unsigned long, loff_t *, rwf_t); extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *, loff_t, size_t, unsigned int); +extern ssize_t generic_copy_file_range(struct file *file_in, loff_t pos_in, + struct file *file_out, loff_t pos_out, + size_t len, unsigned int flags); extern int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in, struct file *file_out, loff_t pos_out, loff_t *count, From patchwork Sun May 26 06:10:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 10961335 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 BC2191880 for ; Sun, 26 May 2019 06:11:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ACBED28A9B for ; Sun, 26 May 2019 06:11:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A170328AA0; Sun, 26 May 2019 06:11:26 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable 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 A80B828AAA for ; Sun, 26 May 2019 06:11:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727607AbfEZGLS (ORCPT ); Sun, 26 May 2019 02:11:18 -0400 Received: from mail-wr1-f67.google.com ([209.85.221.67]:39172 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726131AbfEZGLS (ORCPT ); Sun, 26 May 2019 02:11:18 -0400 Received: by mail-wr1-f67.google.com with SMTP id e2so4888465wrv.6; Sat, 25 May 2019 23:11:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=jgXNJIA/nufnSnu4+ud/rPiS77zTsD8AMGRWTfgrrqI=; b=qZUVMDlLTY5u48xqKNt2w8xJCocDSQbQTiZpComnmGilfzawivtwGXUU3h9ENBawCi v9IO2altJLQZSSvTAYMD6KlL/uPXq+bNFosUyAhXpNGgBp2usMGu6bklaSO5c1eRheq2 wQhaEo6jbwDgC+SBq4e+WLKrXUetgCTslUeKJrquC7i5u85YS9nrkXN+QH2wd12DMK5d ltOWV0AMfKHGWKhDn/SOOSAL8IQuMr3fZHH9im1KiYyzZH+9dtb6tH7w41jgfjLSOOEz Kjj3iFQP/6GfWPlckFwHUJrTFh2Snj2KU6Fn5wYAy/esVDztvqHrcw5mzCfGgvjciFyJ U5LQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=jgXNJIA/nufnSnu4+ud/rPiS77zTsD8AMGRWTfgrrqI=; b=LKik462Ay4N+azunjrAXm7xGrdY5A85h3zqV2WDeWJXpMIn6FZU+SCY+YpAmjqClLp YlDICDgQPNIqEbzKj+JN34p/Qa4Isfl6e/YHeRLZLQwzlE6y8e4yN18BlMCLRuBVGAy6 rGlwAakDBhyJsK2A27IHRuxTAcfrcT4B1sH2WrVwydD06Gu0VHpJVKGOQzFb2yimbm0m eXjndP/dyLDiU7/2jsvRPoVayM7w8EyGSTZD+ms/ocltdsGfAkS0yTHgVebokC+96Opa GS031k50wCHWivD3zH4pyaTAY6JdofPdK4oqzKlcDNAaqW/hhC/+hlmF3jvvuXrb71LA g+sw== X-Gm-Message-State: APjAAAWIEGTf14hpKbIUQgZYeHE3UIoCzTENypcRK41EFNMGhE9A2WPu 0W4doB8Mfz0NuYnaixE7irs= X-Google-Smtp-Source: APXvYqxBB82jF58w2www0dce/6FsyXzVsg1H1geXVnY2uwxAbw5pTgWOEPJAcKprd0J4DWnKAtngVA== X-Received: by 2002:adf:8023:: with SMTP id 32mr6413925wrk.18.1558851075589; Sat, 25 May 2019 23:11:15 -0700 (PDT) Received: from localhost.localdomain ([5.102.238.208]) by smtp.gmail.com with ESMTPSA id a124sm5302943wmh.3.2019.05.25.23.11.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 25 May 2019 23:11:15 -0700 (PDT) From: Amir Goldstein To: "Darrick J . Wong" Cc: Dave Chinner , Christoph Hellwig , Olga Kornievskaia , Luis Henriques , Al Viro , linux-fsdevel@vger.kernel.org, linux-xfs@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, linux-api@vger.kernel.org, Dave Chinner Subject: [PATCH v2 2/8] vfs: no fallback for ->copy_file_range Date: Sun, 26 May 2019 09:10:53 +0300 Message-Id: <20190526061100.21761-3-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190526061100.21761-1-amir73il@gmail.com> References: <20190526061100.21761-1-amir73il@gmail.com> 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 From: Dave Chinner Now that we have generic_copy_file_range(), remove it as a fallback case when offloads fail. This puts the responsibility for executing fallbacks on the filesystems that implement ->copy_file_range and allows us to add operational validity checks to generic_copy_file_range(). Rework vfs_copy_file_range() to call a new do_copy_file_range() helper to exceute the copying callout, and move calls to generic_file_copy_range() into filesystem methods where they currently return failures. [Amir] overlayfs is not responsible of executing the fallback. It is the responsibility of the underlying filesystem. Signed-off-by: Dave Chinner Signed-off-by: Amir Goldstein Reviewed-by: Darrick J. Wong --- fs/ceph/file.c | 21 ++++++++++++++++++--- fs/cifs/cifsfs.c | 4 ++++ fs/fuse/file.c | 21 ++++++++++++++++++--- fs/nfs/nfs4file.c | 20 +++++++++++++++++--- fs/read_write.c | 25 ++++++++++++++++--------- 5 files changed, 73 insertions(+), 18 deletions(-) diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 305daf043eb0..e87f7b2023af 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -1889,9 +1889,9 @@ static int is_file_size_ok(struct inode *src_inode, struct inode *dst_inode, return 0; } -static ssize_t ceph_copy_file_range(struct file *src_file, loff_t src_off, - struct file *dst_file, loff_t dst_off, - size_t len, unsigned int flags) +static ssize_t __ceph_copy_file_range(struct file *src_file, loff_t src_off, + struct file *dst_file, loff_t dst_off, + size_t len, unsigned int flags) { struct inode *src_inode = file_inode(src_file); struct inode *dst_inode = file_inode(dst_file); @@ -2100,6 +2100,21 @@ static ssize_t ceph_copy_file_range(struct file *src_file, loff_t src_off, return ret; } +static ssize_t ceph_copy_file_range(struct file *src_file, loff_t src_off, + struct file *dst_file, loff_t dst_off, + size_t len, unsigned int flags) +{ + ssize_t ret; + + ret = __ceph_copy_file_range(src_file, src_off, dst_file, dst_off, + len, flags); + + if (ret == -EOPNOTSUPP) + ret = generic_copy_file_range(src_file, src_off, dst_file, + dst_off, len, flags); + return ret; +} + const struct file_operations ceph_file_fops = { .open = ceph_open, .release = ceph_release, diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index f5fcd6360056..c65823270313 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -1148,6 +1148,10 @@ static ssize_t cifs_copy_file_range(struct file *src_file, loff_t off, rc = cifs_file_copychunk_range(xid, src_file, off, dst_file, destoff, len, flags); free_xid(xid); + + if (rc == -EOPNOTSUPP) + rc = generic_copy_file_range(src_file, off, dst_file, + destoff, len, flags); return rc; } diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 3959f08279e6..e03901ae729b 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -3097,9 +3097,9 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, return err; } -static ssize_t fuse_copy_file_range(struct file *file_in, loff_t pos_in, - struct file *file_out, loff_t pos_out, - size_t len, unsigned int flags) +static ssize_t __fuse_copy_file_range(struct file *file_in, loff_t pos_in, + struct file *file_out, loff_t pos_out, + size_t len, unsigned int flags) { struct fuse_file *ff_in = file_in->private_data; struct fuse_file *ff_out = file_out->private_data; @@ -3173,6 +3173,21 @@ static ssize_t fuse_copy_file_range(struct file *file_in, loff_t pos_in, return err; } +static ssize_t fuse_copy_file_range(struct file *src_file, loff_t src_off, + struct file *dst_file, loff_t dst_off, + size_t len, unsigned int flags) +{ + ssize_t ret; + + ret = __fuse_copy_file_range(src_file, src_off, dst_file, dst_off, + len, flags); + + if (ret == -EOPNOTSUPP) + ret = generic_copy_file_range(src_file, src_off, dst_file, + dst_off, len, flags); + return ret; +} + static const struct file_operations fuse_file_operations = { .llseek = fuse_file_llseek, .read_iter = fuse_file_read_iter, diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index cf42a8b939e3..4842f3ab3161 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -129,9 +129,9 @@ nfs4_file_flush(struct file *file, fl_owner_t id) } #ifdef CONFIG_NFS_V4_2 -static ssize_t nfs4_copy_file_range(struct file *file_in, loff_t pos_in, - struct file *file_out, loff_t pos_out, - size_t count, unsigned int flags) +static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in, + struct file *file_out, loff_t pos_out, + size_t count, unsigned int flags) { if (!nfs_server_capable(file_inode(file_out), NFS_CAP_COPY)) return -EOPNOTSUPP; @@ -140,6 +140,20 @@ static ssize_t nfs4_copy_file_range(struct file *file_in, loff_t pos_in, return nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count); } +static ssize_t nfs4_copy_file_range(struct file *file_in, loff_t pos_in, + struct file *file_out, loff_t pos_out, + size_t count, unsigned int flags) +{ + ssize_t ret; + + ret = __nfs4_copy_file_range(file_in, pos_in, file_out, pos_out, count, + flags); + if (ret == -EOPNOTSUPP) + ret = generic_copy_file_range(file_in, pos_in, file_out, + pos_out, count, flags); + return ret; +} + static loff_t nfs4_file_llseek(struct file *filep, loff_t offset, int whence) { loff_t ret; diff --git a/fs/read_write.c b/fs/read_write.c index 676b02fae589..b63dcb4e4fe9 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -1595,6 +1595,19 @@ ssize_t generic_copy_file_range(struct file *file_in, loff_t pos_in, } EXPORT_SYMBOL(generic_copy_file_range); +static ssize_t do_copy_file_range(struct file *file_in, loff_t pos_in, + struct file *file_out, loff_t pos_out, + size_t len, unsigned int flags) +{ + if (file_out->f_op->copy_file_range) + return file_out->f_op->copy_file_range(file_in, pos_in, + file_out, pos_out, + len, flags); + + return generic_copy_file_range(file_in, pos_in, file_out, pos_out, len, + flags); +} + /* * copy_file_range() differs from regular file read and write in that it * specifically allows return partial success. When it does so is up to @@ -1655,15 +1668,9 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in, } } - if (file_out->f_op->copy_file_range) { - ret = file_out->f_op->copy_file_range(file_in, pos_in, file_out, - pos_out, len, flags); - if (ret != -EOPNOTSUPP) - goto done; - } - - ret = generic_copy_file_range(file_in, pos_in, file_out, pos_out, len, - flags); + ret = do_copy_file_range(file_in, pos_in, file_out, pos_out, len, + flags); + WARN_ON_ONCE(ret == -EOPNOTSUPP); done: if (ret > 0) { fsnotify_access(file_in); From patchwork Sun May 26 06:10:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 10961313 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 96B481921 for ; Sun, 26 May 2019 06:11:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8439328AB8 for ; Sun, 26 May 2019 06:11:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 78B8728A9D; Sun, 26 May 2019 06:11:25 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable 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 133D028AAF for ; Sun, 26 May 2019 06:11:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727623AbfEZGLU (ORCPT ); Sun, 26 May 2019 02:11:20 -0400 Received: from mail-wr1-f67.google.com ([209.85.221.67]:44028 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726348AbfEZGLT (ORCPT ); Sun, 26 May 2019 02:11:19 -0400 Received: by mail-wr1-f67.google.com with SMTP id l17so5254301wrm.10; Sat, 25 May 2019 23:11:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=dh6NYvHDfeCra0hMJwF294oAaC7qsyBcur4kIgbRNEk=; b=SQmnIrJAyfm/WM8SeFVW6AythYAmq4t0pJiTL6QlOXStTTS5TOLrJVjl4U3LsaLZik ldsV0K3ZhgKPid3ZWhhT1TmXQEKOlfvQNfEifYLGLcr2y1eFcVl4+TaCh273xyRKr8T2 bQFUWZOkzsiQUB1ey2ENVev3UjlBODJEQkcoRPaKIKIJ+2ac4La11Uit01ngeqxHBOkL nfn4t37Mhm2oLTZ+QjUb4SmAgcWJ8YHx8rNbonX+3yjVDUBKiQEwdJItTh9q9CyJ1BhN JJi4rIFJAzKJPUBiR/wKrOJqI4nM8PXbPa0XyCjgs3pgidKMYxmZYfP031WwcehdZ96r yCsA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=dh6NYvHDfeCra0hMJwF294oAaC7qsyBcur4kIgbRNEk=; b=g1wcCZEdY22JfHIpLB7dGprCTur3cRJ0oe9yM5/nz+gulnK7J2nv7RSt0F0Hy50S66 RGTgZGwVwiSGkFiqRlnFdXYjqWiVMImh6Vg4JBdPgjx+uSGBgDA5t2Y2yc1lLixW/K8W POA8ZieW4kG2Q/Rubkupk5wYjWZHujLFnOGrhc3XWH+BUm4NrVLNcYusNskTfur2DYQY zGuaWf17i/VkcFdrA5rVa7NILp5c//Jdz+UBGqdBjXU7yHZk3Tf+2hSBgYqN3tfDWlS5 zCzv+YrQU/WGoCsrF8OGOj6YsP/ZmtstroGMBRCyZSXY5soPoL2XBj3NcoCxE+LX9QRR a4oA== X-Gm-Message-State: APjAAAW9pD7YIcZHi0GRdWiZvRVY2Q1K2P9dwuv9gDnpOOU+GCy7rqt4 P4+o0R2B6LT0gpQkuPzmi1c= X-Google-Smtp-Source: APXvYqz+luHf4urr3DGcHaQp4SwKfS/0Q8U0BnzJGTZtBr1n9gYknnidfMnuqeWr5nBjV1crTjqdfw== X-Received: by 2002:adf:c188:: with SMTP id x8mr6450128wre.256.1558851077351; Sat, 25 May 2019 23:11:17 -0700 (PDT) Received: from localhost.localdomain ([5.102.238.208]) by smtp.gmail.com with ESMTPSA id a124sm5302943wmh.3.2019.05.25.23.11.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 25 May 2019 23:11:16 -0700 (PDT) From: Amir Goldstein To: "Darrick J . Wong" Cc: Dave Chinner , Christoph Hellwig , Olga Kornievskaia , Luis Henriques , Al Viro , linux-fsdevel@vger.kernel.org, linux-xfs@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v2 3/8] vfs: introduce generic_file_rw_checks() Date: Sun, 26 May 2019 09:10:54 +0300 Message-Id: <20190526061100.21761-4-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190526061100.21761-1-amir73il@gmail.com> References: <20190526061100.21761-1-amir73il@gmail.com> 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 Factor out helper with some checks on in/out file that are common to clone_file_range and copy_file_range. Suggested-by: Darrick J. Wong Signed-off-by: Amir Goldstein Reviewed-by: Darrick J. Wong --- fs/read_write.c | 38 +++++++++++--------------------------- include/linux/fs.h | 1 + mm/filemap.c | 24 ++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 27 deletions(-) diff --git a/fs/read_write.c b/fs/read_write.c index b63dcb4e4fe9..f1900bdb3127 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -1617,17 +1617,18 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in, struct file *file_out, loff_t pos_out, size_t len, unsigned int flags) { - struct inode *inode_in = file_inode(file_in); - struct inode *inode_out = file_inode(file_out); ssize_t ret; if (flags != 0) return -EINVAL; - if (S_ISDIR(inode_in->i_mode) || S_ISDIR(inode_out->i_mode)) - return -EISDIR; - if (!S_ISREG(inode_in->i_mode) || !S_ISREG(inode_out->i_mode)) - return -EINVAL; + /* this could be relaxed once a method supports cross-fs copies */ + if (file_inode(file_in)->i_sb != file_inode(file_out)->i_sb) + return -EXDEV; + + ret = generic_file_rw_checks(file_in, file_out); + if (unlikely(ret)) + return ret; ret = rw_verify_area(READ, file_in, &pos_in, len); if (unlikely(ret)) @@ -1637,15 +1638,6 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in, if (unlikely(ret)) return ret; - if (!(file_in->f_mode & FMODE_READ) || - !(file_out->f_mode & FMODE_WRITE) || - (file_out->f_flags & O_APPEND)) - return -EBADF; - - /* this could be relaxed once a method supports cross-fs copies */ - if (inode_in->i_sb != inode_out->i_sb) - return -EXDEV; - if (len == 0) return 0; @@ -2013,29 +2005,21 @@ loff_t do_clone_file_range(struct file *file_in, loff_t pos_in, struct file *file_out, loff_t pos_out, loff_t len, unsigned int remap_flags) { - struct inode *inode_in = file_inode(file_in); - struct inode *inode_out = file_inode(file_out); loff_t ret; WARN_ON_ONCE(remap_flags & REMAP_FILE_DEDUP); - if (S_ISDIR(inode_in->i_mode) || S_ISDIR(inode_out->i_mode)) - return -EISDIR; - if (!S_ISREG(inode_in->i_mode) || !S_ISREG(inode_out->i_mode)) - return -EINVAL; - /* * FICLONE/FICLONERANGE ioctls enforce that src and dest files are on * the same mount. Practically, they only need to be on the same file * system. */ - if (inode_in->i_sb != inode_out->i_sb) + if (file_inode(file_in)->i_sb != file_inode(file_out)->i_sb) return -EXDEV; - if (!(file_in->f_mode & FMODE_READ) || - !(file_out->f_mode & FMODE_WRITE) || - (file_out->f_flags & O_APPEND)) - return -EBADF; + ret = generic_file_rw_checks(file_in, file_out); + if (ret < 0) + return ret; if (!file_in->f_op->remap_file_range) return -EOPNOTSUPP; diff --git a/include/linux/fs.h b/include/linux/fs.h index ea17858310ff..89b9b73eb581 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3049,6 +3049,7 @@ extern ssize_t generic_write_checks(struct kiocb *, struct iov_iter *); extern int generic_remap_checks(struct file *file_in, loff_t pos_in, struct file *file_out, loff_t pos_out, loff_t *count, unsigned int remap_flags); +extern int generic_file_rw_checks(struct file *file_in, struct file *file_out); extern ssize_t generic_file_read_iter(struct kiocb *, struct iov_iter *); extern ssize_t __generic_file_write_iter(struct kiocb *, struct iov_iter *); extern ssize_t generic_file_write_iter(struct kiocb *, struct iov_iter *); diff --git a/mm/filemap.c b/mm/filemap.c index c5af80c43d36..798aac92cd76 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -3040,6 +3040,30 @@ int generic_remap_checks(struct file *file_in, loff_t pos_in, return 0; } + +/* + * Performs common checks before doing a file copy/clone + * from @file_in to @file_out. + */ +int generic_file_rw_checks(struct file *file_in, struct file *file_out) +{ + struct inode *inode_in = file_inode(file_in); + struct inode *inode_out = file_inode(file_out); + + /* Don't copy dirs, pipes, sockets... */ + if (S_ISDIR(inode_in->i_mode) || S_ISDIR(inode_out->i_mode)) + return -EISDIR; + if (!S_ISREG(inode_in->i_mode) || !S_ISREG(inode_out->i_mode)) + return -EINVAL; + + if (!(file_in->f_mode & FMODE_READ) || + !(file_out->f_mode & FMODE_WRITE) || + (file_out->f_flags & O_APPEND)) + return -EBADF; + + return 0; +} + int pagecache_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata) From patchwork Sun May 26 06:10:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 10961319 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 CECB42D49 for ; Sun, 26 May 2019 06:11:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BEF0928AB1 for ; Sun, 26 May 2019 06:11:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B30A828AA0; Sun, 26 May 2019 06:11:25 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,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 720D328AB2 for ; Sun, 26 May 2019 06:11:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727638AbfEZGLX (ORCPT ); Sun, 26 May 2019 02:11:23 -0400 Received: from mail-wr1-f66.google.com ([209.85.221.66]:42593 "EHLO mail-wr1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726131AbfEZGLW (ORCPT ); Sun, 26 May 2019 02:11:22 -0400 Received: by mail-wr1-f66.google.com with SMTP id l2so13657630wrb.9; Sat, 25 May 2019 23:11:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=zqG9JMtX+vHNyprOzkAJ1KkCxnAmtf74H0q9YGZXDsU=; b=AFjDAiKMr1H2ehfKhZmqJsbwBIjdZzOOdzaRVpj/ndzbe9LmjxjQC+so8If5qVNq1v zC6ehnYK5A24p4T7NVImlQvGmSdeCmv4sAMUvvq1zrWJZ54O5fST3vkj2HwrtUykQJdp Riv0p0XmFgeP7JD872uTSSj5rg1x0fZ1xt2x7AyxK2fQfUXQJp1sHkDixbbWrLli4rpO /CGm05znGrQpEj8a7PXNian05T8qi4Y3q8vQNcYRTsjaRP42cl6zZyjogXHFMm/vsjF6 e1032Dhdez+RllJ/5zxuQWeA8tkDVqbb9s7E2MjRFcBCUGnJov2RPlE3mT+E0ADYtvpb v59A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=zqG9JMtX+vHNyprOzkAJ1KkCxnAmtf74H0q9YGZXDsU=; b=V0zXIBu5bAUuYualuDtC1cEhEloBTmfLRZG3/4nXYQgar/bdaJNTKgPQCiL33eCHJV 7qge8Y9NvZxMwrlE73H0usrZKiHpPy9GE0Q/cyVL0u+X2QVSuRNUuzzUn3SaBcazljn7 T8bA8HqBgkJ01xfXT/GAjIg8rT8X/HGP2zkLuGhNF1JozR4+CxItLxaj9urcuPh5auVW +8lr3XBMEb2Y5Ogjrhoge37hlxe/RKZu4O3djJxWLTIupU/QOwB5dZRbe/KuX5IwBXyN HpfK8WDj/8WltBO/Bv3bFX6r0aJuTho72VJoZcr7/fWKOmHUf074rFNMcKa5CH2m8HUL hhzw== X-Gm-Message-State: APjAAAWkvyEncHe16awwnXCYFV36uWo6BbwYg2mcuAmLuJQl0s90sx1C SIKxI1+l8uSIQ50LLLu7v3o= X-Google-Smtp-Source: APXvYqxKUzsiHW6Ri7Q/Xuo7SmX7yJv5pmo4Kz5II++OS4wFNt6PMaU/avaZ66pWprXimsWoRbOvuw== X-Received: by 2002:adf:dd43:: with SMTP id u3mr5312119wrm.313.1558851079405; Sat, 25 May 2019 23:11:19 -0700 (PDT) Received: from localhost.localdomain ([5.102.238.208]) by smtp.gmail.com with ESMTPSA id a124sm5302943wmh.3.2019.05.25.23.11.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 25 May 2019 23:11:18 -0700 (PDT) From: Amir Goldstein To: "Darrick J . Wong" Cc: Dave Chinner , Christoph Hellwig , Olga Kornievskaia , Luis Henriques , Al Viro , linux-fsdevel@vger.kernel.org, linux-xfs@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, linux-api@vger.kernel.org, Dave Chinner Subject: [PATCH v2 4/8] vfs: add missing checks to copy_file_range Date: Sun, 26 May 2019 09:10:55 +0300 Message-Id: <20190526061100.21761-5-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190526061100.21761-1-amir73il@gmail.com> References: <20190526061100.21761-1-amir73il@gmail.com> 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 Like the clone and dedupe interfaces we've recently fixed, the copy_file_range() implementation is missing basic sanity, limits and boundary condition tests on the parameters that are passed to it from userspace. Create a new "generic_copy_file_checks()" function modelled on the generic_remap_checks() function to provide this missing functionality. [Amir] Shorten copy length instead of checking pos_in limits because input file size already abides by the limits. Signed-off-by: Dave Chinner Signed-off-by: Amir Goldstein --- fs/read_write.c | 3 ++- include/linux/fs.h | 3 +++ mm/filemap.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/fs/read_write.c b/fs/read_write.c index f1900bdb3127..b0fb1176b628 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -1626,7 +1626,8 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in, if (file_inode(file_in)->i_sb != file_inode(file_out)->i_sb) return -EXDEV; - ret = generic_file_rw_checks(file_in, file_out); + ret = generic_copy_file_checks(file_in, pos_in, file_out, pos_out, &len, + flags); if (unlikely(ret)) return ret; diff --git a/include/linux/fs.h b/include/linux/fs.h index 89b9b73eb581..e4d382c4342a 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3050,6 +3050,9 @@ extern int generic_remap_checks(struct file *file_in, loff_t pos_in, struct file *file_out, loff_t pos_out, loff_t *count, unsigned int remap_flags); extern int generic_file_rw_checks(struct file *file_in, struct file *file_out); +extern int generic_copy_file_checks(struct file *file_in, loff_t pos_in, + struct file *file_out, loff_t pos_out, + size_t *count, unsigned int flags); extern ssize_t generic_file_read_iter(struct kiocb *, struct iov_iter *); extern ssize_t __generic_file_write_iter(struct kiocb *, struct iov_iter *); extern ssize_t generic_file_write_iter(struct kiocb *, struct iov_iter *); diff --git a/mm/filemap.c b/mm/filemap.c index 798aac92cd76..1852fbf08eeb 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -3064,6 +3064,59 @@ int generic_file_rw_checks(struct file *file_in, struct file *file_out) return 0; } +/* + * Performs necessary checks before doing a file copy + * + * Can adjust amount of bytes to copy + * Returns appropriate error code that caller should return or + * zero in case the copy should be allowed. + */ +int generic_copy_file_checks(struct file *file_in, loff_t pos_in, + struct file *file_out, loff_t pos_out, + size_t *req_count, unsigned int flags) +{ + struct inode *inode_in = file_inode(file_in); + struct inode *inode_out = file_inode(file_out); + uint64_t count = *req_count; + loff_t size_in; + int ret; + + ret = generic_file_rw_checks(file_in, file_out); + if (ret) + return ret; + + /* Don't touch certain kinds of inodes */ + if (IS_IMMUTABLE(inode_out)) + return -EPERM; + + if (IS_SWAPFILE(inode_in) || IS_SWAPFILE(inode_out)) + return -ETXTBSY; + + /* Ensure offsets don't wrap. */ + if (pos_in + count < pos_in || pos_out + count < pos_out) + return -EOVERFLOW; + + /* Shorten the copy to EOF */ + size_in = i_size_read(inode_in); + if (pos_in >= size_in) + count = 0; + else + count = min(count, size_in - (uint64_t)pos_in); + + ret = generic_write_check_limits(file_out, pos_out, &count); + if (ret) + return ret; + + /* Don't allow overlapped copying within the same file. */ + if (inode_in == inode_out && + pos_out + count > pos_in && + pos_out < pos_in + count) + return -EINVAL; + + *req_count = count; + return 0; +} + int pagecache_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata) From patchwork Sun May 26 06:10:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 10961383 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 A5E381390 for ; Sun, 26 May 2019 06:11:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9660A28A9B for ; Sun, 26 May 2019 06:11:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8A3D628AA0; Sun, 26 May 2019 06:11:43 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable 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 0898628A9B for ; Sun, 26 May 2019 06:11:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727671AbfEZGLY (ORCPT ); Sun, 26 May 2019 02:11:24 -0400 Received: from mail-wr1-f67.google.com ([209.85.221.67]:41862 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726348AbfEZGLX (ORCPT ); Sun, 26 May 2019 02:11:23 -0400 Received: by mail-wr1-f67.google.com with SMTP id u16so9758466wrn.8; Sat, 25 May 2019 23:11:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=hJpvGqVp0Vug8Mb9iaO6z9l1/zymJ1J3cdRetJYK7Bs=; b=IeDwTgfuxfRv8fbd84IwJcTY9Vp+VW76FKym3uEZDvVdCBni0KrbSiX7Dv0iZNVeVM Nb9l2O9jRVuhHy++ZVNB7UAskPKj3nJ63Q+GT0dVc6r1sJ+okcMB754x6aPrHxMAMvdO tBLNIh66tCfJoToi/6NXxvqF+P95e+j0FJXieWr+o7xfSo05WoOGNAUUX3HYqoAEjjvT yumMhT5vHLclYix4hqMDq8Qj/Emgq42jLLaWYbs6tV3RQjD/eMHD29CEu4Rte9w/KwAG /u24JEKv/lper0CQMYgsG3fxl62EEYpywonbw4QP4HBlNmglldpqpv3laVt/HBTaBvAq 7BsQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=hJpvGqVp0Vug8Mb9iaO6z9l1/zymJ1J3cdRetJYK7Bs=; b=NWgIjrCAvXrrGR1+56DSF9A3fUlvHrB2eIH5ZfVLpWhfmuTvjSa29NT4niDwMcozmk GAt2aHzI8gVasI2LO4XwsdLXzzgKtVsnEdmOF9k6At1OHyqAMwApTkMUrCft+UBszgO+ 1NOdJ/oMKz06GTGqy+hLiSylN4Pmr0DaJnGSP1TpDYR4AKD1vGWX+vcl+FJ2whYCL++1 6zUX4gsAWW2OqQwNxgWnDfaH/rJ2AoLvoTj5u1pGGFZsWQ3csIGXIj2rXZcvhTTLzun3 i1ojqDOVs9hTQJa+zyMSDgveVytuJfHnZAfZpeBriAVIrMFRLI7eTfSszTdcs8Ysn5vv kObA== X-Gm-Message-State: APjAAAX1i9V0iZAkD2gh04y69aMPkbUgEGAj7pp7xVILoW7ezNBA2QEO s5MzVYRNV5JVASkqp8Nijz0= X-Google-Smtp-Source: APXvYqwbq/jPIu7D1yhioAjiMprkENPZG1N9iFKs4h3m4EtO0EM6SfViM5nzs7W10hTmaWtq+O2qUg== X-Received: by 2002:adf:dc8e:: with SMTP id r14mr55228894wrj.121.1558851081412; Sat, 25 May 2019 23:11:21 -0700 (PDT) Received: from localhost.localdomain ([5.102.238.208]) by smtp.gmail.com with ESMTPSA id a124sm5302943wmh.3.2019.05.25.23.11.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 25 May 2019 23:11:20 -0700 (PDT) From: Amir Goldstein To: "Darrick J . Wong" Cc: Dave Chinner , Christoph Hellwig , Olga Kornievskaia , Luis Henriques , Al Viro , linux-fsdevel@vger.kernel.org, linux-xfs@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, linux-api@vger.kernel.org, Dave Chinner Subject: [PATCH v2 5/8] vfs: copy_file_range needs to strip setuid bits Date: Sun, 26 May 2019 09:10:56 +0300 Message-Id: <20190526061100.21761-6-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190526061100.21761-1-amir73il@gmail.com> References: <20190526061100.21761-1-amir73il@gmail.com> 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 The file we are copying data into needs to have its setuid bit stripped before we start the data copy so that unprivileged users can't copy data into executables that are run with root privs. [Amir] Introduce the helper generic_copy_file_range_prep() modelled after generic_remap_file_range_prep(). Helper is called by filesystem before the copy_file_range operation and with output inode locked. For ceph and for default generic_copy_file_range() implementation there is no inode lock held throughout the copy operation, so we do best effort and remove setuid bit before copy starts. This does not protect suid file from changing if suid bit is set after copy started. Signed-off-by: Dave Chinner Signed-off-by: Amir Goldstein --- fs/ceph/file.c | 9 +++++++++ fs/cifs/cifsfs.c | 9 ++++++--- fs/fuse/file.c | 4 ++++ fs/nfs/nfs42proc.c | 8 +++++--- fs/read_write.c | 31 +++++++++++++++++++++++++++++++ include/linux/fs.h | 2 ++ 6 files changed, 57 insertions(+), 6 deletions(-) diff --git a/fs/ceph/file.c b/fs/ceph/file.c index e87f7b2023af..54cfc877a6ef 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -1947,6 +1947,15 @@ static ssize_t __ceph_copy_file_range(struct file *src_file, loff_t src_off, goto out; } + /* Should inode lock be held throughout the copy operation? */ + inode_lock(dst_inode); + ret = generic_copy_file_range_prep(src_file, dst_file); + inode_unlock(dst_inode); + if (ret < 0) { + dout("failed to copy from src to dst file (%zd)\n", ret); + goto out; + } + /* * We need FILE_WR caps for dst_ci and FILE_RD for src_ci as other * clients may have dirty data in their caches. And OSDs know nothing diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index c65823270313..e103b499aaa8 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -1096,6 +1096,10 @@ ssize_t cifs_file_copychunk_range(unsigned int xid, goto out; } + rc = -EOPNOTSUPP; + if (!target_tcon->ses->server->ops->copychunk_range) + goto out; + /* * Note: cifs case is easier than btrfs since server responsible for * checks for proper open modes and file type and if it wants @@ -1107,11 +1111,10 @@ ssize_t cifs_file_copychunk_range(unsigned int xid, /* should we flush first and last page first */ truncate_inode_pages(&target_inode->i_data, 0); - if (target_tcon->ses->server->ops->copychunk_range) + rc = generic_copy_file_range_prep(src_file, dst_file); + if (!rc) rc = target_tcon->ses->server->ops->copychunk_range(xid, smb_file_src, smb_file_target, off, len, destoff); - else - rc = -EOPNOTSUPP; /* force revalidate of size and timestamps of target file now * that target is updated on the server diff --git a/fs/fuse/file.c b/fs/fuse/file.c index e03901ae729b..3531d4a3d9ec 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -3128,6 +3128,10 @@ static ssize_t __fuse_copy_file_range(struct file *file_in, loff_t pos_in, inode_lock(inode_out); + err = generic_copy_file_range_prep(file_in, file_out); + if (err) + goto out; + if (fc->writeback_cache) { err = filemap_write_and_wait_range(inode_out->i_mapping, pos_out, pos_out + len); diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index 5196bfa7894d..b387951e1d86 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c @@ -345,9 +345,11 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src, do { inode_lock(file_inode(dst)); - err = _nfs42_proc_copy(src, src_lock, - dst, dst_lock, - &args, &res); + err = generic_copy_file_range_prep(src, dst); + if (!err) + err = _nfs42_proc_copy(src, src_lock, + dst, dst_lock, + &args, &res); inode_unlock(file_inode(dst)); if (err >= 0) diff --git a/fs/read_write.c b/fs/read_write.c index b0fb1176b628..e16bcafc0da2 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -1565,6 +1565,28 @@ COMPAT_SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd, } #endif +/* + * Prepare inodes for copy from @file_in to @file_out. + * + * Caller must hold output inode lock. + */ +int generic_copy_file_range_prep(struct file *file_in, struct file *file_out) +{ + int ret; + + WARN_ON_ONCE(!inode_is_locked(file_inode(file_out))); + + /* + * Clear the security bits if the process is not being run by root. + * This keeps people from modifying setuid and setgid binaries. + */ + ret = file_remove_privs(file_out); + + return ret; + +} +EXPORT_SYMBOL(generic_copy_file_range_prep); + /** * generic_copy_file_range - copy data between two files * @file_in: file structure to read from @@ -1590,6 +1612,15 @@ ssize_t generic_copy_file_range(struct file *file_in, loff_t pos_in, struct file *file_out, loff_t pos_out, size_t len, unsigned int flags) { + int ret; + + /* Should inode lock be held throughout the copy operation? */ + inode_lock(file_inode(file_out)); + ret = generic_copy_file_range_prep(file_in, file_out); + inode_unlock(file_inode(file_out)); + if (ret) + return ret; + return do_splice_direct(file_in, &pos_in, file_out, &pos_out, len > MAX_RW_COUNT ? MAX_RW_COUNT : len, 0); } diff --git a/include/linux/fs.h b/include/linux/fs.h index e4d382c4342a..3e03a96d9ab6 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1889,6 +1889,8 @@ extern ssize_t vfs_readv(struct file *, const struct iovec __user *, unsigned long, loff_t *, rwf_t); extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *, loff_t, size_t, unsigned int); +extern int generic_copy_file_range_prep(struct file *file_in, + struct file *file_out); extern ssize_t generic_copy_file_range(struct file *file_in, loff_t pos_in, struct file *file_out, loff_t pos_out, size_t len, unsigned int flags); From patchwork Sun May 26 06:10:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 10961377 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 31365912 for ; Sun, 26 May 2019 06:11:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 232D728A9D for ; Sun, 26 May 2019 06:11:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 178C328AA4; Sun, 26 May 2019 06:11:41 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable 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 EEEA228AA0 for ; Sun, 26 May 2019 06:11:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727685AbfEZGL0 (ORCPT ); Sun, 26 May 2019 02:11:26 -0400 Received: from mail-wm1-f66.google.com ([209.85.128.66]:39959 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727663AbfEZGLZ (ORCPT ); Sun, 26 May 2019 02:11:25 -0400 Received: by mail-wm1-f66.google.com with SMTP id 15so12692931wmg.5; Sat, 25 May 2019 23:11:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=DGrN4rR5rYR4+AFEw/yxi4Y2DyPPMShooGDZpQ3nmN4=; b=rXjemcSygAWLxWoeAChSHdp5wXZOJhg09otgokpp8YocLyi4Qj/aKs7UVeIp5A86ET ZvJbU57lL/uqFpohmWXlv9g2IBR06+XoeONCKzLI6wCSA36/uq2u/hsg4jhUFSN0OigD sYxA5u1qstHS1D/9j5TC9iAHORGDnxCdfbzWu08e/JCt9F+6bpAruhF5NTEJrxAc2FIC nq9e5EIDdtsj0j+bVdJH2+DU718aYBg9CkACNAkmDlB6M1dm5PrjX/r9k/HR3VVKAaKj qIob7LAvdhUPaKWhBGxZIMLzLX0+F59yo1hjrnm0a+yCNJ4hoZEvY6fnJId/e3HIeLBn Pt7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=DGrN4rR5rYR4+AFEw/yxi4Y2DyPPMShooGDZpQ3nmN4=; b=D5IPb2/Ji78Y8h6eFF3LGyyb3gBu/HT2u0dhZlu9VafcYYDKZ1H4FgxaQ0ebK0aTyb J5a6Nm7klw273kaIWAKhMkI4viwBhm5OPMuxp+cwwWxOh+h1BNn13WKhgUSW9Ge+IwP9 icXiNK2Y7x4RZy8Rcsvoc1f6zaTFV8iICvHby8PmNGiIEvcjc3gVDN11OprLUGRgdygG JkldFFw01o3u6DEja9hHSCv1pujjKNvRUpg3kMnuQmdhUAiwDwY5tcHQ2mR39ATeTdlL Envu8wVillIVd1B0T7hjXS06PaDZuHdVH4yeCY4po/NjJkP+MSq2uB4RTa1uxzm27GTR I7CA== X-Gm-Message-State: APjAAAXODhFSa9cLkBiqS0PA4B5FCDri963igT7G5By/jAucn/lw4dgu M+yH3jFdkRChWez1aJ3z4Wc= X-Google-Smtp-Source: APXvYqxL5/b/9xctfsqvUZOtVzu0KdbblnJ9WKr/Jni5zrHOSijuz9UupMuRNYntXRVoNGc0cSTr9g== X-Received: by 2002:a1c:9dc7:: with SMTP id g190mr21200396wme.121.1558851083327; Sat, 25 May 2019 23:11:23 -0700 (PDT) Received: from localhost.localdomain ([5.102.238.208]) by smtp.gmail.com with ESMTPSA id a124sm5302943wmh.3.2019.05.25.23.11.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 25 May 2019 23:11:22 -0700 (PDT) From: Amir Goldstein To: "Darrick J . Wong" Cc: Dave Chinner , Christoph Hellwig , Olga Kornievskaia , Luis Henriques , Al Viro , linux-fsdevel@vger.kernel.org, linux-xfs@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, linux-api@vger.kernel.org, Dave Chinner Subject: [PATCH v2 6/8] vfs: copy_file_range should update file timestamps Date: Sun, 26 May 2019 09:10:57 +0300 Message-Id: <20190526061100.21761-7-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190526061100.21761-1-amir73il@gmail.com> References: <20190526061100.21761-1-amir73il@gmail.com> 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 From: Dave Chinner Timestamps are not updated right now, so programs looking for timestamp updates for file modifications (like rsync) will not detect that files have changed. We are also accessing the source data when doing a copy (but not when cloning) so we need to update atime on the source file as well. Signed-off-by: Dave Chinner Signed-off-by: Amir Goldstein Reviewed-by: Darrick J. Wong --- fs/read_write.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fs/read_write.c b/fs/read_write.c index e16bcafc0da2..4b23a86aacd9 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -1576,6 +1576,16 @@ int generic_copy_file_range_prep(struct file *file_in, struct file *file_out) WARN_ON_ONCE(!inode_is_locked(file_inode(file_out))); + /* Update source timestamps, because we are accessing file data */ + file_accessed(file_in); + + /* Update destination timestamps, since we can alter file contents. */ + if (!(file_out->f_mode & FMODE_NOCMTIME)) { + ret = file_update_time(file_out); + if (ret) + return ret; + } + /* * Clear the security bits if the process is not being run by root. * This keeps people from modifying setuid and setgid binaries. From patchwork Sun May 26 06:10:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 10961375 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 0938016C1 for ; Sun, 26 May 2019 06:11:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EDC4328A9D for ; Sun, 26 May 2019 06:11:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E245128AA4; Sun, 26 May 2019 06:11:40 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable 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 B809328A9B for ; Sun, 26 May 2019 06:11:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727702AbfEZGL2 (ORCPT ); Sun, 26 May 2019 02:11:28 -0400 Received: from mail-wm1-f65.google.com ([209.85.128.65]:35361 "EHLO mail-wm1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726131AbfEZGL1 (ORCPT ); Sun, 26 May 2019 02:11:27 -0400 Received: by mail-wm1-f65.google.com with SMTP id w9so6605525wmi.0; Sat, 25 May 2019 23:11:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Owu1kqq/INqxAb9EY95jYyw2nK1rSUlj4Hlb88mLwsA=; b=ezfAITJPkBhPTI9UrfuxBtzIdQ8Pj+7vpBVqRZ4U9Br2cREUQc0NgOWslINdwSpJsN yGaNZTvWN8WLDjLdhQLNdFXIJHlETvbE4XLqKnagGi3ySxp7vDAksa8p6isoctb0/TBJ txydc5EFZKwCzIHpRUAgBOIEZEQNIPoGUZ1fuCVtCQpU4+jk786Ld19lTwA8zRCF3Q+3 YLsYtCHzu2zKrxReEMYrP+8XHLikLGiLSEqmBcdtpE3XwyO7qmFGfQj0GRTIWCVgZm50 igg5oEtHsEJf7316jUsQldY+xGmBHC6OJwrm4yQHypHEkqQNYtLy1ZJMdsIzFPnnv6BH 6j4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Owu1kqq/INqxAb9EY95jYyw2nK1rSUlj4Hlb88mLwsA=; b=nI7zCsXK6rB+H8p4078kNQtFh7uXNtuPxfnlxio7wyG7fzNEEoQyz24+uzVKlH6OJ5 WuVxwCFpLgEplQNp2L0EHbZZUF4pj0vOREmF92RWcsQaCnKVDbZQHVoaKiWPItM3oCqm F9cQCC8hi2gnMFUlipu/Mr79fyMwn9XWz3QPBVZt8/kRls/rDdavJFAACgzNM1PqUepl nKQiBjD1xe4Lvm1Rj9f8M78+4Auh41LbR0f4LkYEX6NayDccV5zq/2wdCXsYnuikH/1b cQzk+FCadbPoPvmcrCuySgSfnMbURjwGoURVBGWC/3sn7/NO1xc/UEId/cOq1x7Hfsxr lB0w== X-Gm-Message-State: APjAAAWPQg0oouUFc7DY3uOvBlcAhcvd2EboytV+bqd9NuLA/YDdT0mK muUMlx4xzs8c93aIRiZJMxg= X-Google-Smtp-Source: APXvYqw9rMgGsQe5SD/ng55LCAF4+KUSaox/Qs9QyVUvAzxqkoDXUlL+qEp5vqyM8kydHOsb5Q0yGw== X-Received: by 2002:a05:600c:22cc:: with SMTP id 12mr5567828wmg.141.1558851085122; Sat, 25 May 2019 23:11:25 -0700 (PDT) Received: from localhost.localdomain ([5.102.238.208]) by smtp.gmail.com with ESMTPSA id a124sm5302943wmh.3.2019.05.25.23.11.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 25 May 2019 23:11:24 -0700 (PDT) From: Amir Goldstein To: "Darrick J . Wong" Cc: Dave Chinner , Christoph Hellwig , Olga Kornievskaia , Luis Henriques , Al Viro , linux-fsdevel@vger.kernel.org, linux-xfs@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, linux-api@vger.kernel.org, Dave Chinner Subject: [PATCH v2 7/8] vfs: allow copy_file_range to copy across devices Date: Sun, 26 May 2019 09:10:58 +0300 Message-Id: <20190526061100.21761-8-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190526061100.21761-1-amir73il@gmail.com> References: <20190526061100.21761-1-amir73il@gmail.com> 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 We want to enable cross-filesystem copy_file_range functionality where possible, so push the "same superblock only" checks down to the individual filesystem callouts so they can make their own decisions about cross-superblock copy offload and fallack to generic_copy_file_range() for cross-superblock copy. [Amir] We do not call ->remap_file_range() in case the inodes are not on the same sb and do not call ->copy_file_range() in case the inodes are not on the same filesystem type. This changes behavior of the copy_file_range(2) syscall, which will now allow cross filesystem in-kernel copy. CIFS already supports cross-superblock copy, between two shares to the same server. This functionality will now be available via the copy_file_range(2) syscall. Cc: Steve French Signed-off-by: Dave Chinner Signed-off-by: Amir Goldstein Reviewed-by: Darrick J. Wong --- fs/ceph/file.c | 4 +++- fs/cifs/cifsfs.c | 2 +- fs/fuse/file.c | 5 ++++- fs/nfs/nfs4file.c | 5 ++++- fs/read_write.c | 20 ++++++++++++++------ 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 54cfc877a6ef..adf99557c46c 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -1909,6 +1909,8 @@ static ssize_t __ceph_copy_file_range(struct file *src_file, loff_t src_off, if (src_inode == dst_inode) return -EINVAL; + if (src_inode->i_sb != dst_inode->i_sb) + return -EXDEV; if (ceph_snap(dst_inode) != CEPH_NOSNAP) return -EROFS; @@ -2118,7 +2120,7 @@ static ssize_t ceph_copy_file_range(struct file *src_file, loff_t src_off, ret = __ceph_copy_file_range(src_file, src_off, dst_file, dst_off, len, flags); - if (ret == -EOPNOTSUPP) + if (ret == -EOPNOTSUPP || ret == -EXDEV) ret = generic_copy_file_range(src_file, src_off, dst_file, dst_off, len, flags); return ret; diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index e103b499aaa8..7bde046110ce 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -1152,7 +1152,7 @@ static ssize_t cifs_copy_file_range(struct file *src_file, loff_t off, len, flags); free_xid(xid); - if (rc == -EOPNOTSUPP) + if (rc == -EOPNOTSUPP || rc == -EXDEV) rc = generic_copy_file_range(src_file, off, dst_file, destoff, len, flags); return rc; diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 3531d4a3d9ec..180161f6f0bd 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -3126,6 +3126,9 @@ static ssize_t __fuse_copy_file_range(struct file *file_in, loff_t pos_in, if (fc->no_copy_file_range) return -EOPNOTSUPP; + if (file_inode(file_in)->i_sb != file_inode(file_out)->i_sb) + return -EXDEV; + inode_lock(inode_out); err = generic_copy_file_range_prep(file_in, file_out); @@ -3186,7 +3189,7 @@ static ssize_t fuse_copy_file_range(struct file *src_file, loff_t src_off, ret = __fuse_copy_file_range(src_file, src_off, dst_file, dst_off, len, flags); - if (ret == -EOPNOTSUPP) + if (ret == -EOPNOTSUPP || ret == -EXDEV) ret = generic_copy_file_range(src_file, src_off, dst_file, dst_off, len, flags); return ret; diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index 4842f3ab3161..f4157eb1f69d 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -133,6 +133,9 @@ static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in, struct file *file_out, loff_t pos_out, size_t count, unsigned int flags) { + /* Only offload copy if superblock is the same */ + if (file_inode(file_in)->i_sb != file_inode(file_out)->i_sb) + return -EXDEV; if (!nfs_server_capable(file_inode(file_out), NFS_CAP_COPY)) return -EOPNOTSUPP; if (file_inode(file_in) == file_inode(file_out)) @@ -148,7 +151,7 @@ static ssize_t nfs4_copy_file_range(struct file *file_in, loff_t pos_in, ret = __nfs4_copy_file_range(file_in, pos_in, file_out, pos_out, count, flags); - if (ret == -EOPNOTSUPP) + if (ret == -EOPNOTSUPP || ret == -EXDEV) ret = generic_copy_file_range(file_in, pos_in, file_out, pos_out, count, flags); return ret; diff --git a/fs/read_write.c b/fs/read_write.c index 4b23a86aacd9..283ec30d2136 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -1640,7 +1640,18 @@ static ssize_t do_copy_file_range(struct file *file_in, loff_t pos_in, struct file *file_out, loff_t pos_out, size_t len, unsigned int flags) { - if (file_out->f_op->copy_file_range) + /* + * Although we now allow filesystems to handle cross sb copy, passing + * an inode of the wrong filesystem type to filesystem operation can + * often result in an attempt to dereference the wrong concrete inode + * struct, so avoid doing that until we really have a good reason. + * The incentive for passing inode from different sb to filesystem is + * NFS cross server copy and for that use case, enforcing same + * filesystem type is acceptable. + */ + if (file_out->f_op->copy_file_range && + file_inode(file_in)->i_sb->s_type == + file_inode(file_out)->i_sb->s_type) return file_out->f_op->copy_file_range(file_in, pos_in, file_out, pos_out, len, flags); @@ -1663,10 +1674,6 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in, if (flags != 0) return -EINVAL; - /* this could be relaxed once a method supports cross-fs copies */ - if (file_inode(file_in)->i_sb != file_inode(file_out)->i_sb) - return -EXDEV; - ret = generic_copy_file_checks(file_in, pos_in, file_out, pos_out, &len, flags); if (unlikely(ret)) @@ -1689,7 +1696,8 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in, * Try cloning first, this is supported by more file systems, and * more efficient if both clone and copy are supported (e.g. NFS). */ - if (file_in->f_op->remap_file_range) { + if (file_in->f_op->remap_file_range && + file_inode(file_in)->i_sb == file_inode(file_out)->i_sb) { loff_t cloned; cloned = file_in->f_op->remap_file_range(file_in, pos_in, From patchwork Sun May 26 06:10:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 10961363 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 C7C19912 for ; Sun, 26 May 2019 06:11:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B765028A9B for ; Sun, 26 May 2019 06:11:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AB44C28AA0; Sun, 26 May 2019 06:11:35 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable 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 6A27828A9B for ; Sun, 26 May 2019 06:11:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727724AbfEZGLa (ORCPT ); Sun, 26 May 2019 02:11:30 -0400 Received: from mail-wm1-f68.google.com ([209.85.128.68]:54804 "EHLO mail-wm1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727663AbfEZGL3 (ORCPT ); Sun, 26 May 2019 02:11:29 -0400 Received: by mail-wm1-f68.google.com with SMTP id i3so12982499wml.4; Sat, 25 May 2019 23:11:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=xzMeQSjk/vpAnsoZTPGclf7QJxi3EL8e26LVdVAwCA0=; b=V6hO9Pn3tG6o05o4jaFAQ0zpkPrUpsu5TE+T4CZ/1IvBUrlSLbgxy1G+6GIWzXi/I6 TgeodHxD/zbZxntaF3uDrUuZZeCAC4N1JfY+Urrr+Ntd8YCOu6H4akUUsSVCEVpPNsec yZ+lfn867N7qcRF/4t1jJB3ZxVs3ffYdcXguw/2sFh+abnajfNg6qQ3VkBIvLFlK7gQL v2/sfVkNGrfgKu8+eckFVUDmJ/Lut7xvl80PfUYNgtqJpBnWrq0UeUWNXJuPc5c2qilE B6avEzGPv5DEmCvApni5ctUXq59SqtRvKAN5CdDgQhqyHVjs9rU2LfuEdmg/6sywTnAm I+Ew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=xzMeQSjk/vpAnsoZTPGclf7QJxi3EL8e26LVdVAwCA0=; b=Gy2Q4HNUbxS98EAbCezluKAdAckJizNi78LV5B1ZWzRq0yK86fdkjyNERb4ISSsBoV 8w35fTEwmIRd6idfCmjG/C5HvOFkOp3JOCz257ryMGdQ4RFYHkdjkdngtRyeU/kgMlM1 7D+meenyvELl8X4r63JP15sa12JKQeQBg1nEeORERbAURkSv3J5+YjoEJD2Gg55WiZUc o6tiqHopsiYw7rjngsNzA0BJheIoDOpXjJRtoMgqD46KooBHvKxIKfq7AdW0NsXkbh1G GfaDi/NMgYEOPQe/pt4Rme1kosLuk7JzPdKaqpok5VMWQOnsbaCXFh7/9DjymRoUjSKE 2DTw== X-Gm-Message-State: APjAAAVbYCrqCm8zkZgZClN9CBfK3Tzbkhc+pYfhYLUyf3tYIEPX1dyW qQ0daHa6Hhn3Oh1MqEGsXsA= X-Google-Smtp-Source: APXvYqy+J5jgXwkRr/gZ5c4Cs4Qrvo1uXdv6xXM+Eq0qAqd4SzWgaFxn1XfrZxdTSFpWvSgOMfW92A== X-Received: by 2002:a7b:c549:: with SMTP id j9mr21521254wmk.114.1558851087039; Sat, 25 May 2019 23:11:27 -0700 (PDT) Received: from localhost.localdomain ([5.102.238.208]) by smtp.gmail.com with ESMTPSA id a124sm5302943wmh.3.2019.05.25.23.11.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 25 May 2019 23:11:26 -0700 (PDT) From: Amir Goldstein To: "Darrick J . Wong" Cc: Dave Chinner , Christoph Hellwig , Olga Kornievskaia , Luis Henriques , Al Viro , linux-fsdevel@vger.kernel.org, linux-xfs@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v2 8/8] vfs: remove redundant checks from generic_remap_checks() Date: Sun, 26 May 2019 09:10:59 +0300 Message-Id: <20190526061100.21761-9-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190526061100.21761-1-amir73il@gmail.com> References: <20190526061100.21761-1-amir73il@gmail.com> 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 The access limit checks on input file range in generic_remap_checks() are redundant because the input file size is guarantied to be within limits and pos+len are already checked to be within input file size. Beyond the fact that the check cannot fail, if it would have failed, it could return -EFBIG for input file range error. There is no precedent for that. -EFBIG is returned in syscalls that would change file length. Signed-off-by: Amir Goldstein --- mm/filemap.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/mm/filemap.c b/mm/filemap.c index 1852fbf08eeb..7e1aa36d57a2 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -3000,10 +3000,6 @@ int generic_remap_checks(struct file *file_in, loff_t pos_in, return -EINVAL; count = min(count, size_in - (uint64_t)pos_in); - ret = generic_access_check_limits(file_in, pos_in, &count); - if (ret) - return ret; - ret = generic_write_check_limits(file_out, pos_out, &count); if (ret) return ret; From patchwork Sun May 26 06:11:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 10961369 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 B06CF912 for ; Sun, 26 May 2019 06:11:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9EDBD28AA4 for ; Sun, 26 May 2019 06:11:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 934F428AAB; Sun, 26 May 2019 06:11:39 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable 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 9BAD828AA4 for ; Sun, 26 May 2019 06:11:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727734AbfEZGLf (ORCPT ); Sun, 26 May 2019 02:11:35 -0400 Received: from mail-wr1-f65.google.com ([209.85.221.65]:43010 "EHLO mail-wr1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727717AbfEZGLb (ORCPT ); Sun, 26 May 2019 02:11:31 -0400 Received: by mail-wr1-f65.google.com with SMTP id l17so5254510wrm.10; Sat, 25 May 2019 23:11:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=cducFLuU0ir0Q0WPZZBgZj30yxOPz/TPO76rzq4FrUw=; b=MT5GSLyjdkxiLs7sS42XeP4bahm+UMeBohQ/LGy+5ffS9X60wfhc46H/42daPIXCd3 /9GiWSmv9/P0phUzkn3g1ALZ2sdH7qOjNTJgwUc14idInm/sCJlYwFHQkkwqss6RlARo gz4MuAZgVM1D9myZp+Z76KyM2bVsDZYhBs+IjdUUTMO1tw0W5nfbozqNis+qCKVIphHr S6QGsjLyYoEBZ6+joOdwc3UE6pR0dOx1EByE46Dypn4Ab8fqqG7A6X0Qd0Mgm9Zk0Pxk pPLDorIAICPENkLChejLIhUuqER650ZIj0y4/Cn65WGe36cwh6BTwXALKxnnwROpyFCX xoow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=cducFLuU0ir0Q0WPZZBgZj30yxOPz/TPO76rzq4FrUw=; b=ZLf5R0pNkyVfnMiev5xZ+dXEeY8gV/8hYY8n7LKgvd0374fKm+Yl4rm9oTGnfM/egl UNP7Reoc1MKn55oPCgyADIUJgyPw8Epb+VDbpPqK3pDS/b8tdYgqPnMr5XVYd1EZIoxP hlUfq1Gjo4UOA9NjpzgOcGZh1bleAoV8bPGunXNDO/XuJ8YeWv19a3tH7PSU+5Gubb4D ufN63o7q6/9uTFH3+WVAzsM3qVXewsNK9gF2vW7fgrG+EWijtYArZIYx9qiLy6LOBBkO /arWRwlGFLmncZhZoTiHvvV+0CXyrDz+uCAH4IpGXes9YdjW1B0yHpdLq/gTeO+vVBHV fgeg== X-Gm-Message-State: APjAAAUCpprArdTrkLjc0uPA8kvBPBgE9zp3qPRFEk1spR3zh8CuLLfY rAnAUR9rs1Jzi2slT6k0OTI= X-Google-Smtp-Source: APXvYqxAbdy5mvAvbBTCtmh2uFWBEJilLDh3vNpbDyE1F1QGGJU8IaJcsa1VOG5wnc99eBGqOcbWiw== X-Received: by 2002:a5d:534b:: with SMTP id t11mr24310161wrv.297.1558851088914; Sat, 25 May 2019 23:11:28 -0700 (PDT) Received: from localhost.localdomain ([5.102.238.208]) by smtp.gmail.com with ESMTPSA id a124sm5302943wmh.3.2019.05.25.23.11.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 25 May 2019 23:11:28 -0700 (PDT) From: Amir Goldstein To: "Darrick J . Wong" Cc: Dave Chinner , Christoph Hellwig , Olga Kornievskaia , Luis Henriques , Al Viro , linux-fsdevel@vger.kernel.org, linux-xfs@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, ceph-devel@vger.kernel.org, linux-api@vger.kernel.org, Dave Chinner Subject: [PATCH v2 9/8] man-pages: copy_file_range updates Date: Sun, 26 May 2019 09:11:00 +0300 Message-Id: <20190526061100.21761-10-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190526061100.21761-1-amir73il@gmail.com> References: <20190526061100.21761-1-amir73il@gmail.com> 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 Update with all the missing errors the syscall can return, the behaviour the syscall should have w.r.t. to copies within single files, etc. [Amir] Copying beyond EOF returns zero. Signed-off-by: Dave Chinner Signed-off-by: Amir Goldstein --- man2/copy_file_range.2 | 93 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 77 insertions(+), 16 deletions(-) diff --git a/man2/copy_file_range.2 b/man2/copy_file_range.2 index 2438b63c8..fab11f977 100644 --- a/man2/copy_file_range.2 +++ b/man2/copy_file_range.2 @@ -42,9 +42,9 @@ without the additional cost of transferring data from the kernel to user space and then back into the kernel. It copies up to .I len -bytes of data from file descriptor +bytes of data from the source file descriptor .I fd_in -to file descriptor +to target file descriptor .IR fd_out , overwriting any data that exists within the requested range of the target file. .PP @@ -74,6 +74,11 @@ is not changed, but .I off_in is adjusted appropriately. .PP +.I fd_in +and +.I fd_out +can refer to the same file. If they refer to the same file, then the source and +target ranges are not allowed to overlap. .PP The .I flags @@ -84,6 +89,11 @@ Upon successful completion, .BR copy_file_range () will return the number of bytes copied between files. This could be less than the length originally requested. +If the file offset of +.I fd_in +is at or past the end of file, no bytes are copied, and +.BR copy_file_range () +returns zero. .PP On error, .BR copy_file_range () @@ -93,12 +103,16 @@ is set to indicate the error. .SH ERRORS .TP .B EBADF -One or more file descriptors are not valid; or +One or more file descriptors are not valid. +.TP +.B EBADF .I fd_in is not open for reading; or .I fd_out -is not open for writing; or -the +is not open for writing. +.TP +.B EBADF +The .B O_APPEND flag is set for the open file description (see .BR open (2)) @@ -106,17 +120,36 @@ referred to by the file descriptor .IR fd_out . .TP .B EFBIG -An attempt was made to write a file that exceeds the implementation-defined -maximum file size or the process's file size limit, -or to write at a position past the maximum allowed offset. +An attempt was made to write at a position past the maximum file offset the +kernel supports. +.TP +.B EFBIG +An attempt was made to write a range that exceeds the allowed maximum file size. +The maximum file size differs between filesystem implemenations and can be +different to the maximum allowed file offset. +.TP +.B EFBIG +An attempt was made to write beyond the process's file size resource +limit. This may also result in the process receiving a +.I SIGXFSZ +signal. .TP .B EINVAL -Requested range extends beyond the end of the source file; or the +The .I flags argument is not 0. .TP -.B EIO -A low-level I/O error occurred while copying. +.B EINVAL +.I fd_in +and +.I fd_out +refer to the same file and the source and target ranges overlap. +.TP +.B EINVAL +.I fd_in +or +.I fd_out +is not a regular file. .TP .B EISDIR .I fd_in @@ -124,22 +157,50 @@ or .I fd_out refers to a directory. .TP +.B EOVERFLOW +The requested source or destination range is too large to represent in the +specified data types. +.TP +.B EIO +A low-level I/O error occurred while copying. +.TP .B ENOMEM Out of memory. .TP -.B ENOSPC -There is not enough space on the target filesystem to complete the copy. -.TP .B EXDEV The files referred to by .IR file_in " and " file_out -are not on the same mounted filesystem. +are not on the same mounted filesystem (pre Linux 5.3). +.TP +.B ENOSPC +There is not enough space on the target filesystem to complete the copy. +.TP +.B TXTBSY +.I fd_in +or +.I fd_out +refers to an active swap file. +.TP +.B EPERM +.I fd_out +refers to an immutable file. +.TP +.B EACCES +The user does not have write permissions for the destination file. .SH VERSIONS The .BR copy_file_range () system call first appeared in Linux 4.5, but glibc 2.27 provides a user-space emulation when it is not available. .\" https://sourceware.org/git/?p=glibc.git;a=commit;f=posix/unistd.h;h=bad7a0c81f501fbbcc79af9eaa4b8254441c4a1f +.PP +A major rework of the kernel implementation occurred in 5.3. Areas of the API +that weren't clearly defined were clarified and the API bounds are much more +strictly checked than on earlier kernels. Applications should target the +behaviour and requirements of 5.3 kernels. +.PP +First support for cross-filesystem copies was introduced in Linux 5.3. Older +kernels will return -EXDEV when cross-filesystem copies are attempted. .SH CONFORMING TO The .BR copy_file_range () @@ -224,7 +285,7 @@ main(int argc, char **argv) } len \-= ret; - } while (len > 0); + } while (len > 0 && ret > 0); close(fd_in); close(fd_out);