All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Biggers <ebiggers@kernel.org>
To: Christoph Hellwig <hch@lst.de>
Cc: Al Viro <viro@zeniv.linux.org.uk>,
	Christian Brauner <brauner@kernel.org>, Jan Kara <jack@suse.cz>,
	David Sterba <dsterba@suse.com>, Theodore Ts'o <tytso@mit.edu>,
	Jaegeuk Kim <jaegeuk@kernel.org>, Chao Yu <chao@kernel.org>,
	Andrey Albershteyn <aalbersh@redhat.com>,
	"Matthew Wilcox (Oracle)" <willy@infradead.org>,
	linux-fsdevel@vger.kernel.org, linux-btrfs@vger.kernel.org,
	linux-ext4@vger.kernel.org,
	linux-f2fs-devel@lists.sourceforge.net, fsverity@lists.linux.dev
Subject: Re: [PATCH 05/11] fsverity: kick off hash readahead at data I/O submission time
Date: Sat, 24 Jan 2026 12:53:29 -0800	[thread overview]
Message-ID: <20260124205329.GE2762@quark> (raw)
In-Reply-To: <20260122082214.452153-6-hch@lst.de>

On Thu, Jan 22, 2026 at 09:22:01AM +0100, Christoph Hellwig wrote:
> +/**
> + * generic_readahead_merkle_tree() - generic ->readahead_merkle_tree helper
> + * @inode:	inode containing the Merkle tree
> + * @index:	0-based index of the first page to read ahead in the inode
> + * @nr_pages:	number of data pages to 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;
>  
>  	folio = __filemap_get_folio(inode->i_mapping, index, FGP_ACCESSED, 0);
> -	if (IS_ERR(folio) || !folio_test_uptodate(folio)) {
> +	if (PTR_ERR(folio) == -ENOENT || !folio_test_uptodate(folio)) {

This dereferences an ERR_PTR() when __filemap_get_folio() returns an
error other than -ENOENT.

> diff --git a/fs/verity/read_metadata.c b/fs/verity/read_metadata.c
> index cba5d6af4e04..430306abc4c6 100644
> --- a/fs/verity/read_metadata.c
> +++ b/fs/verity/read_metadata.c
> @@ -28,24 +28,24 @@ static int fsverity_read_merkle_tree(struct inode *inode,
>  	if (offset >= end_offset)
>  		return 0;
>  	offs_in_page = offset_in_page(offset);
> +	index = offset >> PAGE_SHIFT;
>  	last_index = (end_offset - 1) >> PAGE_SHIFT;
>  
> +	__fsverity_readahead(inode, vi, offset, last_index - index + 1);

This passes a position in the Merkle tree to a function that expects a
position in the file data.

I think the correct thing to do here would be the following:

        if (inode->i_sb->s_vop->readahead_merkle_tree)
		inode->i_sb->s_vop->readahead_merkle_tree(inode, index,
							  last_index - index + 1);

Then __fsverity_readahead() can be folded into fsverity_readahead().

> +void __fsverity_readahead(struct inode *inode, const struct fsverity_info *vi,
> +		loff_t data_start_pos, unsigned long nr_pages)
> +{
> +	const struct merkle_tree_params *params = &vi->tree_params;
> +	u64 start_hidx = data_start_pos >> params->log_blocksize;
> +	u64 end_hidx = (data_start_pos + ((nr_pages - 1) << PAGE_SHIFT)) >>
> +			params->log_blocksize;

(nr_pages - 1) << PAGE_SHIFT can overflow an 'unsigned long'.
(nr_pages - 1) needs to be cast to u64 before doing the shift.

But also it would make more sense to pass
(pgoff_t start_index, unsigned long nr_pages) instead of
(loff_t data_start_pos, unsigned long nr_pages),
so that the two numbers have the same units.

start_idx and end_hidx could then be computed as follows:

    u64 start_hidx = (u64)start_index << params->log_blocks_per_page;
    u64 end_hidx = (((u64)start_index + nr_pages) << params->log_blocks_per_page) - 1;

Note that fsverity_readahead() derives the position from the index.  If
it just used the index directly, that would be more direct.

> +	int level;
> +
> +	if (!inode->i_sb->s_vop->readahead_merkle_tree)
> +		return;
> +	if (unlikely(data_start_pos >= inode->i_size))
> +		return;

The check against i_size shouldn't be necessary: the caller should just
call this only for data it's actually going to read.

> +	for (level = 0; level < params->num_levels; level++) {
> +		unsigned long level_start = params->level_start[level];
> +		unsigned long next_start_hidx = start_hidx >> params->log_arity;
> +		unsigned long next_end_hidx = end_hidx >> params->log_arity;
> +		unsigned long start_idx = (level_start + next_start_hidx) >>
> +				params->log_blocks_per_page;
> +		unsigned long end_idx = (level_start + next_end_hidx) >>
> +				params->log_blocks_per_page;

start_idx and end_idx should have type pgoff_t to make it clear that
they're page indices.

> +EXPORT_SYMBOL_GPL(fsverity_readahead);

This should be below the definition of fsverity_readahead, not the
definition of __fsverity_readahead.

> +/**
> + * fsverity_readahead() - kick off readahead on fsverity hashes
> + * @folio:		first folio that is being read

folio => file data folio

Otherwise it can be confused with the Merkle tree.

> + * Start readahead on fsverity hashes.  To be called from the file systems
> + * ->read_folio and ->readahead methods to ensure that the hashes are
> + * already cached on completion of the file data read if possible.

Similarly, it would be helpful to clarify that the readahead is done on
the hashes *that will be needed to verify the specified file data*.
Otherwise it might sound like the caller is specifying the hashes to
readahead directly.

> +       /**
> +        * Perform readahad of a Merkle tree for the given inode.

readahad => readahead

- Eric

WARNING: multiple messages have this Message-ID (diff)
From: Eric Biggers via Linux-f2fs-devel <linux-f2fs-devel@lists.sourceforge.net>
To: Christoph Hellwig <hch@lst.de>
Cc: fsverity@lists.linux.dev, Christian Brauner <brauner@kernel.org>,
	Theodore Ts'o <tytso@mit.edu>,
	Andrey Albershteyn <aalbersh@redhat.com>,
	"Matthew Wilcox \(Oracle\)" <willy@infradead.org>,
	linux-f2fs-devel@lists.sourceforge.net,
	linux-fsdevel@vger.kernel.org, Al Viro <viro@zeniv.linux.org.uk>,
	Jaegeuk Kim <jaegeuk@kernel.org>, David Sterba <dsterba@suse.com>,
	Jan Kara <jack@suse.cz>,
	linux-ext4@vger.kernel.org, linux-btrfs@vger.kernel.org
Subject: Re: [f2fs-dev] [PATCH 05/11] fsverity: kick off hash readahead at data I/O submission time
Date: Sat, 24 Jan 2026 12:53:29 -0800	[thread overview]
Message-ID: <20260124205329.GE2762@quark> (raw)
In-Reply-To: <20260122082214.452153-6-hch@lst.de>

On Thu, Jan 22, 2026 at 09:22:01AM +0100, Christoph Hellwig wrote:
> +/**
> + * generic_readahead_merkle_tree() - generic ->readahead_merkle_tree helper
> + * @inode:	inode containing the Merkle tree
> + * @index:	0-based index of the first page to read ahead in the inode
> + * @nr_pages:	number of data pages to 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;
>  
>  	folio = __filemap_get_folio(inode->i_mapping, index, FGP_ACCESSED, 0);
> -	if (IS_ERR(folio) || !folio_test_uptodate(folio)) {
> +	if (PTR_ERR(folio) == -ENOENT || !folio_test_uptodate(folio)) {

This dereferences an ERR_PTR() when __filemap_get_folio() returns an
error other than -ENOENT.

> diff --git a/fs/verity/read_metadata.c b/fs/verity/read_metadata.c
> index cba5d6af4e04..430306abc4c6 100644
> --- a/fs/verity/read_metadata.c
> +++ b/fs/verity/read_metadata.c
> @@ -28,24 +28,24 @@ static int fsverity_read_merkle_tree(struct inode *inode,
>  	if (offset >= end_offset)
>  		return 0;
>  	offs_in_page = offset_in_page(offset);
> +	index = offset >> PAGE_SHIFT;
>  	last_index = (end_offset - 1) >> PAGE_SHIFT;
>  
> +	__fsverity_readahead(inode, vi, offset, last_index - index + 1);

This passes a position in the Merkle tree to a function that expects a
position in the file data.

I think the correct thing to do here would be the following:

        if (inode->i_sb->s_vop->readahead_merkle_tree)
		inode->i_sb->s_vop->readahead_merkle_tree(inode, index,
							  last_index - index + 1);

Then __fsverity_readahead() can be folded into fsverity_readahead().

> +void __fsverity_readahead(struct inode *inode, const struct fsverity_info *vi,
> +		loff_t data_start_pos, unsigned long nr_pages)
> +{
> +	const struct merkle_tree_params *params = &vi->tree_params;
> +	u64 start_hidx = data_start_pos >> params->log_blocksize;
> +	u64 end_hidx = (data_start_pos + ((nr_pages - 1) << PAGE_SHIFT)) >>
> +			params->log_blocksize;

(nr_pages - 1) << PAGE_SHIFT can overflow an 'unsigned long'.
(nr_pages - 1) needs to be cast to u64 before doing the shift.

But also it would make more sense to pass
(pgoff_t start_index, unsigned long nr_pages) instead of
(loff_t data_start_pos, unsigned long nr_pages),
so that the two numbers have the same units.

start_idx and end_hidx could then be computed as follows:

    u64 start_hidx = (u64)start_index << params->log_blocks_per_page;
    u64 end_hidx = (((u64)start_index + nr_pages) << params->log_blocks_per_page) - 1;

Note that fsverity_readahead() derives the position from the index.  If
it just used the index directly, that would be more direct.

> +	int level;
> +
> +	if (!inode->i_sb->s_vop->readahead_merkle_tree)
> +		return;
> +	if (unlikely(data_start_pos >= inode->i_size))
> +		return;

The check against i_size shouldn't be necessary: the caller should just
call this only for data it's actually going to read.

> +	for (level = 0; level < params->num_levels; level++) {
> +		unsigned long level_start = params->level_start[level];
> +		unsigned long next_start_hidx = start_hidx >> params->log_arity;
> +		unsigned long next_end_hidx = end_hidx >> params->log_arity;
> +		unsigned long start_idx = (level_start + next_start_hidx) >>
> +				params->log_blocks_per_page;
> +		unsigned long end_idx = (level_start + next_end_hidx) >>
> +				params->log_blocks_per_page;

start_idx and end_idx should have type pgoff_t to make it clear that
they're page indices.

> +EXPORT_SYMBOL_GPL(fsverity_readahead);

This should be below the definition of fsverity_readahead, not the
definition of __fsverity_readahead.

> +/**
> + * fsverity_readahead() - kick off readahead on fsverity hashes
> + * @folio:		first folio that is being read

folio => file data folio

Otherwise it can be confused with the Merkle tree.

> + * Start readahead on fsverity hashes.  To be called from the file systems
> + * ->read_folio and ->readahead methods to ensure that the hashes are
> + * already cached on completion of the file data read if possible.

Similarly, it would be helpful to clarify that the readahead is done on
the hashes *that will be needed to verify the specified file data*.
Otherwise it might sound like the caller is specifying the hashes to
readahead directly.

> +       /**
> +        * Perform readahad of a Merkle tree for the given inode.

readahad => readahead

- Eric


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

  parent reply	other threads:[~2026-01-24 20:53 UTC|newest]

Thread overview: 104+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-22  8:21 fsverity cleanups, speedup and memory usage optimization v2 Christoph Hellwig
2026-01-22  8:21 ` [f2fs-dev] " Christoph Hellwig
2026-01-22  8:21 ` [PATCH 01/11] fs,fsverity: reject size changes on fsverity files in setattr_prepare Christoph Hellwig
2026-01-22  8:21   ` [f2fs-dev] [PATCH 01/11] fs, fsverity: " Christoph Hellwig
2026-01-22  9:12   ` [PATCH 01/11] fs,fsverity: " Jan Kara
2026-01-22  9:12     ` [f2fs-dev] [PATCH 01/11] fs, fsverity: " Jan Kara
2026-01-22 21:21   ` [PATCH 01/11] fs,fsverity: " Darrick J. Wong
2026-01-22 21:21     ` [f2fs-dev] [PATCH 01/11] fs, fsverity: " Darrick J. Wong via Linux-f2fs-devel
2026-01-22  8:21 ` [PATCH 02/11] fs,fsverity: clear out fsverity_info from common code Christoph Hellwig
2026-01-22  8:21   ` [f2fs-dev] [PATCH 02/11] fs, fsverity: " Christoph Hellwig
2026-01-22  9:15   ` [PATCH 02/11] fs,fsverity: " Jan Kara
2026-01-22  9:15     ` [f2fs-dev] [PATCH 02/11] fs, fsverity: " Jan Kara
2026-01-22 21:22   ` [PATCH 02/11] fs,fsverity: " Darrick J. Wong
2026-01-22 21:22     ` [f2fs-dev] [PATCH 02/11] fs, fsverity: " Darrick J. Wong via Linux-f2fs-devel
2026-01-22  8:21 ` [PATCH 03/11] fsverity: pass struct file to ->write_merkle_tree_block Christoph Hellwig
2026-01-22  8:21   ` [f2fs-dev] " Christoph Hellwig
2026-01-22 10:04   ` Andrey Albershteyn
2026-01-22 10:04     ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-01-22 21:23   ` Darrick J. Wong
2026-01-22 21:23     ` [f2fs-dev] " Darrick J. Wong via Linux-f2fs-devel
2026-01-22  8:22 ` [PATCH 04/11] fsverity: start consolidating pagecache code Christoph Hellwig
2026-01-22  8:22   ` [f2fs-dev] " Christoph Hellwig
2026-01-22  9:18   ` Jan Kara
2026-01-22  9:18     ` [f2fs-dev] " Jan Kara
2026-01-22 10:12   ` Andrey Albershteyn
2026-01-22 10:12     ` [f2fs-dev] " Andrey Albershteyn via Linux-f2fs-devel
2026-01-22 21:27   ` Darrick J. Wong
2026-01-22 21:27     ` [f2fs-dev] " Darrick J. Wong via Linux-f2fs-devel
2026-01-23  5:12     ` Christoph Hellwig
2026-01-23  5:12       ` [f2fs-dev] " Christoph Hellwig
2026-01-23  7:21       ` Darrick J. Wong
2026-01-23  7:21         ` [f2fs-dev] " Darrick J. Wong via Linux-f2fs-devel
2026-01-24 19:27   ` Eric Biggers
2026-01-24 19:27     ` [f2fs-dev] " Eric Biggers via Linux-f2fs-devel
2026-01-26  4:27     ` Christoph Hellwig
2026-01-26  4:27       ` [f2fs-dev] " Christoph Hellwig
2026-01-22  8:22 ` [PATCH 05/11] fsverity: kick off hash readahead at data I/O submission time Christoph Hellwig
2026-01-22  8:22   ` [f2fs-dev] " Christoph Hellwig
2026-01-22 21:42   ` Darrick J. Wong
2026-01-22 21:42     ` [f2fs-dev] " Darrick J. Wong via Linux-f2fs-devel
2026-01-23  5:14     ` Christoph Hellwig
2026-01-23  5:14       ` [f2fs-dev] " Christoph Hellwig
2026-01-23  7:22       ` Darrick J. Wong
2026-01-23  7:22         ` [f2fs-dev] " Darrick J. Wong via Linux-f2fs-devel
2026-01-24 20:53   ` Eric Biggers [this message]
2026-01-24 20:53     ` Eric Biggers via Linux-f2fs-devel
2026-01-26  4:30     ` Christoph Hellwig
2026-01-26  4:30       ` [f2fs-dev] " Christoph Hellwig
2026-01-22  8:22 ` [PATCH 06/11] fsverity: push out fsverity_info lookup Christoph Hellwig
2026-01-22  8:22   ` [f2fs-dev] " Christoph Hellwig
2026-01-22 21:45   ` Darrick J. Wong
2026-01-22 21:45     ` [f2fs-dev] " Darrick J. Wong via Linux-f2fs-devel
2026-01-24 21:19   ` Eric Biggers
2026-01-24 21:19     ` [f2fs-dev] " Eric Biggers via Linux-f2fs-devel
2026-01-26  4:33     ` Christoph Hellwig
2026-01-26  4:33       ` [f2fs-dev] " Christoph Hellwig
2026-01-22  8:22 ` [PATCH 07/11] fs: consolidate fsverity_info lookup in buffer.c Christoph Hellwig
2026-01-22  8:22   ` [f2fs-dev] " Christoph Hellwig
2026-01-22 21:49   ` Darrick J. Wong
2026-01-22 21:49     ` [f2fs-dev] " Darrick J. Wong via Linux-f2fs-devel
2026-01-23  5:15     ` Christoph Hellwig
2026-01-23  5:15       ` [f2fs-dev] " Christoph Hellwig
2026-01-23  7:23       ` Darrick J. Wong
2026-01-23  7:23         ` [f2fs-dev] " Darrick J. Wong via Linux-f2fs-devel
2026-01-23  7:24         ` Christoph Hellwig
2026-01-23  7:24           ` [f2fs-dev] " Christoph Hellwig
2026-01-22  8:22 ` [PATCH 08/11] ext4: consolidate fsverity_info lookup Christoph Hellwig
2026-01-22  8:22   ` [f2fs-dev] " Christoph Hellwig
2026-01-22 21:54   ` Darrick J. Wong
2026-01-22 21:54     ` [f2fs-dev] " Darrick J. Wong via Linux-f2fs-devel
2026-01-23  5:18     ` Christoph Hellwig
2026-01-23  5:18       ` [f2fs-dev] " Christoph Hellwig
2026-01-23  7:25       ` Darrick J. Wong
2026-01-23  7:25         ` [f2fs-dev] " Darrick J. Wong via Linux-f2fs-devel
2026-01-22  8:22 ` [PATCH 09/11] f2fs: " Christoph Hellwig
2026-01-22  8:22   ` [f2fs-dev] " Christoph Hellwig
2026-01-22  8:22 ` [PATCH 10/11] btrfs: " Christoph Hellwig
2026-01-22  8:22   ` [f2fs-dev] " Christoph Hellwig
2026-01-22  8:22 ` [PATCH 11/11] fsverity: use a hashtable to find the fsverity_info Christoph Hellwig
2026-01-22  8:22   ` [f2fs-dev] " Christoph Hellwig
2026-01-22 22:04   ` Darrick J. Wong
2026-01-22 22:04     ` [f2fs-dev] " Darrick J. Wong via Linux-f2fs-devel
2026-01-23  5:27     ` Christoph Hellwig
2026-01-23  5:27       ` [f2fs-dev] " Christoph Hellwig
2026-01-23  7:27       ` Darrick J. Wong
2026-01-23  7:27         ` [f2fs-dev] " Darrick J. Wong via Linux-f2fs-devel
2026-01-23  7:30         ` Christoph Hellwig
2026-01-23  7:30           ` [f2fs-dev] " Christoph Hellwig
2026-01-25  1:31   ` Eric Biggers
2026-01-25  1:31     ` [f2fs-dev] " Eric Biggers via Linux-f2fs-devel
2026-01-25 21:48     ` Matthew Wilcox
2026-01-25 21:48       ` [f2fs-dev] " Matthew Wilcox
2026-01-26  4:44       ` Christoph Hellwig
2026-01-26  4:44         ` [f2fs-dev] " Christoph Hellwig
2026-01-26 20:12         ` Eric Biggers
2026-01-26 20:12           ` [f2fs-dev] " Eric Biggers via Linux-f2fs-devel
2026-01-28 21:38           ` Matthew Wilcox
2026-01-28 21:38             ` [f2fs-dev] " Matthew Wilcox
2026-01-28 22:14             ` Eric Biggers
2026-01-28 22:14               ` [f2fs-dev] " Eric Biggers via Linux-f2fs-devel
2026-01-26  4:43     ` Christoph Hellwig
2026-01-26  4:43       ` [f2fs-dev] " Christoph Hellwig
2026-01-22 15:42 ` fsverity cleanups, speedup and memory usage optimization v2 David Sterba
2026-01-22 15:42   ` [f2fs-dev] " David Sterba

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260124205329.GE2762@quark \
    --to=ebiggers@kernel.org \
    --cc=aalbersh@redhat.com \
    --cc=brauner@kernel.org \
    --cc=chao@kernel.org \
    --cc=dsterba@suse.com \
    --cc=fsverity@lists.linux.dev \
    --cc=hch@lst.de \
    --cc=jack@suse.cz \
    --cc=jaegeuk@kernel.org \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-f2fs-devel@lists.sourceforge.net \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=tytso@mit.edu \
    --cc=viro@zeniv.linux.org.uk \
    --cc=willy@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.