From patchwork Wed Oct 10 00:10:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 10633423 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 382CE17E3 for ; Wed, 10 Oct 2018 00:11:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 23C8329C7D for ; Wed, 10 Oct 2018 00:11:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1800029C98; Wed, 10 Oct 2018 00:11: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=-3.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7447129CA6 for ; Wed, 10 Oct 2018 00:11:00 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id ED91C6B000D; Tue, 9 Oct 2018 20:10:58 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id E8A3E6B000E; Tue, 9 Oct 2018 20:10:58 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id CB6026B0010; Tue, 9 Oct 2018 20:10:58 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pf1-f197.google.com (mail-pf1-f197.google.com [209.85.210.197]) by kanga.kvack.org (Postfix) with ESMTP id 8CF8E6B000D for ; Tue, 9 Oct 2018 20:10:58 -0400 (EDT) Received: by mail-pf1-f197.google.com with SMTP id e15-v6so3229494pfi.5 for ; Tue, 09 Oct 2018 17:10:58 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:dkim-signature:subject:from:to:cc:date :message-id:in-reply-to:references:user-agent:mime-version :content-transfer-encoding; bh=Q7WRM8cm5WCpI5pToKQWHyNcuRIx4G5Ru2lJk9SDSnU=; b=TbpE0gIrbRVnsyD9QTUU8L3ZyM0T7g2CG5nu0ula/z0ELf14lzjvdPk4JP+o2hIe/x jSHIulPly18daR3seJhWjmP1PYAfiBDh95lH8GwL6j7yNvLZSiMDm2rUrBcOa8zGKt5C Gxg79UoyoqmrO6qESItcybAZ9NZMEK8q9rThfMCc2K70dEz+jYw9Se6YteqZNr4Diw2n zQYK7CsHk3Fe/dacGQ+o+XkiWERiL+NTLTjxM/C4D2LVcSry81MYB2CKnRB4ECbrbbGP lke4c0OQfLWlkfFyRn1duRezNwJMXSxAKb0/vOPPne62EpNFTVVmjPM3946g/OltHNka n/Cg== X-Gm-Message-State: ABuFfoiUoe5/e7ddd+q9pGqiy3HH8eW54nZAha/V7Q+hUuF9zY29mYl/ tULvW/kUuaYFfOQQ4WLo8wPcxh6rOx6Apvj9ROWhwRJS0p+NxkMVwiYtprPIuicdE3KEyl18P4k HktvGSEDspmUkdvYDFYsfY31jePNGyUh28BcVebPigst6BzjE3iHc7GAi2BZAbUBCaw== X-Received: by 2002:a62:5982:: with SMTP id k2-v6mr21757955pfj.180.1539130258223; Tue, 09 Oct 2018 17:10:58 -0700 (PDT) X-Google-Smtp-Source: ACcGV62AEf7p1Vi84mwDeWBbOEmAndKQjCbN6CFUWPOj/SnUwn/Lcy7gWjnYsTw0+esAKS1fyDwV X-Received: by 2002:a62:5982:: with SMTP id k2-v6mr21757895pfj.180.1539130257341; Tue, 09 Oct 2018 17:10:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539130257; cv=none; d=google.com; s=arc-20160816; b=zi6/PVQpgokNovFPGwdB81Xfj3Z8pKLCDa3WMQTZwyOggsmroj2y+ijHQRYPzanWNS qQgZUxnOA2eUNOpXL4RwbtGRDl0CWGhqXXEncFiq8qi0PK7tYFwBUT9l1RYoYMGMHPKz TpcYB83QssnV71yjNzf+s12ZvEYRfeA4Wzr+w1/zvGtGBQv8tvvrTpMQ6Yst2x0jqxcM fN+RPDF0YLPpGDnTurzprW6dEYz5pA4P0UdXLwRAJetqGbXoSybyhnKcS1UIdXu0AUyw /Okn9VuyzVIb8o5DRZgqQiZ/hmgH25dr2DH0Q/r250ole1fwkIizPA86MRhg9eTWWc6H mTrw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:user-agent:references :in-reply-to:message-id:date:cc:to:from:subject:dkim-signature; bh=Q7WRM8cm5WCpI5pToKQWHyNcuRIx4G5Ru2lJk9SDSnU=; b=SyywrDDUAjCAAhifWBOthin1dikbMjqVAX5uIb/kLJ0Cd+THSh5vRg4NBXsJnMzvKK 2TAZtipu0bPWzZucKUopLzy9Zvyk1L3dLai5put7wznoC1xI6NYOg/4PJH+gtolrTR0O X0xPBa5xDcFAtCJMLqtfAesRo8iOItjTlCMHLLgGRTbSbRcQ7V94M638J4UiUh9ERQ/s kVH5sUATqKP+dc1EVcHNW1ueSoyaNzYNA5JZT0+yyGGwIY4w/sZQmEUACps8JAAP4EyC +wfM4vSqmO4QtbxB7WXA0avU+FPD7STaNbENDu2XK8nX888r8xrJRZWXo+JSrQ3DcbJP dmEg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@oracle.com header.s=corp-2018-07-02 header.b=sbZljqwc; spf=pass (google.com: domain of darrick.wong@oracle.com designates 141.146.126.78 as permitted sender) smtp.mailfrom=darrick.wong@oracle.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=oracle.com Received: from aserp2120.oracle.com (aserp2120.oracle.com. [141.146.126.78]) by mx.google.com with ESMTPS id e8-v6si22985957pgh.447.2018.10.09.17.10.57 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Oct 2018 17:10:57 -0700 (PDT) Received-SPF: pass (google.com: domain of darrick.wong@oracle.com designates 141.146.126.78 as permitted sender) client-ip=141.146.126.78; Authentication-Results: mx.google.com; dkim=pass header.i=@oracle.com header.s=corp-2018-07-02 header.b=sbZljqwc; spf=pass (google.com: domain of darrick.wong@oracle.com designates 141.146.126.78 as permitted sender) smtp.mailfrom=darrick.wong@oracle.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=oracle.com Received: from pps.filterd (aserp2120.oracle.com [127.0.0.1]) by aserp2120.oracle.com (8.16.0.22/8.16.0.22) with SMTP id w9A08wZ2138901; Wed, 10 Oct 2018 00:10:56 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=subject : from : to : cc : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=corp-2018-07-02; bh=Q7WRM8cm5WCpI5pToKQWHyNcuRIx4G5Ru2lJk9SDSnU=; b=sbZljqwctBNHKocMq4GyabetJ7oLp3SXgUT4wD8hRMNEvuCJQdSGlayZdRSpM2PK8nKh nleTKcfhSJeTUw7dAsiIq2UFPoLiouVuRmU0p1J1jeEa/wTdrtMkdt53HbOgmT2d9LN5 8VHgeXX5knLQ+IHqs2ikwvNcxkLgYmQYhforYL1HZnOEtvhfExv7xKjAPfpDdHSI6cxJ sh57K0nKKKuVf9g3z6NgjLh+/+HXUqfNFnDqAOF6mQa59EDcRMOD7sGTlrYVqHqXEMFo PP+VtZa4mAOkRz8+CM2BpRwIWl8F4ZgUaRjc1aRwbqdsMNh9L2N9Q9X7c/j9H1rkRgbB iA== Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp2120.oracle.com with ESMTP id 2mxn0q0tfu-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 10 Oct 2018 00:10:56 +0000 Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0022.oracle.com (8.14.4/8.14.4) with ESMTP id w9A0Atjv008509 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 10 Oct 2018 00:10:55 GMT Received: from abhmp0020.oracle.com (abhmp0020.oracle.com [141.146.116.26]) by userv0121.oracle.com (8.14.4/8.13.8) with ESMTP id w9A0Askv020568; Wed, 10 Oct 2018 00:10:54 GMT Received: from localhost (/10.159.249.114) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 10 Oct 2018 00:10:54 +0000 Subject: [PATCH 02/25] xfs: refactor clonerange preparation into a separate helper From: "Darrick J. Wong" To: david@fromorbit.com, darrick.wong@oracle.com Cc: sandeen@redhat.com, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-unionfs@vger.kernel.org, linux-xfs@vger.kernel.org, linux-mm@kvack.org, linux-btrfs@vger.kernel.org, Dave Chinner , linux-fsdevel@vger.kernel.org, ocfs2-devel@oss.oracle.com Date: Tue, 09 Oct 2018 17:10:52 -0700 Message-ID: <153913025230.32295.8365539801924505278.stgit@magnolia> In-Reply-To: <153913023835.32295.13962696655740190941.stgit@magnolia> References: <153913023835.32295.13962696655740190941.stgit@magnolia> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9041 signatures=668706 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1807170000 definitions=main-1810100000 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: X-Virus-Scanned: ClamAV using ClamSMTP From: Darrick J. Wong Refactor all the reflink preparation steps into a separate helper that we'll use to land all the upcoming fixes for insufficient input checks. This rework also moves the invalidation of the destination range to the prep function so that it is done before the range is remapped. This ensures that nobody can access the data in range being remapped until the remap is complete. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/xfs_reflink.c | 101 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 27 deletions(-) diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 5289e22cb081..ebd65d3e31f3 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -1220,35 +1220,48 @@ xfs_iolock_two_inodes_and_break_layout( return 0; } +/* Unlock both inodes after they've been prepped for a range clone. */ +STATIC void +xfs_reflink_remap_unlock( + struct file *file_in, + struct file *file_out) +{ + struct inode *inode_in = file_inode(file_in); + struct xfs_inode *src = XFS_I(inode_in); + struct inode *inode_out = file_inode(file_out); + struct xfs_inode *dest = XFS_I(inode_out); + bool same_inode = (inode_in == inode_out); + + xfs_iunlock(dest, XFS_MMAPLOCK_EXCL); + if (!same_inode) + xfs_iunlock(src, XFS_MMAPLOCK_SHARED); + inode_unlock(inode_out); + if (!same_inode) + inode_unlock_shared(inode_in); +} + /* - * Link a range of blocks from one file to another. + * Prepare two files for range cloning. Upon a successful return both inodes + * will have the iolock and mmaplock held, the page cache of the out file + * will be truncated, and any leases on the out file will have been broken. + * Returns negative for error, 0 for nothing to do, and 1 for success. */ -int -xfs_reflink_remap_range( +STATIC int +xfs_reflink_remap_prep( struct file *file_in, loff_t pos_in, struct file *file_out, loff_t pos_out, - u64 len, + u64 *len, bool is_dedupe) { struct inode *inode_in = file_inode(file_in); struct xfs_inode *src = XFS_I(inode_in); struct inode *inode_out = file_inode(file_out); struct xfs_inode *dest = XFS_I(inode_out); - struct xfs_mount *mp = src->i_mount; bool same_inode = (inode_in == inode_out); - xfs_fileoff_t sfsbno, dfsbno; - xfs_filblks_t fsblen; - xfs_extlen_t cowextsize; ssize_t ret; - if (!xfs_sb_version_hasreflink(&mp->m_sb)) - return -EOPNOTSUPP; - - if (XFS_FORCED_SHUTDOWN(mp)) - return -EIO; - /* Lock both files against IO */ ret = xfs_iolock_two_inodes_and_break_layout(inode_in, inode_out); if (ret) @@ -1270,7 +1283,7 @@ xfs_reflink_remap_range( goto out_unlock; ret = vfs_clone_file_prep_inodes(inode_in, pos_in, inode_out, pos_out, - &len, is_dedupe); + len, is_dedupe); if (ret <= 0) goto out_unlock; @@ -1279,8 +1292,6 @@ xfs_reflink_remap_range( if (ret) goto out_unlock; - trace_xfs_reflink_remap_range(src, pos_in, len, dest, pos_out); - /* * Clear out post-eof preallocations because we don't have page cache * backing the delayed allocations and they'll never get freed on @@ -1297,6 +1308,51 @@ xfs_reflink_remap_range( if (ret) goto out_unlock; + /* Zap any page cache for the destination file's range. */ + truncate_inode_pages_range(&inode_out->i_data, pos_out, + PAGE_ALIGN(pos_out + *len) - 1); + return 1; +out_unlock: + xfs_reflink_remap_unlock(file_in, file_out); + return ret; +} + +/* + * Link a range of blocks from one file to another. + */ +int +xfs_reflink_remap_range( + struct file *file_in, + loff_t pos_in, + struct file *file_out, + loff_t pos_out, + u64 len, + bool is_dedupe) +{ + struct inode *inode_in = file_inode(file_in); + struct xfs_inode *src = XFS_I(inode_in); + struct inode *inode_out = file_inode(file_out); + struct xfs_inode *dest = XFS_I(inode_out); + struct xfs_mount *mp = src->i_mount; + xfs_fileoff_t sfsbno, dfsbno; + xfs_filblks_t fsblen; + xfs_extlen_t cowextsize; + ssize_t ret; + + if (!xfs_sb_version_hasreflink(&mp->m_sb)) + return -EOPNOTSUPP; + + if (XFS_FORCED_SHUTDOWN(mp)) + return -EIO; + + /* Prepare and then clone file data. */ + ret = xfs_reflink_remap_prep(file_in, pos_in, file_out, pos_out, + &len, is_dedupe); + if (ret <= 0) + return ret; + + trace_xfs_reflink_remap_range(src, pos_in, len, dest, pos_out); + dfsbno = XFS_B_TO_FSBT(mp, pos_out); sfsbno = XFS_B_TO_FSBT(mp, pos_in); fsblen = XFS_B_TO_FSB(mp, len); @@ -1305,10 +1361,6 @@ xfs_reflink_remap_range( if (ret) goto out_unlock; - /* Zap any page cache for the destination file's range. */ - truncate_inode_pages_range(&inode_out->i_data, pos_out, - PAGE_ALIGN(pos_out + len) - 1); - /* * Carry the cowextsize hint from src to dest if we're sharing the * entire source file to the entire destination file, the source file @@ -1325,12 +1377,7 @@ xfs_reflink_remap_range( is_dedupe); out_unlock: - xfs_iunlock(dest, XFS_MMAPLOCK_EXCL); - if (!same_inode) - xfs_iunlock(src, XFS_MMAPLOCK_SHARED); - inode_unlock(inode_out); - if (!same_inode) - inode_unlock_shared(inode_in); + xfs_reflink_remap_unlock(file_in, file_out); if (ret) trace_xfs_reflink_remap_range_error(dest, ret, _RET_IP_); return ret;