Re: [PATCH RFC 07/14] fs/erofs: mm/pagemap: add readahead_folio_reverse() to avoid folio->private
Gao Xiang <[email protected]> Tue, 4 Aug 2026 07:55:09 +0800
| Newsgroups | org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel,org.kvack.linux-mm,org.ozlabs.lists.linux-erofs |
|---|---|
| Message-ID | <[email protected]> |
On Fri, Jul 31, 2026 at 10:13:30PM -0400, Zi Yan wrote: > erofs needs to traverse readahead folios in reverse order to achieve > maximum performance by > 1. reading all folios from readahead_folio(); > 2. storing the prior folio pointer in folio->private; > 3. traverse from the last folio to the first one. > > Add readahead_folio_reverse() to achieve the same function without using > folio->private. > > It prepares for a future commit that replaces PG_private checks with > !folio->private checks. After switching the checks, erofs's use of > folio->private without bumping folio refcount can cause unexpected > outcomes, e.g., in filemap_release_folio(), try_to_free_buffers() becomes > reachable. > > No funtional change intended. > > Assisted-by: Claude:claude-opus-4-8 > Assisted-by: Codex:gpt-5 > Signed-off-by: Zi Yan <[email protected]> > To: Gao Xiang <[email protected]> > To: Chao Yu <[email protected]> > To: "Matthew Wilcox (Oracle)" <[email protected]> > To: Jan Kara <[email protected]> > Cc: Yue Hu <[email protected]> > Cc: Jeffle Xu <[email protected]> > Cc: Sandeep Dhavale <[email protected]> > Cc: Hongbo Li <[email protected]> > Cc: Chunhai Guo <[email protected]> > Cc: [email protected] > Cc: [email protected] > Cc: [email protected] > Cc: [email protected] > --- > fs/erofs/zdata.c | 11 ++--------- > include/linux/pagemap.h | 31 +++++++++++++++++++++++++++++++ > 2 files changed, 33 insertions(+), 9 deletions(-) > > diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c > index 74520e9102596..b59f2745a8e72 100644 > --- a/fs/erofs/zdata.c > +++ b/fs/erofs/zdata.c > @@ -1902,21 +1902,14 @@ static void z_erofs_readahead(struct readahead_control *rac) > struct inode *realinode = erofs_real_inode(sharedinode, &need_iput); > Z_EROFS_DEFINE_FRONTEND(f, realinode, sharedinode, readahead_pos(rac)); > unsigned int nrpages = readahead_count(rac); > - struct folio *head = NULL, *folio; > + struct folio *folio; > int err; > > trace_erofs_readahead(realinode, readahead_index(rac), nrpages, false); > z_erofs_pcluster_readmore(&f, rac, true); > - while ((folio = readahead_folio(rac))) { > - folio->private = head; > - head = folio; > - } > > /* traverse in reverse order for best metadata I/O performance */ > - while (head) { > - folio = head; > - head = folio_get_private(folio); > - > + while ((folio = readahead_folio_reverse(rac))) { Yes, it's needed due to EROFS compression metadata design and on-demand partial decompression, the last extent in the readahead request can be parsed as a partial extent (means from the starting logical offset of extents to the necessary offset.). Since there may be many extents in a single readahead request, so it needs to iterate backwards here; but the actual compressed data I/Os will be issued forwards. Previously I tend to avoid touching core-mm so it uses folio->private but if MM folks can provide a new helper, that would be very helpful (one more words: all folios are locked in the forward order previously, so it won't have any deadlock risk). Thanks, Gao Xiang