xref: /linux/fs/verity/pagecache.c (revision 23eec9fd64b2889286f31340371d67babfe54155)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright 2019 Google LLC
4  */
5 
6 #include <linux/fsverity.h>
7 #include <linux/pagemap.h>
8 
9 /**
10  * generic_read_merkle_tree_page - generic ->read_merkle_tree_page helper
11  * @inode:	inode containing the Merkle tree
12  * @index:	0-based index of the Merkle tree page in the inode
13  * @num_ra_pages: The number of Merkle tree pages that should be prefetched.
14  *
15  * The caller needs to adjust @index from the Merkle-tree relative index passed
16  * to ->read_merkle_tree_page to the actual index where the Merkle tree is
17  * stored in the page cache for @inode.
18  */
19 struct page *generic_read_merkle_tree_page(struct inode *inode, pgoff_t index,
20 					   unsigned long num_ra_pages)
21 {
22 	struct folio *folio;
23 
24 	folio = __filemap_get_folio(inode->i_mapping, index, FGP_ACCESSED, 0);
25 	if (folio == ERR_PTR(-ENOENT) ||
26 	    (!IS_ERR(folio) && !folio_test_uptodate(folio))) {
27 		DEFINE_READAHEAD(ractl, NULL, NULL, inode->i_mapping, index);
28 
29 		if (!IS_ERR(folio))
30 			folio_put(folio);
31 		else if (num_ra_pages > 1)
32 			page_cache_ra_unbounded(&ractl, num_ra_pages, 0);
33 		folio = read_mapping_folio(inode->i_mapping, index, NULL);
34 	}
35 	if (IS_ERR(folio))
36 		return ERR_CAST(folio);
37 	return folio_file_page(folio, index);
38 }
39 EXPORT_SYMBOL_GPL(generic_read_merkle_tree_page);
40