mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-07-06 13:55:22 +02:00
filemap: add filemap_get_folios_contig()
Patch series "Convert to filemap_get_folios_contig()", v3. This patch series replaces find_get_pages_contig() with filemap_get_folios_contig(). This patch (of 7): This function is meant to replace find_get_pages_contig(). Unlike find_get_pages_contig(), filemap_get_folios_contig() no longer takes in a target number of pages to find - It returns up to 15 contiguous folios. To be more consistent with filemap_get_folios(), filemap_get_folios_contig() now also updates the start index passed in, and takes an end index. Link: https://lkml.kernel.org/r/20220824004023.77310-1-vishal.moola@gmail.com Link: https://lkml.kernel.org/r/20220824004023.77310-2-vishal.moola@gmail.com Signed-off-by: Vishal Moola (Oracle) <vishal.moola@gmail.com> Cc: Chris Mason <clm@fb.com> Cc: Josef Bacik <josef@toxicpanda.com> Cc: David Sterba <dsterba@suse.com> Cc: Ryusuke Konishi <konishi.ryusuke@gmail.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Matthew Wilcox <willy@infradead.org> Cc: David Sterba <dsterb@suse.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
641608f362
commit
35b471467f
|
@ -718,6 +718,8 @@ static inline struct page *find_subpage(struct page *head, pgoff_t index)
|
||||||
|
|
||||||
unsigned filemap_get_folios(struct address_space *mapping, pgoff_t *start,
|
unsigned filemap_get_folios(struct address_space *mapping, pgoff_t *start,
|
||||||
pgoff_t end, struct folio_batch *fbatch);
|
pgoff_t end, struct folio_batch *fbatch);
|
||||||
|
unsigned filemap_get_folios_contig(struct address_space *mapping,
|
||||||
|
pgoff_t *start, pgoff_t end, struct folio_batch *fbatch);
|
||||||
unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start,
|
unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start,
|
||||||
unsigned int nr_pages, struct page **pages);
|
unsigned int nr_pages, struct page **pages);
|
||||||
unsigned find_get_pages_range_tag(struct address_space *mapping, pgoff_t *index,
|
unsigned find_get_pages_range_tag(struct address_space *mapping, pgoff_t *index,
|
||||||
|
|
73
mm/filemap.c
73
mm/filemap.c
|
@ -2196,6 +2196,79 @@ bool folio_more_pages(struct folio *folio, pgoff_t index, pgoff_t max)
|
||||||
return index < folio->index + folio_nr_pages(folio) - 1;
|
return index < folio->index + folio_nr_pages(folio) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* filemap_get_folios_contig - Get a batch of contiguous folios
|
||||||
|
* @mapping: The address_space to search
|
||||||
|
* @start: The starting page index
|
||||||
|
* @end: The final page index (inclusive)
|
||||||
|
* @fbatch: The batch to fill
|
||||||
|
*
|
||||||
|
* filemap_get_folios_contig() works exactly like filemap_get_folios(),
|
||||||
|
* except the returned folios are guaranteed to be contiguous. This may
|
||||||
|
* not return all contiguous folios if the batch gets filled up.
|
||||||
|
*
|
||||||
|
* Return: The number of folios found.
|
||||||
|
* Also update @start to be positioned for traversal of the next folio.
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned filemap_get_folios_contig(struct address_space *mapping,
|
||||||
|
pgoff_t *start, pgoff_t end, struct folio_batch *fbatch)
|
||||||
|
{
|
||||||
|
XA_STATE(xas, &mapping->i_pages, *start);
|
||||||
|
unsigned long nr;
|
||||||
|
struct folio *folio;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
|
||||||
|
for (folio = xas_load(&xas); folio && xas.xa_index <= end;
|
||||||
|
folio = xas_next(&xas)) {
|
||||||
|
if (xas_retry(&xas, folio))
|
||||||
|
continue;
|
||||||
|
/*
|
||||||
|
* If the entry has been swapped out, we can stop looking.
|
||||||
|
* No current caller is looking for DAX entries.
|
||||||
|
*/
|
||||||
|
if (xa_is_value(folio))
|
||||||
|
goto update_start;
|
||||||
|
|
||||||
|
if (!folio_try_get_rcu(folio))
|
||||||
|
goto retry;
|
||||||
|
|
||||||
|
if (unlikely(folio != xas_reload(&xas)))
|
||||||
|
goto put_folio;
|
||||||
|
|
||||||
|
if (!folio_batch_add(fbatch, folio)) {
|
||||||
|
nr = folio_nr_pages(folio);
|
||||||
|
|
||||||
|
if (folio_test_hugetlb(folio))
|
||||||
|
nr = 1;
|
||||||
|
*start = folio->index + nr;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
put_folio:
|
||||||
|
folio_put(folio);
|
||||||
|
|
||||||
|
retry:
|
||||||
|
xas_reset(&xas);
|
||||||
|
}
|
||||||
|
|
||||||
|
update_start:
|
||||||
|
nr = folio_batch_count(fbatch);
|
||||||
|
|
||||||
|
if (nr) {
|
||||||
|
folio = fbatch->folios[nr - 1];
|
||||||
|
if (folio_test_hugetlb(folio))
|
||||||
|
*start = folio->index + 1;
|
||||||
|
else
|
||||||
|
*start = folio->index + folio_nr_pages(folio);
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
rcu_read_unlock();
|
||||||
|
return folio_batch_count(fbatch);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(filemap_get_folios_contig);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* find_get_pages_contig - gang contiguous pagecache lookup
|
* find_get_pages_contig - gang contiguous pagecache lookup
|
||||||
* @mapping: The address_space to search
|
* @mapping: The address_space to search
|
||||||
|
|
Loading…
Reference in New Issue
Block a user