81 lines
2.5 KiB
C
81 lines
2.5 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright 2019 Google LLC
|
|
*/
|
|
#include "fsverity_private.h"
|
|
|
|
#include <linux/export.h>
|
|
#include <linux/fsverity.h>
|
|
#include <linux/pagemap.h>
|
|
|
|
/**
|
|
* generic_read_merkle_tree_page - generic ->read_merkle_tree_page helper
|
|
* @inode: inode containing the Merkle tree
|
|
* @index: 0-based index of the Merkle tree page in the inode
|
|
*
|
|
* The caller needs to adjust @index from the Merkle-tree relative index passed
|
|
* to ->read_merkle_tree_page to the actual index where the Merkle tree is
|
|
* stored in the page cache for @inode.
|
|
*/
|
|
struct page *generic_read_merkle_tree_page(struct inode *inode, pgoff_t index)
|
|
{
|
|
struct folio *folio;
|
|
|
|
folio = read_mapping_folio(inode->i_mapping, index, NULL);
|
|
if (IS_ERR(folio))
|
|
return ERR_CAST(folio);
|
|
return folio_file_page(folio, index);
|
|
}
|
|
EXPORT_SYMBOL_GPL(generic_read_merkle_tree_page);
|
|
|
|
/**
|
|
* generic_readahead_merkle_tree() - generic ->readahead_merkle_tree helper
|
|
* @inode: inode containing the Merkle tree
|
|
* @index: 0-based index of the first Merkle tree page to read ahead in the
|
|
* inode
|
|
* @nr_pages: the number of Merkle tree pages that should be read ahead
|
|
*
|
|
* The caller needs to adjust @index from the Merkle-tree relative index passed
|
|
* to ->read_merkle_tree_page to the actual index where the Merkle tree is
|
|
* stored in the page cache for @inode.
|
|
*/
|
|
void generic_readahead_merkle_tree(struct inode *inode, pgoff_t index,
|
|
unsigned long nr_pages)
|
|
{
|
|
struct folio *folio;
|
|
|
|
lockdep_assert_held(&inode->i_mapping->invalidate_lock);
|
|
|
|
folio = __filemap_get_folio(inode->i_mapping, index, FGP_ACCESSED, 0);
|
|
if (folio == ERR_PTR(-ENOENT) ||
|
|
(!IS_ERR(folio) && !folio_test_uptodate(folio))) {
|
|
DEFINE_READAHEAD(ractl, NULL, NULL, inode->i_mapping, index);
|
|
|
|
page_cache_ra_unbounded(&ractl, nr_pages, 0);
|
|
}
|
|
if (!IS_ERR(folio))
|
|
folio_put(folio);
|
|
}
|
|
EXPORT_SYMBOL_GPL(generic_readahead_merkle_tree);
|
|
|
|
/**
|
|
* fsverity_fill_zerohash() - fill folio with hashes of zero data block
|
|
* @folio: folio to fill
|
|
* @offset: offset in the folio to start
|
|
* @len: length of the range to fill with hashes
|
|
* @vi: fsverity info
|
|
*/
|
|
void fsverity_fill_zerohash(struct folio *folio, size_t offset, size_t len,
|
|
struct fsverity_info *vi)
|
|
{
|
|
size_t off = offset;
|
|
|
|
WARN_ON_ONCE(!IS_ALIGNED(offset, vi->tree_params.digest_size));
|
|
WARN_ON_ONCE(!IS_ALIGNED(len, vi->tree_params.digest_size));
|
|
|
|
for (; off < (offset + len); off += vi->tree_params.digest_size)
|
|
memcpy_to_folio(folio, off, vi->tree_params.zero_digest,
|
|
vi->tree_params.digest_size);
|
|
}
|
|
EXPORT_SYMBOL_GPL(fsverity_fill_zerohash);
|