Require the invalidate_lock to be held over calls to page_cache_ra_unbounded instead of acquiring it in this function.
This prepares for calling page_cache_ra_unbounded from ->readahead for fsverity read-ahead. Signed-off-by: Christoph Hellwig <[email protected]> --- fs/f2fs/file.c | 2 ++ fs/verity/pagecache.c | 7 +++++-- mm/readahead.c | 13 ++++++++----- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index da029fed4e5a..c9b9fcdd0cae 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -4418,7 +4418,9 @@ static int redirty_blocks(struct inode *inode, pgoff_t page_idx, int len) pgoff_t redirty_idx = page_idx; int page_len = 0, ret = 0; + filemap_invalidate_lock_shared(mapping); page_cache_ra_unbounded(&ractl, len, 0); + filemap_invalidate_unlock_shared(mapping); do { folio = read_cache_folio(mapping, page_idx, NULL, NULL); diff --git a/fs/verity/pagecache.c b/fs/verity/pagecache.c index 1a88decace53..8e0d6fde802f 100644 --- a/fs/verity/pagecache.c +++ b/fs/verity/pagecache.c @@ -26,10 +26,13 @@ struct page *generic_read_merkle_tree_page(struct inode *inode, pgoff_t index, (!IS_ERR(folio) && !folio_test_uptodate(folio))) { DEFINE_READAHEAD(ractl, NULL, NULL, inode->i_mapping, index); - if (!IS_ERR(folio)) + if (!IS_ERR(folio)) { folio_put(folio); - else if (num_ra_pages > 1) + } else if (num_ra_pages > 1) { + filemap_invalidate_lock_shared(inode->i_mapping); page_cache_ra_unbounded(&ractl, num_ra_pages, 0); + filemap_invalidate_unlock_shared(inode->i_mapping); + } folio = read_mapping_folio(inode->i_mapping, index, NULL); } if (IS_ERR(folio)) diff --git a/mm/readahead.c b/mm/readahead.c index b415c9969176..25f81124beb6 100644 --- a/mm/readahead.c +++ b/mm/readahead.c @@ -204,7 +204,8 @@ static struct folio *ractl_alloc_folio(struct readahead_control *ractl, * not the function you want to call. Use page_cache_async_readahead() * or page_cache_sync_readahead() instead. * - * Context: File is referenced by caller. Mutexes may be held by caller. + * Context: File is referenced by caller, and ractl->mapping->invalidate_lock + * must be held by the caller in shared mode. Mutexes may be held by caller. * May sleep, but will not reenter filesystem to reclaim memory. */ void page_cache_ra_unbounded(struct readahead_control *ractl, @@ -228,9 +229,10 @@ void page_cache_ra_unbounded(struct readahead_control *ractl, */ unsigned int nofs = memalloc_nofs_save(); + lockdep_assert_held_read(&mapping->invalidate_lock); + trace_page_cache_ra_unbounded(mapping->host, index, nr_to_read, lookahead_size); - filemap_invalidate_lock_shared(mapping); index = mapping_align_index(mapping, index); /* @@ -300,7 +302,6 @@ void page_cache_ra_unbounded(struct readahead_control *ractl, * will then handle the error. */ read_pages(ractl); - filemap_invalidate_unlock_shared(mapping); memalloc_nofs_restore(nofs); } EXPORT_SYMBOL_GPL(page_cache_ra_unbounded); @@ -314,9 +315,9 @@ EXPORT_SYMBOL_GPL(page_cache_ra_unbounded); static void do_page_cache_ra(struct readahead_control *ractl, unsigned long nr_to_read, unsigned long lookahead_size) { - struct inode *inode = ractl->mapping->host; + struct address_space *mapping = ractl->mapping; unsigned long index = readahead_index(ractl); - loff_t isize = i_size_read(inode); + loff_t isize = i_size_read(mapping->host); pgoff_t end_index; /* The last page we want to read */ if (isize == 0) @@ -329,7 +330,9 @@ static void do_page_cache_ra(struct readahead_control *ractl, if (nr_to_read > end_index - index) nr_to_read = end_index - index + 1; + filemap_invalidate_lock_shared(mapping); page_cache_ra_unbounded(ractl, nr_to_read, lookahead_size); + filemap_invalidate_unlock_shared(mapping); } /* -- 2.47.3 _______________________________________________ Linux-f2fs-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
