[f2fs-dev] [PATCH 08/11] ext4: consolidate fsverity_info lookup

2026-02-01 Thread Christoph Hellwig
Look up the fsverity_info once in ext4_mpage_readpages, and then use it
for the readahead, local verification of holes and pass it along to the
I/O completion workqueue in struct bio_post_read_ctx.

This amortizes the lookup better once it becomes less efficient.

Signed-off-by: Christoph Hellwig 
Reviewed-by: Jan Kara 
Reviewed-by: "Darrick J. Wong" 
---
 fs/ext4/readpage.c | 46 ++
 1 file changed, 22 insertions(+), 24 deletions(-)

diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c
index 823d67e98c70..09acca898c25 100644
--- a/fs/ext4/readpage.c
+++ b/fs/ext4/readpage.c
@@ -62,6 +62,7 @@ enum bio_post_read_step {
 
 struct bio_post_read_ctx {
struct bio *bio;
+   struct fsverity_info *vi;
struct work_struct work;
unsigned int cur_step;
unsigned int enabled_steps;
@@ -97,7 +98,7 @@ static void verity_work(struct work_struct *work)
struct bio_post_read_ctx *ctx =
container_of(work, struct bio_post_read_ctx, work);
struct bio *bio = ctx->bio;
-   struct inode *inode = bio_first_folio_all(bio)->mapping->host;
+   struct fsverity_info *vi = ctx->vi;
 
/*
 * fsverity_verify_bio() may call readahead() again, and although verity
@@ -110,7 +111,7 @@ static void verity_work(struct work_struct *work)
mempool_free(ctx, bio_post_read_ctx_pool);
bio->bi_private = NULL;
 
-   fsverity_verify_bio(*fsverity_info_addr(inode), bio);
+   fsverity_verify_bio(vi, bio);
 
__read_end_io(bio);
 }
@@ -174,22 +175,16 @@ static void mpage_end_io(struct bio *bio)
__read_end_io(bio);
 }
 
-static inline bool ext4_need_verity(const struct inode *inode, pgoff_t idx)
-{
-   return fsverity_active(inode) &&
-  idx < DIV_ROUND_UP(inode->i_size, PAGE_SIZE);
-}
-
 static void ext4_set_bio_post_read_ctx(struct bio *bio,
   const struct inode *inode,
-  pgoff_t first_idx)
+  struct fsverity_info *vi)
 {
unsigned int post_read_steps = 0;
 
if (fscrypt_inode_uses_fs_layer_crypto(inode))
post_read_steps |= 1 << STEP_DECRYPT;
 
-   if (ext4_need_verity(inode, first_idx))
+   if (vi)
post_read_steps |= 1 << STEP_VERITY;
 
if (post_read_steps) {
@@ -198,6 +193,7 @@ static void ext4_set_bio_post_read_ctx(struct bio *bio,
mempool_alloc(bio_post_read_ctx_pool, GFP_NOFS);
 
ctx->bio = bio;
+   ctx->vi = vi;
ctx->enabled_steps = post_read_steps;
bio->bi_private = ctx;
}
@@ -211,7 +207,7 @@ static inline loff_t ext4_readpage_limit(struct inode 
*inode)
return i_size_read(inode);
 }
 
-static int ext4_mpage_readpages(struct inode *inode,
+static int ext4_mpage_readpages(struct inode *inode, struct fsverity_info *vi,
struct readahead_control *rac, struct folio *folio)
 {
struct bio *bio = NULL;
@@ -331,10 +327,7 @@ static int ext4_mpage_readpages(struct inode *inode,
folio_zero_segment(folio, first_hole << blkbits,
  folio_size(folio));
if (first_hole == 0) {
-   if (ext4_need_verity(inode, folio->index) &&
-   !fsverity_verify_folio(
-   *fsverity_info_addr(inode),
-   folio))
+   if (vi && !fsverity_verify_folio(vi, folio))
goto set_error_page;
folio_end_read(folio, true);
continue;
@@ -362,7 +355,7 @@ static int ext4_mpage_readpages(struct inode *inode,
REQ_OP_READ, GFP_KERNEL);
fscrypt_set_bio_crypt_ctx(bio, inode, next_block,
  GFP_KERNEL);
-   ext4_set_bio_post_read_ctx(bio, inode, folio->index);
+   ext4_set_bio_post_read_ctx(bio, inode, vi);
bio->bi_iter.bi_sector = first_block << (blkbits - 9);
bio->bi_end_io = mpage_end_io;
if (rac)
@@ -401,6 +394,7 @@ static int ext4_mpage_readpages(struct inode *inode,
 int ext4_read_folio(struct file *file, struct folio *folio)
 {
struct inode *inode = folio->mapping->host;
+   struct fsverity_info *vi = NULL;
int ret;
 
trace_ext4_read_folio(inode, folio);
@@ -411,24 +405,28 @@ int ext4_read_folio(struct file *file, struct folio 
*folio)
return ret;
}
 
-   if (ext4_need_verity(inode, folio->index))
-   fsverity_readahead(*fsverity_info_addr(inode), folio->index,
- 

Re: [f2fs-dev] [PATCH 08/11] ext4: consolidate fsverity_info lookup

2026-01-22 Thread Darrick J. Wong via Linux-f2fs-devel
On Fri, Jan 23, 2026 at 06:18:36AM +0100, Christoph Hellwig wrote:
> On Thu, Jan 22, 2026 at 01:54:57PM -0800, Darrick J. Wong wrote:
> > > + if (folio->index <
> > > + DIV_ROUND_UP(inode->i_size, PAGE_SIZE))
> > 
> > I keep seeing this predicate, maybe it should go into fsverity.h as a
> > helper function with the comment about mmap that I was muttering about
> > in the previous patch?
> 
> Right now it is not generic.  Nothing in the generic fsverity code
> known about the offset, ext4 and f2fs just happened to chose the
> same constant (and the ext4 one leak to buffer.c), while btrfs stores
> the verity hashed totally differently.  I hope the xfs works ends up
> with a consolidated way of doing this, at which point such a helper
> would be useful.
> 
> > Or maybe a "get verity info for given folio index" helper?
> 
> How would that make sense?
> 
> > /*
> >  * Grab the fsverity context needed to verify the contents of the folio.
> >  *
> >  * 
> >  */
> > static inline struct fsverity_info *vi
> > fsverity_folio_info(const struct folio *folio)
> > {
> > struct inode *inode = folio->mapping->host;
> > 
> > if (folio->index < DIV_ROUND_UP(inode->i_size, PAGE_SIZE))
> > return fsverity_get_info(inode);
> > return NULL;
> > }
> 
> Tthe offset right now is entirely file system specific,
> so we can't do this.  Maybe that'll change with further consolidation.

 Ok, I think I'll defer all this talk of helpers until whichever
series cleans up all the post-eof pagecache stuff, and then we can make
all four filesystems pick the same offset for the cached merkle trees.

Reviewed-by: "Darrick J. Wong" 

--D


___
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 08/11] ext4: consolidate fsverity_info lookup

2026-01-22 Thread Christoph Hellwig
On Thu, Jan 22, 2026 at 01:54:57PM -0800, Darrick J. Wong wrote:
> > +   if (folio->index <
> > +   DIV_ROUND_UP(inode->i_size, PAGE_SIZE))
> 
> I keep seeing this predicate, maybe it should go into fsverity.h as a
> helper function with the comment about mmap that I was muttering about
> in the previous patch?

Right now it is not generic.  Nothing in the generic fsverity code
known about the offset, ext4 and f2fs just happened to chose the
same constant (and the ext4 one leak to buffer.c), while btrfs stores
the verity hashed totally differently.  I hope the xfs works ends up
with a consolidated way of doing this, at which point such a helper
would be useful.

> Or maybe a "get verity info for given folio index" helper?

How would that make sense?

> /*
>  * Grab the fsverity context needed to verify the contents of the folio.
>  *
>  * 
>  */
> static inline struct fsverity_info *vi
> fsverity_folio_info(const struct folio *folio)
> {
>   struct inode *inode = folio->mapping->host;
> 
>   if (folio->index < DIV_ROUND_UP(inode->i_size, PAGE_SIZE))
>   return fsverity_get_info(inode);
>   return NULL;
> }

Tthe offset right now is entirely file system specific,
so we can't do this.  Maybe that'll change with further consolidation.



___
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


Re: [f2fs-dev] [PATCH 08/11] ext4: consolidate fsverity_info lookup

2026-01-22 Thread Darrick J. Wong via Linux-f2fs-devel
On Thu, Jan 22, 2026 at 09:22:04AM +0100, Christoph Hellwig wrote:
> Look up the fsverity_info once in ext4_mpage_readpages, and then use it
> for the readahead, local verification of holes and pass it along to the
> I/O completion workqueue in struct bio_post_read_ctx.
> 
> This amortizes the lookup better once it becomes less efficient.
> 
> Signed-off-by: Christoph Hellwig 
> ---
>  fs/ext4/readpage.c | 33 ++---
>  1 file changed, 14 insertions(+), 19 deletions(-)
> 
> diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c
> index 02f918cf1945..6092d6d59063 100644
> --- a/fs/ext4/readpage.c
> +++ b/fs/ext4/readpage.c
> @@ -61,6 +61,7 @@ enum bio_post_read_step {
>  
>  struct bio_post_read_ctx {
>   struct bio *bio;
> + struct fsverity_info *vi;
>   struct work_struct work;
>   unsigned int cur_step;
>   unsigned int enabled_steps;
> @@ -96,7 +97,7 @@ static void verity_work(struct work_struct *work)
>   struct bio_post_read_ctx *ctx =
>   container_of(work, struct bio_post_read_ctx, work);
>   struct bio *bio = ctx->bio;
> - struct inode *inode = bio_first_folio_all(bio)->mapping->host;
> + struct fsverity_info *vi = ctx->vi;
>  
>   /*
>* fsverity_verify_bio() may call readahead() again, and although verity
> @@ -109,7 +110,7 @@ static void verity_work(struct work_struct *work)
>   mempool_free(ctx, bio_post_read_ctx_pool);
>   bio->bi_private = NULL;
>  
> - fsverity_verify_bio(*fsverity_info_addr(inode), bio);
> + fsverity_verify_bio(vi, bio);
>  
>   __read_end_io(bio);
>  }
> @@ -172,22 +173,16 @@ static void mpage_end_io(struct bio *bio)
>   __read_end_io(bio);
>  }
>  
> -static inline bool ext4_need_verity(const struct inode *inode, pgoff_t idx)
> -{
> - return fsverity_active(inode) &&
> -idx < DIV_ROUND_UP(inode->i_size, PAGE_SIZE);
> -}
> -
>  static void ext4_set_bio_post_read_ctx(struct bio *bio,
>  const struct inode *inode,
> -pgoff_t first_idx)
> +struct fsverity_info *vi)
>  {
>   unsigned int post_read_steps = 0;
>  
>   if (fscrypt_inode_uses_fs_layer_crypto(inode))
>   post_read_steps |= 1 << STEP_DECRYPT;
>  
> - if (ext4_need_verity(inode, first_idx))
> + if (vi)
>   post_read_steps |= 1 << STEP_VERITY;
>  
>   if (post_read_steps) {
> @@ -196,6 +191,7 @@ static void ext4_set_bio_post_read_ctx(struct bio *bio,
>   mempool_alloc(bio_post_read_ctx_pool, GFP_NOFS);
>  
>   ctx->bio = bio;
> + ctx->vi = vi;
>   ctx->enabled_steps = post_read_steps;
>   bio->bi_private = ctx;
>   }
> @@ -223,6 +219,7 @@ int ext4_mpage_readpages(struct inode *inode,
>   sector_t first_block;
>   unsigned page_block;
>   struct block_device *bdev = inode->i_sb->s_bdev;
> + struct fsverity_info *vi = NULL;
>   int length;
>   unsigned relative_block = 0;
>   struct ext4_map_blocks map;
> @@ -244,9 +241,11 @@ int ext4_mpage_readpages(struct inode *inode,
>   folio = readahead_folio(rac);
>  
>   if (first_folio) {
> - if (ext4_need_verity(inode, folio->index))
> - fsverity_readahead(*fsverity_info_addr(inode),
> - folio, nr_pages);
> + if (folio->index <
> + DIV_ROUND_UP(inode->i_size, PAGE_SIZE))

I keep seeing this predicate, maybe it should go into fsverity.h as a
helper function with the comment about mmap that I was muttering about
in the previous patch?

Or maybe a "get verity info for given folio index" helper?

/*
 * Grab the fsverity context needed to verify the contents of the folio.
 *
 * 
 */
static inline struct fsverity_info *vi
fsverity_folio_info(const struct folio *folio)
{
struct inode *inode = folio->mapping->host;

if (folio->index < DIV_ROUND_UP(inode->i_size, PAGE_SIZE))
return fsverity_get_info(inode);
return NULL;
}

then ext4 just does:

vi = fsverity_folio_info(folio);
if (vi)
fsverity_readahead(vi, folio, nr_pages);

Hrm?

--D

> + vi = fsverity_get_info(inode);
> + if (vi)
> + fsverity_readahead(vi, folio, nr_pages);
>   first_folio = false;
>   }
>  
> @@ -337,11 +336,7 @@ int ext4_mpage_readpages(struct inode *inode,
>   folio_zero_segment(folio, first_hole << blkbits,
> folio_size(folio));
>   if (first_hole == 0) {
> - struct fsverity_info *vi =
> - 
> *fsverity_info_addr(folio->mapping->host);
> -

[f2fs-dev] [PATCH 08/11] ext4: consolidate fsverity_info lookup

2026-01-22 Thread Christoph Hellwig
Look up the fsverity_info once in ext4_mpage_readpages, and then use it
for the readahead, local verification of holes and pass it along to the
I/O completion workqueue in struct bio_post_read_ctx.

This amortizes the lookup better once it becomes less efficient.

Signed-off-by: Christoph Hellwig 
---
 fs/ext4/readpage.c | 33 ++---
 1 file changed, 14 insertions(+), 19 deletions(-)

diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c
index 02f918cf1945..6092d6d59063 100644
--- a/fs/ext4/readpage.c
+++ b/fs/ext4/readpage.c
@@ -61,6 +61,7 @@ enum bio_post_read_step {
 
 struct bio_post_read_ctx {
struct bio *bio;
+   struct fsverity_info *vi;
struct work_struct work;
unsigned int cur_step;
unsigned int enabled_steps;
@@ -96,7 +97,7 @@ static void verity_work(struct work_struct *work)
struct bio_post_read_ctx *ctx =
container_of(work, struct bio_post_read_ctx, work);
struct bio *bio = ctx->bio;
-   struct inode *inode = bio_first_folio_all(bio)->mapping->host;
+   struct fsverity_info *vi = ctx->vi;
 
/*
 * fsverity_verify_bio() may call readahead() again, and although verity
@@ -109,7 +110,7 @@ static void verity_work(struct work_struct *work)
mempool_free(ctx, bio_post_read_ctx_pool);
bio->bi_private = NULL;
 
-   fsverity_verify_bio(*fsverity_info_addr(inode), bio);
+   fsverity_verify_bio(vi, bio);
 
__read_end_io(bio);
 }
@@ -172,22 +173,16 @@ static void mpage_end_io(struct bio *bio)
__read_end_io(bio);
 }
 
-static inline bool ext4_need_verity(const struct inode *inode, pgoff_t idx)
-{
-   return fsverity_active(inode) &&
-  idx < DIV_ROUND_UP(inode->i_size, PAGE_SIZE);
-}
-
 static void ext4_set_bio_post_read_ctx(struct bio *bio,
   const struct inode *inode,
-  pgoff_t first_idx)
+  struct fsverity_info *vi)
 {
unsigned int post_read_steps = 0;
 
if (fscrypt_inode_uses_fs_layer_crypto(inode))
post_read_steps |= 1 << STEP_DECRYPT;
 
-   if (ext4_need_verity(inode, first_idx))
+   if (vi)
post_read_steps |= 1 << STEP_VERITY;
 
if (post_read_steps) {
@@ -196,6 +191,7 @@ static void ext4_set_bio_post_read_ctx(struct bio *bio,
mempool_alloc(bio_post_read_ctx_pool, GFP_NOFS);
 
ctx->bio = bio;
+   ctx->vi = vi;
ctx->enabled_steps = post_read_steps;
bio->bi_private = ctx;
}
@@ -223,6 +219,7 @@ int ext4_mpage_readpages(struct inode *inode,
sector_t first_block;
unsigned page_block;
struct block_device *bdev = inode->i_sb->s_bdev;
+   struct fsverity_info *vi = NULL;
int length;
unsigned relative_block = 0;
struct ext4_map_blocks map;
@@ -244,9 +241,11 @@ int ext4_mpage_readpages(struct inode *inode,
folio = readahead_folio(rac);
 
if (first_folio) {
-   if (ext4_need_verity(inode, folio->index))
-   fsverity_readahead(*fsverity_info_addr(inode),
-   folio, nr_pages);
+   if (folio->index <
+   DIV_ROUND_UP(inode->i_size, PAGE_SIZE))
+   vi = fsverity_get_info(inode);
+   if (vi)
+   fsverity_readahead(vi, folio, nr_pages);
first_folio = false;
}
 
@@ -337,11 +336,7 @@ int ext4_mpage_readpages(struct inode *inode,
folio_zero_segment(folio, first_hole << blkbits,
  folio_size(folio));
if (first_hole == 0) {
-   struct fsverity_info *vi =
-   
*fsverity_info_addr(folio->mapping->host);
-
-   if (ext4_need_verity(inode, folio->index) &&
-   !fsverity_verify_folio(vi, folio))
+   if (vi && !fsverity_verify_folio(vi, folio))
goto set_error_page;
folio_end_read(folio, true);
continue;
@@ -369,7 +364,7 @@ int ext4_mpage_readpages(struct inode *inode,
REQ_OP_READ, GFP_KERNEL);
fscrypt_set_bio_crypt_ctx(bio, inode, next_block,
  GFP_KERNEL);
-   ext4_set_bio_post_read_ctx(bio, inode, folio->index);
+   ext4_set_bio_post_read_ctx(bio, inode, vi);
bio->bi_iter.bi_sector = first_block << (blkbits - 9);
bio->bi_end_io