diff options
| author | Vishal Moola (Oracle) <vishal.moola@gmail.com> | 2025-04-03 16:54:17 -0700 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2025-04-25 10:43:54 +0200 |
| commit | f95a2ec3ec9f24168dd25148ebe75471ab60f10d (patch) | |
| tree | c3596aa2018db7ffb84d1e217e1f4b2bb2fb8009 /mm | |
| parent | a6e7f6018dfd2011d741537c9aea0e57e7edd281 (diff) | |
| download | linux-f95a2ec3ec9f24168dd25148ebe75471ab60f10d.tar.gz linux-f95a2ec3ec9f24168dd25148ebe75471ab60f10d.tar.bz2 linux-f95a2ec3ec9f24168dd25148ebe75471ab60f10d.zip | |
mm: fix filemap_get_folios_contig returning batches of identical folios
commit 8ab1b16023961dc640023b10436d282f905835ad upstream.
filemap_get_folios_contig() is supposed to return distinct folios found
within [start, end]. Large folios in the Xarray become multi-index
entries. xas_next() can iterate through the sub-indexes before finding a
sibling entry and breaking out of the loop.
This can result in a returned folio_batch containing an indeterminate
number of duplicate folios, which forces the callers to skeptically handle
the returned batch. This is inefficient and incurs a large maintenance
overhead.
We can fix this by calling xas_advance() after we have successfully adding
a folio to the batch to ensure our Xarray is positioned such that it will
correctly find the next folio - similar to filemap_get_read_batch().
Link: https://lkml.kernel.org/r/Z-8s1-kiIDkzgRbc@fedora
Fixes: 35b471467f88 ("filemap: add filemap_get_folios_contig()")
Signed-off-by: Vishal Moola (Oracle) <vishal.moola@gmail.com>
Reported-by: Qu Wenruo <quwenruo.btrfs@gmx.com>
Closes: https://lkml.kernel.org/r/b714e4de-2583-4035-b829-72cfb5eb6fc6@gmx.com
Tested-by: Qu Wenruo <quwenruo.btrfs@gmx.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Vivek Kasireddy <vivek.kasireddy@intel.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'mm')
| -rw-r--r-- | mm/filemap.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 78bf403473fb..6649a853dc5f 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2266,6 +2266,7 @@ unsigned filemap_get_folios_contig(struct address_space *mapping, *start = folio->index + nr; goto out; } + xas_advance(&xas, folio_next_index(folio) - 1); continue; put_folio: folio_put(folio); |
