From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.8 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 14F3CC433B4 for ; Thu, 8 Apr 2021 22:33:43 +0000 (UTC) Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A84536115C for ; Thu, 8 Apr 2021 22:33:41 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A84536115C Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-nvdimm-bounces@lists.01.org Received: from ml01.vlan13.01.org (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 5E979100EAB66; Thu, 8 Apr 2021 15:33:41 -0700 (PDT) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=198.145.29.99; helo=mail.kernel.org; envelope-from=djwong@kernel.org; receiver= Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id CA1E1100EAB60 for ; Thu, 8 Apr 2021 15:33:38 -0700 (PDT) Received: by mail.kernel.org (Postfix) with ESMTPSA id D714D61159; Thu, 8 Apr 2021 22:33:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1617921217; bh=pIXAWdF4etfveY6DyHQCkA+BjDO7SA9GuyWMh9fzC0g=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=WOIr5mS5WEysTPC18xj8DCO8gqONd0fl/7BAVpA1SonKsPea6YsWA9r7wgozZn/oe hDE4LIv9N0OfEBSRSLN8nBew5ZVuBm1LOc97wE4Z9A3YU/GzcTekvpEBdp7RZKxSjZ deA7+2v5wNS373EGXYYDVQRNixHDHpp+MYpGcAssTawo3UjHY+CEFadwOGwMVaRQD3 PFaBgQU9s5teamwtSyMBAfLe5OcJEKOuG42sQzeqrdpQilq2nA+lrvHl2TJKawHo3p AxQoTgqItF9KSb8PI2gxOv4XDZ32vNf6sEj4Y5oOZJS/tXvR2Zjnpk+E4TBe7d3uSC 7unxF5liYi5Ng== Date: Thu, 8 Apr 2021 15:33:36 -0700 From: "Darrick J. Wong" To: Shiyang Ruan Subject: Re: [PATCH v4 5/7] fsdax: Dedup file range to use a compare function Message-ID: <20210408223336.GB3957620@magnolia> References: <20210408120432.1063608-1-ruansy.fnst@fujitsu.com> <20210408120432.1063608-6-ruansy.fnst@fujitsu.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20210408120432.1063608-6-ruansy.fnst@fujitsu.com> Message-ID-Hash: QW65XJ5NTCXCYLACNBS2O23C24LMQGHG X-Message-ID-Hash: QW65XJ5NTCXCYLACNBS2O23C24LMQGHG X-MailFrom: djwong@kernel.org X-Mailman-Rule-Hits: nonmember-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation CC: linux-kernel@vger.kernel.org, linux-xfs@vger.kernel.org, linux-nvdimm@lists.01.org, linux-fsdevel@vger.kernel.org, darrick.wong@oracle.com, willy@infradead.org, jack@suse.cz, viro@zeniv.linux.org.uk, linux-btrfs@vger.kernel.org, david@fromorbit.com, hch@lst.de, rgoldwyn@suse.de, Goldwyn Rodrigues X-Mailman-Version: 3.1.1 Precedence: list List-Id: "Linux-nvdimm developer list." Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit On Thu, Apr 08, 2021 at 08:04:30PM +0800, Shiyang Ruan wrote: > With dax we cannot deal with readpage() etc. So, we create a dax > comparison funciton which is similar with > vfs_dedupe_file_range_compare(). > And introduce dax_remap_file_range_prep() for filesystem use. > > Signed-off-by: Goldwyn Rodrigues > Signed-off-by: Shiyang Ruan > --- > fs/dax.c | 56 ++++++++++++++++++++++++++++++++++++++++++++ > fs/remap_range.c | 45 ++++++++++++++++++++++++++++------- > fs/xfs/xfs_reflink.c | 9 +++++-- > include/linux/dax.h | 4 ++++ > include/linux/fs.h | 12 ++++++---- > 5 files changed, 112 insertions(+), 14 deletions(-) > > diff --git a/fs/dax.c b/fs/dax.c > index fcd1e932716e..ba924b6629a6 100644 > --- a/fs/dax.c > +++ b/fs/dax.c > @@ -1849,3 +1849,59 @@ vm_fault_t dax_finish_sync_fault(struct vm_fault *vmf, > return dax_insert_pfn_mkwrite(vmf, pfn, order); > } > EXPORT_SYMBOL_GPL(dax_finish_sync_fault); > + > +static loff_t dax_range_compare_actor(struct inode *ino1, loff_t pos1, > + struct inode *ino2, loff_t pos2, loff_t len, void *data, > + struct iomap *smap, struct iomap *dmap) > +{ > + void *saddr, *daddr; > + bool *same = data; > + int ret; > + > + if (smap->type == IOMAP_HOLE && dmap->type == IOMAP_HOLE) { > + *same = true; > + return len; > + } > + > + if (smap->type == IOMAP_HOLE || dmap->type == IOMAP_HOLE) { > + *same = false; > + return 0; > + } > + > + ret = dax_iomap_direct_access(smap, pos1, ALIGN(pos1 + len, PAGE_SIZE), > + &saddr, NULL); > + if (ret < 0) > + return -EIO; > + > + ret = dax_iomap_direct_access(dmap, pos2, ALIGN(pos2 + len, PAGE_SIZE), > + &daddr, NULL); > + if (ret < 0) > + return -EIO; > + > + *same = !memcmp(saddr, daddr, len); > + return len; > +} > + > +int dax_dedupe_file_range_compare(struct inode *src, loff_t srcoff, > + struct inode *dest, loff_t destoff, loff_t len, bool *is_same, > + const struct iomap_ops *ops) > +{ > + int id, ret = 0; > + > + id = dax_read_lock(); > + while (len) { > + ret = iomap_apply2(src, srcoff, dest, destoff, len, 0, ops, > + is_same, dax_range_compare_actor); > + if (ret < 0 || !*is_same) > + goto out; > + > + len -= ret; > + srcoff += ret; > + destoff += ret; > + } > + ret = 0; > +out: > + dax_read_unlock(id); > + return ret; > +} > +EXPORT_SYMBOL_GPL(dax_dedupe_file_range_compare); > diff --git a/fs/remap_range.c b/fs/remap_range.c > index e4a5fdd7ad7b..1fab0db49c68 100644 > --- a/fs/remap_range.c > +++ b/fs/remap_range.c > @@ -14,6 +14,7 @@ > #include > #include > #include > +#include > #include "internal.h" > > #include > @@ -199,9 +200,9 @@ static void vfs_unlock_two_pages(struct page *page1, struct page *page2) > * Compare extents of two files to see if they are the same. > * Caller must have locked both inodes to prevent write races. > */ > -static int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcoff, > - struct inode *dest, loff_t destoff, > - loff_t len, bool *is_same) > +int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcoff, > + struct inode *dest, loff_t destoff, > + loff_t len, bool *is_same) > { > loff_t src_poff; > loff_t dest_poff; > @@ -280,6 +281,7 @@ static int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcoff, > out_error: > return error; > } > +EXPORT_SYMBOL(vfs_dedupe_file_range_compare); > > /* > * Check that the two inodes are eligible for cloning, the ranges make > @@ -289,9 +291,11 @@ static int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcoff, > * If there's an error, then the usual negative error code is returned. > * Otherwise returns 0 with *len set to the request length. > */ > -int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in, > - struct file *file_out, loff_t pos_out, > - loff_t *len, unsigned int remap_flags) > +static int > +__generic_remap_file_range_prep(struct file *file_in, loff_t pos_in, > + struct file *file_out, loff_t pos_out, > + loff_t *len, unsigned int remap_flags, > + const struct iomap_ops *ops) Can we rename @ops to @dax_read_ops instead? > { > struct inode *inode_in = file_inode(file_in); > struct inode *inode_out = file_inode(file_out); > @@ -351,8 +355,15 @@ int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in, > if (remap_flags & REMAP_FILE_DEDUP) { > bool is_same = false; > > - ret = vfs_dedupe_file_range_compare(inode_in, pos_in, > - inode_out, pos_out, *len, &is_same); > + if (!IS_DAX(inode_in) && !IS_DAX(inode_out)) If we already checked that IS_DAX(inode_in) == IS_DAX(inode_out), then can we only check one of these? if (!IS_DAX(inode_in)) ret = vfs_dedupe_file_range_compare(...); else if (dax_compare_ops) ret = dax_dedupe_file_range_compare(...); else ret = -EINVAL; > + ret = vfs_dedupe_file_range_compare(inode_in, pos_in, > + inode_out, pos_out, *len, &is_same); > + else if (IS_DAX(inode_in) && IS_DAX(inode_out) && ops) > + ret = dax_dedupe_file_range_compare(inode_in, pos_in, > + inode_out, pos_out, *len, &is_same, > + ops); > + else > + return -EINVAL; > if (ret) > return ret; > if (!is_same) > @@ -370,6 +381,24 @@ int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in, > > return ret; > } > + > +int dax_remap_file_range_prep(struct file *file_in, loff_t pos_in, > + struct file *file_out, loff_t pos_out, > + loff_t *len, unsigned int remap_flags, > + const struct iomap_ops *ops) > +{ > + return __generic_remap_file_range_prep(file_in, pos_in, file_out, > + pos_out, len, remap_flags, ops); > +} > +EXPORT_SYMBOL(dax_remap_file_range_prep); > + > +int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in, > + struct file *file_out, loff_t pos_out, > + loff_t *len, unsigned int remap_flags) > +{ > + return __generic_remap_file_range_prep(file_in, pos_in, file_out, > + pos_out, len, remap_flags, NULL); > +} > EXPORT_SYMBOL(generic_remap_file_range_prep); > > loff_t do_clone_file_range(struct file *file_in, loff_t pos_in, > diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c > index 725c7d8e4438..9ef9f98725a2 100644 > --- a/fs/xfs/xfs_reflink.c > +++ b/fs/xfs/xfs_reflink.c > @@ -1329,8 +1329,13 @@ xfs_reflink_remap_prep( > if (IS_DAX(inode_in) || IS_DAX(inode_out)) > goto out_unlock; > > - ret = generic_remap_file_range_prep(file_in, pos_in, file_out, pos_out, > - len, remap_flags); > + if (!IS_DAX(inode_in)) > + ret = generic_remap_file_range_prep(file_in, pos_in, file_out, > + pos_out, len, remap_flags); > + else > + ret = dax_remap_file_range_prep(file_in, pos_in, file_out, > + pos_out, len, remap_flags, > + &xfs_read_iomap_ops); > if (ret || *len == 0) > goto out_unlock; > > diff --git a/include/linux/dax.h b/include/linux/dax.h > index 3275e01ed33d..32e1c34349f2 100644 > --- a/include/linux/dax.h > +++ b/include/linux/dax.h > @@ -239,6 +239,10 @@ int dax_invalidate_mapping_entry_sync(struct address_space *mapping, > pgoff_t index); > s64 dax_iomap_zero(loff_t pos, u64 length, struct iomap *iomap, > struct iomap *srcmap); > +int dax_dedupe_file_range_compare(struct inode *src, loff_t srcoff, > + struct inode *dest, loff_t destoff, > + loff_t len, bool *is_same, > + const struct iomap_ops *ops); What happens if dax isn't enabled in the kernel build? --D > static inline bool dax_mapping(struct address_space *mapping) > { > return mapping->host && IS_DAX(mapping->host); > diff --git a/include/linux/fs.h b/include/linux/fs.h > index ec8f3ddf4a6a..28861e334dac 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -70,6 +70,7 @@ struct fsverity_info; > struct fsverity_operations; > struct fs_context; > struct fs_parameter_spec; > +struct iomap_ops; > > extern void __init inode_init(void); > extern void __init inode_init_early(void); > @@ -1989,10 +1990,13 @@ extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *, > 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, > - unsigned int remap_flags); > +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, unsigned int remap_flags); > +int dax_remap_file_range_prep(struct file *file_in, loff_t pos_in, > + struct file *file_out, loff_t pos_out, > + loff_t *len, unsigned int remap_flags, > + const struct iomap_ops *ops); > extern 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); > -- > 2.31.0 > > > _______________________________________________ Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org To unsubscribe send an email to linux-nvdimm-leave@lists.01.org