From patchwork Mon Oct 22 17:56:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 10652333 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 D40BF14DE for ; Mon, 22 Oct 2018 17:57:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C41A729173 for ; Mon, 22 Oct 2018 17:57:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B81782917E; Mon, 22 Oct 2018 17:57:01 +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 26FD229173 for ; Mon, 22 Oct 2018 17:57:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728931AbeJWCQ3 (ORCPT ); Mon, 22 Oct 2018 22:16:29 -0400 Received: from mail-wr1-f68.google.com ([209.85.221.68]:40659 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728715AbeJWCQ2 (ORCPT ); Mon, 22 Oct 2018 22:16:28 -0400 Received: by mail-wr1-f68.google.com with SMTP id d2-v6so45963320wro.7; Mon, 22 Oct 2018 10:56:56 -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; bh=hbe1nGAz5paEZARtW0rCnxEu/AAIOLpabdhtb4M0+q8=; b=FCHxCDLrGzJkX0nfQkc4EfjXgm66woxwXNT1Fx7ETBu/ILtwiNWcOtWD43BmOm7MeF jbVYQUnaj6o1JHI2jkzFKLQzZSSjOJsRRwGw6qpjR7ewtYU+vR4tPhkuaSbQEiBoPcZ6 pA2EuAuSqVM/KIKq5+dsU5LDt5erl4UUoTrcH5hjAujNz7/2+INl3FisiG9KtHodg1VF dhSrzpkfYYnLe45NHf0Rc6keuIje61ms5ZHspqvLkHXCwjZdhGbq7CYEnEc1VZS8EU0K gCuoeIFE8akZZ1pvmsztRUvA12qi5yHzk5u8VYTBm3uu3WP9l6zdRpEgrQ5DP647dr7C 7w3w== 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; bh=hbe1nGAz5paEZARtW0rCnxEu/AAIOLpabdhtb4M0+q8=; b=rGNmB9MJ7LrjMS9xCrw1HrM9w+PWPZpeg0IJg3uHZZn8/zDwtylamjn5muK/3ADVGY 3zMhv2YcB0UBlsBEPgzF13WAxtBmlhqjLCDCLYVaydD5aO2s80lY0FNqvN72LF2PRK/x SOtqt0Mj4yw8uMuN3HEY7n8I4jdggwnWBFeTu2GvS50IyyF0y18n2DMEDGSqVCDfFQNr en1CuLCVIi8o9+Q/E6wH3trfLSlDv7CbR5lmhn4VYbTo1ymeLV0gpvQ1LZd03oQDLiLZ sd8b6U6NXpQat60MTtMwU34xSGmMQNht5dU8BwzXugcDN3rf1R4ucGJJomDJkc4nnrux RCgw== X-Gm-Message-State: AGRZ1gLCYhvvaTjNc6NE3PX0KbbylXFRs2DCnYiWV51JBNTWEMZ2tFOx FnMBG+CB8Ku97EOrTGF79zcyD4pK X-Google-Smtp-Source: AJdET5fqv1ohyUuvEbIwiDATWbQqNvaXOdn1wS6EH17bI+68XBJ/7nRrXHPEsDfo37sD8+TmDmUe/w== X-Received: by 2002:a5d:420d:: with SMTP id n13-v6mr21337332wrq.201.1540231015356; Mon, 22 Oct 2018 10:56:55 -0700 (PDT) Received: from localhost.localdomain ([94.230.83.227]) by smtp.gmail.com with ESMTPSA id 2-v6sm32147652wro.96.2018.10.22.10.56.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 22 Oct 2018 10:56:54 -0700 (PDT) From: Amir Goldstein To: Greg Kroah-Hartman Cc: Miklos Szeredi , stable@vger.kernel.org, linux-unionfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, Miklos Szeredi Subject: [PATCH] vfs: swap names of {do,vfs}_clone_file_range() Date: Mon, 22 Oct 2018 20:56:46 +0300 Message-Id: <20181022175646.20146-1-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP commit a725356b6659469d182d662f22d770d83d3bc7b5 upstream. Commit 031a072a0b8a ("vfs: call vfs_clone_file_range() under freeze protection") created a wrapper do_clone_file_range() around vfs_clone_file_range() moving the freeze protection to former, so overlayfs could call the latter. The more common vfs practice is to call do_xxx helpers from vfs_xxx helpers, where freeze protecction is taken in the vfs_xxx helper, so this anomality could be a source of confusion. It seems that commit 8ede205541ff ("ovl: add reflink/copyfile/dedup support") may have fallen a victim to this confusion - ovl_clone_file_range() calls the vfs_clone_file_range() helper in the hope of getting freeze protection on upper fs, but in fact results in overlayfs allowing to bypass upper fs freeze protection. Swap the names of the two helpers to conform to common vfs practice and call the correct helpers from overlayfs and nfsd. Signed-off-by: Amir Goldstein Signed-off-by: Miklos Szeredi Fixes: 031a072a0b8a ("vfs: call vfs_clone_file_range() under freeze...") Signed-off-by: Amir Goldstein --- Greg, The upstream commit (-rc8) is not a bug fix, it's a vfs API fix. If we do not apply it to stable kernels, we are going to have a backporting landmine, should a future fix use vfs_clone_file_range() it will not do the same thing upstream and in stable. I backported the change to linux-4.18.y and added the Fixes label. I verified that there are no pathces between the Fixes commit and current master that use {vfs,do}_clone_file_range() and could be considered for backporting to stable (all thoses that can be considered are already in stable). I verified that that with this backport applies to v4.18.16 there are no regression of quick clone tests in xfstests with overlayfs and with xfs. Backport patch also applies cleanly to v4.14.78. Thanks, Amir. fs/ioctl.c | 2 +- fs/nfsd/vfs.c | 3 ++- fs/overlayfs/copy_up.c | 2 +- fs/read_write.c | 17 +++++++++++++++-- include/linux/fs.h | 17 +++-------------- 5 files changed, 22 insertions(+), 19 deletions(-) diff --git a/fs/ioctl.c b/fs/ioctl.c index b445b13fc59b..5444fec607ce 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -229,7 +229,7 @@ static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd, ret = -EXDEV; if (src_file.file->f_path.mnt != dst_file->f_path.mnt) goto fdput; - ret = do_clone_file_range(src_file.file, off, dst_file, destoff, olen); + ret = vfs_clone_file_range(src_file.file, off, dst_file, destoff, olen); fdput: fdput(src_file); return ret; diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index b0555d7d8200..613d2fe2dddd 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -541,7 +541,8 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp, __be32 nfsd4_clone_file_range(struct file *src, u64 src_pos, struct file *dst, u64 dst_pos, u64 count) { - return nfserrno(do_clone_file_range(src, src_pos, dst, dst_pos, count)); + return nfserrno(vfs_clone_file_range(src, src_pos, dst, dst_pos, + count)); } ssize_t nfsd_copy_file_range(struct file *src, u64 src_pos, struct file *dst, diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index ddaddb4ce4c3..26b477f2538d 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -156,7 +156,7 @@ static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len) } /* Try to use clone_file_range to clone up within the same fs */ - error = vfs_clone_file_range(old_file, 0, new_file, 0, len); + error = do_clone_file_range(old_file, 0, new_file, 0, len); if (!error) goto out; /* Couldn't clone, so now we try to copy the data */ diff --git a/fs/read_write.c b/fs/read_write.c index 153f8f690490..c9d489684335 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -1818,8 +1818,8 @@ int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in, } EXPORT_SYMBOL(vfs_clone_file_prep_inodes); -int vfs_clone_file_range(struct file *file_in, loff_t pos_in, - struct file *file_out, loff_t pos_out, u64 len) +int do_clone_file_range(struct file *file_in, loff_t pos_in, + struct file *file_out, loff_t pos_out, u64 len) { struct inode *inode_in = file_inode(file_in); struct inode *inode_out = file_inode(file_out); @@ -1866,6 +1866,19 @@ int vfs_clone_file_range(struct file *file_in, loff_t pos_in, return ret; } +EXPORT_SYMBOL(do_clone_file_range); + +int vfs_clone_file_range(struct file *file_in, loff_t pos_in, + struct file *file_out, loff_t pos_out, u64 len) +{ + int ret; + + file_start_write(file_out); + ret = do_clone_file_range(file_in, pos_in, file_out, pos_out, len); + file_end_write(file_out); + + return ret; +} EXPORT_SYMBOL(vfs_clone_file_range); /* diff --git a/include/linux/fs.h b/include/linux/fs.h index a3afa50bb79f..e73363bd8646 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1813,8 +1813,10 @@ extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *, extern int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in, struct inode *inode_out, loff_t pos_out, u64 *len, bool is_dedupe); +extern int do_clone_file_range(struct file *file_in, loff_t pos_in, + struct file *file_out, loff_t pos_out, u64 len); extern int vfs_clone_file_range(struct file *file_in, loff_t pos_in, - struct file *file_out, loff_t pos_out, u64 len); + struct file *file_out, loff_t pos_out, u64 len); extern int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcoff, struct inode *dest, loff_t destoff, loff_t len, bool *is_same); @@ -2755,19 +2757,6 @@ static inline void file_end_write(struct file *file) __sb_end_write(file_inode(file)->i_sb, SB_FREEZE_WRITE); } -static inline int do_clone_file_range(struct file *file_in, loff_t pos_in, - struct file *file_out, loff_t pos_out, - u64 len) -{ - int ret; - - file_start_write(file_out); - ret = vfs_clone_file_range(file_in, pos_in, file_out, pos_out, len); - file_end_write(file_out); - - return ret; -} - /* * get_write_access() gets write permission for a file. * put_write_access() releases this write permission.