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 <[email protected]> Reviewed-by: Jan Kara <[email protected]> Reviewed-by: "Darrick J. Wong" <[email protected]> --- 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, - folio_nr_pages(folio)); - return ext4_mpage_readpages(inode, NULL, folio); + if (folio->index < DIV_ROUND_UP(inode->i_size, PAGE_SIZE)) + vi = fsverity_get_info(inode); + if (vi) + fsverity_readahead(vi, folio->index, folio_nr_pages(folio)); + return ext4_mpage_readpages(inode, vi, NULL, folio); } void ext4_readahead(struct readahead_control *rac) { struct inode *inode = rac->mapping->host; + struct fsverity_info *vi = NULL; /* If the file has inline data, no need to do readahead. */ if (ext4_has_inline_data(inode)) return; - if (ext4_need_verity(inode, readahead_index(rac))) - fsverity_readahead(*fsverity_info_addr(inode), - readahead_index(rac), readahead_count(rac)); - ext4_mpage_readpages(inode, rac, NULL); + if (readahead_index(rac) < DIV_ROUND_UP(inode->i_size, PAGE_SIZE)) + vi = fsverity_get_info(inode); + if (vi) + fsverity_readahead(vi, readahead_index(rac), + readahead_count(rac)); + ext4_mpage_readpages(inode, vi, rac, NULL); } -- 2.47.3 _______________________________________________ Linux-f2fs-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
