[PATCH v14 05/21] fsverity: improve flushing performance of fsverity_fill_zerohash

Andrey Albershteyn via Linux-f2fs-devel <[email protected]>
Newsgroups gmane.linux.file-systems.f2fs,gmane.linux.file-systems,gmane.comp.file-systems.ext4,gmane.comp.file-systems.btrfs
Message-ID <[email protected]>
The current version calls flush_dcache_folio(), in memcpy_to_folio(), to
flush whole folio on every digest (which is 128 for 4k) on the HIGHMEM
systems. Open code folio mapping and flushing to copy all digests at
once.

Reported-by: Eric Biggers <[email protected]>
Link: https://lore.kernel.org/linux-fsdevel/20260401222717.GH2466@quark/
Signed-off-by: Andrey Albershteyn <[email protected]>
---
 fs/verity/pagecache.c | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/fs/verity/pagecache.c b/fs/verity/pagecache.c
index 9d82e6b74ba1..911207dc0ef7 100644
--- a/fs/verity/pagecache.c
+++ b/fs/verity/pagecache.c
@@ -68,14 +68,38 @@ EXPORT_SYMBOL_GPL(generic_readahead_merkle_tree);
 void fsverity_fill_zerohash(struct folio *folio, size_t offset, size_t len,
 			      struct fsverity_info *vi)
 {
-	size_t off = offset;
+	size_t off;
 
 	WARN_ON_ONCE(!IS_ALIGNED(offset, vi->tree_params.digest_size));
 	WARN_ON_ONCE(!IS_ALIGNED(len, vi->tree_params.digest_size));
+#ifdef CONFIG_HIGHMEM
+	WARN_ON_ONCE(offset + len > folio_size(folio));
 
-	for (; off < (offset + len); off += vi->tree_params.digest_size)
+	do {
+		void *vaddr = kmap_local_folio(folio, offset);
+		void *to = vaddr;
+
+		off = len;
+
+		if (folio_test_partial_kmap(folio) &&
+		    off > PAGE_SIZE - offset_in_page(offset))
+			off = PAGE_SIZE - offset_in_page(offset);
+		for (; to < (vaddr + off); to += vi->tree_params.digest_size)
+			memcpy(to, vi->tree_params.zero_digest,
+				vi->tree_params.digest_size);
+		kunmap_local(vaddr);
+
+		offset += off;
+		len -= off;
+	} while (len > 0);
+
+	flush_dcache_folio(folio);
+#else
+	for (off = offset; off < (offset + len);
+			off += vi->tree_params.digest_size)
 		memcpy_to_folio(folio, off, vi->tree_params.zero_digest,
 				vi->tree_params.digest_size);
+#endif
 }
 EXPORT_SYMBOL_GPL(fsverity_fill_zerohash);
 
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.