summaryrefslogtreecommitdiff
path: root/mm
diff options
context:
space:
mode:
authorVishal Moola (Oracle) <vishal.moola@gmail.com>2025-04-03 16:54:17 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-04-25 10:45:48 +0200
commitc3b3987bae52a17b0cf7d17ed664cfece68dd3e1 (patch)
treee5d9ac69a6c33c45b2e9a4d10f9ab41be7a4b6bd /mm
parent006b67ac61312fe2be05f33acb3f9473df6a7416 (diff)
downloadlinux-c3b3987bae52a17b0cf7d17ed664cfece68dd3e1.tar.gz
linux-c3b3987bae52a17b0cf7d17ed664cfece68dd3e1.tar.bz2
linux-c3b3987bae52a17b0cf7d17ed664cfece68dd3e1.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.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/mm/filemap.c b/mm/filemap.c
index d7c79a69afc8..05eb77623a10 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2256,6 +2256,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);