[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <vu3c3isevxhsayshrgv4yj2xfkeugbtx4jaryrdxehz57vq6ho@mkrueh7j55fe>
Date: Mon, 2 Feb 2026 14:36:18 +0100
From: Jan Kara <jack@...e.cz>
To: Christoph Hellwig <hch@....de>
Cc: Eric Biggers <ebiggers@...nel.org>, Al Viro <viro@...iv.linux.org.uk>,
Christian Brauner <brauner@...nel.org>, Jan Kara <jack@...e.cz>, David Sterba <dsterba@...e.com>,
Theodore Ts'o <tytso@....edu>, Jaegeuk Kim <jaegeuk@...nel.org>, Chao Yu <chao@...nel.org>,
Andrey Albershteyn <aalbersh@...hat.com>, Matthew Wilcox <willy@...radead.org>,
linux-fsdevel@...r.kernel.org, linux-btrfs@...r.kernel.org, linux-ext4@...r.kernel.org,
linux-f2fs-devel@...ts.sourceforge.net, fsverity@...ts.linux.dev
Subject: Re: [PATCH 02/11] readahead: push invalidate_lock out of
page_cache_ra_unbounded
On Mon 02-02-26 07:06:31, Christoph Hellwig wrote:
> 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 <hch@....de>
Looks good to me. Feel free to add:
Reviewed-by: Jan Kara <jack@...e.cz>
Honza
> 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
>
--
Jan Kara <jack@...e.com>
SUSE Labs, CR
Powered by blists - more mailing lists