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=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham 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 79118C07E99 for ; Mon, 12 Jul 2021 04:12:45 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 1A8926101D for ; Mon, 12 Jul 2021 04:12:43 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1A8926101D Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=infradead.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 3816B6B0098; Mon, 12 Jul 2021 00:12:43 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 357FF6B009F; Mon, 12 Jul 2021 00:12:43 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 220E76B00A0; Mon, 12 Jul 2021 00:12:43 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id F3A776B0098 for ; Mon, 12 Jul 2021 00:12:42 -0400 (EDT) Received: from smtpin20.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay02.hostedemail.com (Postfix) with ESMTP id 26291230F1 for ; Mon, 12 Jul 2021 04:12:42 +0000 (UTC) X-FDA: 78352614564.20.A91F724 Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) by imf12.hostedemail.com (Postfix) with ESMTP id D190910000A8 for ; Mon, 12 Jul 2021 04:12:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=BmJF8mjcFHM1Tho8GqMXTNLfymCr4gvrm2oudpTxXSA=; b=gTJ0LYyqd55Z+xxgj1SAzN3q8e /awGm2D1SXng1S15wUuwCAaLhIWMzJc1mHtL8X+el1DH+dXLFQZpdHfXfTh6x1+jwzJ39fDuqC/xu CSia9bgMSvJkun+Rhebpv5tmXsBjzsDNdGPJ9FZkpAMyyQCiIKC70btOxGPh14zwbkm39CwhUMg03 44TW6Ys8+dt7FQLtujXruxYoRoDdHJreDUCiTCOYwAA6eW2kTM9K1wFA58o6so5AIDX7ElVaiPSTn S4x+8DEVQOcuauUE9rafYLdSMfvlsYXubWZUDrblfA8luQMCYUeKH7mlsVC9/emZxkGsi6+RMLUko t03c/S5Q==; Received: from willy by casper.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1m2nIY-00GrMA-LN; Mon, 12 Jul 2021 04:12:06 +0000 From: "Matthew Wilcox (Oracle)" To: linux-kernel@vger.kernel.org Cc: "Matthew Wilcox (Oracle)" , linux-mm@kvack.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v13 123/137] fs: Convert vfs_dedupe_file_range_compare to folios Date: Mon, 12 Jul 2021 04:06:47 +0100 Message-Id: <20210712030701.4000097-124-willy@infradead.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210712030701.4000097-1-willy@infradead.org> References: <20210712030701.4000097-1-willy@infradead.org> MIME-Version: 1.0 Authentication-Results: imf12.hostedemail.com; dkim=pass header.d=infradead.org header.s=casper.20170209 header.b=gTJ0LYyq; spf=none (imf12.hostedemail.com: domain of willy@infradead.org has no SPF policy when checking 90.155.50.34) smtp.mailfrom=willy@infradead.org; dmarc=none X-Stat-Signature: 4xijtwyj3x4ukq71tdjwgaipxk87dr1b X-Rspamd-Queue-Id: D190910000A8 X-Rspamd-Server: rspam01 X-HE-Tag: 1626063161-175688 Content-Transfer-Encoding: quoted-printable 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: We still only operate on a single page of data at a time due to using kmap(). A more complex implementation would work on each page in a folio= , but it's not clear that such a complex implementation would be worthwhile= . Signed-off-by: Matthew Wilcox (Oracle) --- fs/remap_range.c | 116 ++++++++++++++++++++++------------------------- 1 file changed, 55 insertions(+), 61 deletions(-) diff --git a/fs/remap_range.c b/fs/remap_range.c index e4a5fdd7ad7b..da50f87e83e7 100644 --- a/fs/remap_range.c +++ b/fs/remap_range.c @@ -158,41 +158,41 @@ static int generic_remap_check_len(struct inode *in= ode_in, } =20 /* Read a page's worth of file data into the page cache. */ -static struct page *vfs_dedupe_get_page(struct inode *inode, loff_t offs= et) +static struct folio *vfs_dedupe_get_folio(struct inode *inode, loff_t po= s) { - struct page *page; + struct folio *folio; =20 - page =3D read_mapping_page(inode->i_mapping, offset >> PAGE_SHIFT, NULL= ); - if (IS_ERR(page)) - return page; - if (!PageUptodate(page)) { - put_page(page); + folio =3D read_mapping_folio(inode->i_mapping, pos >> PAGE_SHIFT, NULL)= ; + if (IS_ERR(folio)) + return folio; + if (!folio_uptodate(folio)) { + folio_put(folio); return ERR_PTR(-EIO); } - return page; + return folio; } =20 /* - * Lock two pages, ensuring that we lock in offset order if the pages ar= e from - * the same file. + * Lock two folios, ensuring that we lock in offset order if the folios + * are from the same file. */ -static void vfs_lock_two_pages(struct page *page1, struct page *page2) +static void vfs_lock_two_folios(struct folio *folio1, struct folio *foli= o2) { /* Always lock in order of increasing index. */ - if (page1->index > page2->index) - swap(page1, page2); + if (folio1->index > folio2->index) + swap(folio1, folio2); =20 - lock_page(page1); - if (page1 !=3D page2) - lock_page(page2); + folio_lock(folio1); + if (folio1 !=3D folio2) + folio_lock(folio2); } =20 -/* Unlock two pages, being careful not to unlock the same page twice. */ -static void vfs_unlock_two_pages(struct page *page1, struct page *page2) +/* Unlock two folios, being careful not to unlock the same folio twice. = */ +static void vfs_unlock_two_folios(struct folio *folio1, struct folio *fo= lio2) { - unlock_page(page1); - if (page1 !=3D page2) - unlock_page(page2); + folio_unlock(folio1); + if (folio1 !=3D folio2) + folio_unlock(folio2); } =20 /* @@ -200,77 +200,71 @@ static void vfs_unlock_two_pages(struct page *page1= , struct page *page2) * Caller must have locked both inodes to prevent write races. */ static int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcof= f, - struct inode *dest, loff_t destoff, + struct inode *dest, loff_t dstoff, loff_t len, bool *is_same) { - loff_t src_poff; - loff_t dest_poff; - void *src_addr; - void *dest_addr; - struct page *src_page; - struct page *dest_page; - loff_t cmp_len; - bool same; - int error; - - error =3D -EINVAL; - same =3D true; + bool same =3D true; + int error =3D -EINVAL; + while (len) { - src_poff =3D srcoff & (PAGE_SIZE - 1); - dest_poff =3D destoff & (PAGE_SIZE - 1); - cmp_len =3D min(PAGE_SIZE - src_poff, - PAGE_SIZE - dest_poff); + struct folio *src_folio, *dst_folio; + void *src_addr, *dst_addr; + loff_t cmp_len =3D min(PAGE_SIZE - offset_in_page(srcoff), + PAGE_SIZE - offset_in_page(dstoff)); + cmp_len =3D min(cmp_len, len); if (cmp_len <=3D 0) goto out_error; =20 - src_page =3D vfs_dedupe_get_page(src, srcoff); - if (IS_ERR(src_page)) { - error =3D PTR_ERR(src_page); + src_folio =3D vfs_dedupe_get_folio(src, srcoff); + if (IS_ERR(src_folio)) { + error =3D PTR_ERR(src_folio); goto out_error; } - dest_page =3D vfs_dedupe_get_page(dest, destoff); - if (IS_ERR(dest_page)) { - error =3D PTR_ERR(dest_page); - put_page(src_page); + dst_folio =3D vfs_dedupe_get_folio(dest, dstoff); + if (IS_ERR(dst_folio)) { + error =3D PTR_ERR(dst_folio); + folio_put(src_folio); goto out_error; } =20 - vfs_lock_two_pages(src_page, dest_page); + vfs_lock_two_folios(src_folio, dst_folio); =20 /* - * Now that we've locked both pages, make sure they're still + * Now that we've locked both folios, make sure they're still * mapped to the file data we're interested in. If not, * someone is invalidating pages on us and we lose. */ - if (!PageUptodate(src_page) || !PageUptodate(dest_page) || - src_page->mapping !=3D src->i_mapping || - dest_page->mapping !=3D dest->i_mapping) { + if (!folio_uptodate(src_folio) || !folio_uptodate(dst_folio) || + src_folio->mapping !=3D src->i_mapping || + dst_folio->mapping !=3D dest->i_mapping) { same =3D false; goto unlock; } =20 - src_addr =3D kmap_atomic(src_page); - dest_addr =3D kmap_atomic(dest_page); + src_addr =3D kmap_local_folio(src_folio, + offset_in_folio(src_folio, srcoff)); + dst_addr =3D kmap_local_folio(dst_folio, + offset_in_folio(dst_folio, dstoff)); =20 - flush_dcache_page(src_page); - flush_dcache_page(dest_page); + flush_dcache_folio(src_folio); + flush_dcache_folio(dst_folio); =20 - if (memcmp(src_addr + src_poff, dest_addr + dest_poff, cmp_len)) + if (memcmp(src_addr, dst_addr, cmp_len)) same =3D false; =20 - kunmap_atomic(dest_addr); - kunmap_atomic(src_addr); + kunmap_local(dst_addr); + kunmap_local(src_addr); unlock: - vfs_unlock_two_pages(src_page, dest_page); - put_page(dest_page); - put_page(src_page); + vfs_unlock_two_folios(src_folio, dst_folio); + folio_put(dst_folio); + folio_put(src_folio); =20 if (!same) break; =20 srcoff +=3D cmp_len; - destoff +=3D cmp_len; + dstoff +=3D cmp_len; len -=3D cmp_len; } =20 --=20 2.30.2