diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2022-06-05 16:44:53 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2022-06-05 16:44:53 -0400 |
commit | 5d370ea0a95804da1d533cc806040f78b0a6f297 (patch) | |
tree | ea333d8344734f33d79cbcf8d4e7049c655b93a4 /mm/filemap.c | |
parent | 6fc5ba99ee0db14f86d99db929210e21b68b9ab2 (diff) |
filemap: for_each_folio_batched()folio_iter_batched
This adds a cleaner interface around iterating over folios with batched
lookup, and a new iterator type (folio_iter_batched), and converts most
users of filemap_get_folios() to the new interface.
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Diffstat (limited to 'mm/filemap.c')
-rw-r--r-- | mm/filemap.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index d631bc317131..930478daa168 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2182,6 +2182,55 @@ out: } EXPORT_SYMBOL(filemap_get_folios); +static inline struct folio *__folio_iter_batched_peek(struct folio_iter_batched *iter) +{ + return iter->batch.folios[iter->batch_idx]; +} + +struct folio *folio_iter_batched_peek(struct folio_iter_batched *iter) +{ + struct folio *f; + + if (iter->batch_idx >= iter->batch.nr) { + pgoff_t start = iter->pos; + + folio_batch_release(&iter->batch); + + cond_resched(); + + filemap_get_folios(iter->mapping, &start, iter->end, &iter->batch); + iter->batch_idx = 0; + } + + if (!iter->batch.nr) { + iter->pos = iter->end + 1; + return NULL; + } + + f = __folio_iter_batched_peek(iter); + /* + * folio might span iter->pos, but iter->pos should be monotonically + * increasing: + */ + iter->pos = max(iter->pos, f->index); + return f; +} +EXPORT_SYMBOL(folio_iter_batched_peek); + +void folio_iter_batched_advance(struct folio_iter_batched *iter) +{ + /* Do we have a previously returned folio? */ + if (iter->batch_idx < iter->batch.nr) { + struct folio *f = __folio_iter_batched_peek(iter); + pgoff_t f_end = folio_next_index(f); + + BUG_ON(iter->pos < f->index || iter->pos >= f_end); + iter->pos = f_end; + iter->batch_idx++; + } +} +EXPORT_SYMBOL(folio_iter_batched_advance); + static inline bool folio_more_pages(struct folio *folio, pgoff_t index, pgoff_t max) { |