diff mbox series

[05/18] fsverity: pass the merkle tree block level to fsverity_read_merkle_tree_block

Message ID 171444679675.955480.12163095281875879169.stgit@frogsfrogsfrogs (mailing list archive)
State New, archived
Headers show
Series [01/18] fs: add FS_XFLAG_VERITY for verity files | expand

Commit Message

Darrick J. Wong April 30, 2024, 3:20 a.m. UTC
From: Darrick J. Wong <djwong@kernel.org>

The XFS fsverity implementation will cache merkle tree blocks on its
own.  It would be great if the shrinker that will be associated with
this cache could guesstimate the amount of pain associated with
reclaiming a cached merkle tree block.  We can use the tree level of a
block as this guesstimate, so export this information if we have it.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 fs/verity/fsverity_private.h |    2 +-
 fs/verity/read_metadata.c    |    1 +
 fs/verity/verify.c           |   11 ++++++++---
 include/linux/fsverity.h     |    7 +++++++
 4 files changed, 17 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/fs/verity/fsverity_private.h b/fs/verity/fsverity_private.h
index 8a41e27413284..c1f82a0ea4cfa 100644
--- a/fs/verity/fsverity_private.h
+++ b/fs/verity/fsverity_private.h
@@ -156,7 +156,7 @@  void __init fsverity_init_workqueue(void);
 
 int fsverity_read_merkle_tree_block(struct inode *inode,
 				    const struct merkle_tree_params *params,
-				    u64 pos, unsigned long ra_bytes,
+				    int level, u64 pos, unsigned long ra_bytes,
 				    struct fsverity_blockbuf *block);
 
 void fsverity_drop_merkle_tree_block(struct inode *inode,
diff --git a/fs/verity/read_metadata.c b/fs/verity/read_metadata.c
index 4011a02f5d32d..3ec6230425d65 100644
--- a/fs/verity/read_metadata.c
+++ b/fs/verity/read_metadata.c
@@ -40,6 +40,7 @@  static int fsverity_read_merkle_tree(struct inode *inode,
 				      params->block_size - offs_in_block);
 
 		err = fsverity_read_merkle_tree_block(inode, &vi->tree_params,
+						      FSVERITY_STREAMING_READ,
 						      pos - offs_in_block,
 						      ra_bytes, &block);
 		if (err)
diff --git a/fs/verity/verify.c b/fs/verity/verify.c
index 55ada2af290ac..daf2057dbe839 100644
--- a/fs/verity/verify.c
+++ b/fs/verity/verify.c
@@ -183,8 +183,9 @@  verify_data_block(struct inode *inode, struct fsverity_info *vi,
 		else
 			ra_bytes = 0;
 
-		if (fsverity_read_merkle_tree_block(inode, params, hblock_pos,
-						    ra_bytes, block) != 0)
+		if (fsverity_read_merkle_tree_block(inode, params, level,
+						    hblock_pos, ra_bytes,
+						    block) != 0)
 			goto error;
 
 		if (is_hash_block_verified(inode, block, hblock_idx)) {
@@ -371,6 +372,8 @@  void __init fsverity_init_workqueue(void)
  * fsverity_read_merkle_tree_block() - read Merkle tree block
  * @inode: inode to which this Merkle tree block belongs
  * @params: merkle tree parameters
+ * @level: expected level of the block; level 0 are the leaves, -1 means a
+ * streaming read
  * @pos: byte position within merkle tree
  * @ra_bytes: try to read ahead this many bytes
  * @block: block to be loaded
@@ -379,7 +382,7 @@  void __init fsverity_init_workqueue(void)
  */
 int fsverity_read_merkle_tree_block(struct inode *inode,
 				    const struct merkle_tree_params *params,
-				    u64 pos, unsigned long ra_bytes,
+				    int level, u64 pos, unsigned long ra_bytes,
 				    struct fsverity_blockbuf *block)
 {
 	const struct fsverity_operations *vops = inode->i_sb->s_vop;
@@ -396,6 +399,8 @@  int fsverity_read_merkle_tree_block(struct inode *inode,
 	if (vops->read_merkle_tree_block) {
 		struct fsverity_readmerkle req = {
 			.inode = inode,
+			.level = level,
+			.num_levels = params->num_levels,
 			.ra_bytes = ra_bytes,
 		};
 
diff --git a/include/linux/fsverity.h b/include/linux/fsverity.h
index ad17f8553f9cf..15bf33be99d79 100644
--- a/include/linux/fsverity.h
+++ b/include/linux/fsverity.h
@@ -56,6 +56,9 @@  struct fsverity_blockbuf {
 /**
  * struct fsverity_readmerkle - Request to read a Merkle Tree block buffer
  * @inode: the inode to read
+ * @level: expected level of the block; level 0 are the leaves.
+ * 		A value of FSVERITY_STREAMING_READ means a streaming read.
+ * @num_levels: number of levels in the tree total
  * @ra_bytes: The number of bytes that should be prefetched starting at pos
  *		if the page at @block->offset isn't already cached.
  *		Implementations may ignore this argument; it's only a
@@ -64,8 +67,12 @@  struct fsverity_blockbuf {
 struct fsverity_readmerkle {
 	struct inode *inode;
 	unsigned long ra_bytes;
+	int level;
+	int num_levels;
 };
 
+#define FSVERITY_STREAMING_READ	(-1)
+
 /* Verity operations for filesystems */
 struct fsverity_operations {