Loading mm/filemap.c +23 −28 Original line number Diff line number Diff line Loading @@ -1578,53 +1578,48 @@ unsigned find_get_entries(struct address_space *mapping, pgoff_t start, unsigned int nr_entries, struct page **entries, pgoff_t *indices) { void **slot; XA_STATE(xas, &mapping->i_pages, start); struct page *page; unsigned int ret = 0; struct radix_tree_iter iter; if (!nr_entries) return 0; rcu_read_lock(); radix_tree_for_each_slot(slot, &mapping->i_pages, &iter, start) { struct page *head, *page; repeat: page = radix_tree_deref_slot(slot); if (unlikely(!page)) continue; if (radix_tree_exception(page)) { if (radix_tree_deref_retry(page)) { slot = radix_tree_iter_retry(&iter); xas_for_each(&xas, page, ULONG_MAX) { struct page *head; if (xas_retry(&xas, page)) continue; } /* * A shadow entry of a recently evicted page, a swap * entry from shmem/tmpfs or a DAX entry. Return it * without attempting to raise page count. */ if (xa_is_value(page)) goto export; } head = compound_head(page); if (!page_cache_get_speculative(head)) goto repeat; goto retry; /* The page was split under us? */ if (compound_head(page) != head) { put_page(head); goto repeat; } if (compound_head(page) != head) goto put_page; /* Has the page moved? */ if (unlikely(page != *slot)) { put_page(head); goto repeat; } if (unlikely(page != xas_reload(&xas))) goto put_page; export: indices[ret] = iter.index; indices[ret] = xas.xa_index; entries[ret] = page; if (++ret == nr_entries) break; continue; put_page: put_page(head); retry: xas_reset(&xas); } rcu_read_unlock(); return ret; Loading Loading
mm/filemap.c +23 −28 Original line number Diff line number Diff line Loading @@ -1578,53 +1578,48 @@ unsigned find_get_entries(struct address_space *mapping, pgoff_t start, unsigned int nr_entries, struct page **entries, pgoff_t *indices) { void **slot; XA_STATE(xas, &mapping->i_pages, start); struct page *page; unsigned int ret = 0; struct radix_tree_iter iter; if (!nr_entries) return 0; rcu_read_lock(); radix_tree_for_each_slot(slot, &mapping->i_pages, &iter, start) { struct page *head, *page; repeat: page = radix_tree_deref_slot(slot); if (unlikely(!page)) continue; if (radix_tree_exception(page)) { if (radix_tree_deref_retry(page)) { slot = radix_tree_iter_retry(&iter); xas_for_each(&xas, page, ULONG_MAX) { struct page *head; if (xas_retry(&xas, page)) continue; } /* * A shadow entry of a recently evicted page, a swap * entry from shmem/tmpfs or a DAX entry. Return it * without attempting to raise page count. */ if (xa_is_value(page)) goto export; } head = compound_head(page); if (!page_cache_get_speculative(head)) goto repeat; goto retry; /* The page was split under us? */ if (compound_head(page) != head) { put_page(head); goto repeat; } if (compound_head(page) != head) goto put_page; /* Has the page moved? */ if (unlikely(page != *slot)) { put_page(head); goto repeat; } if (unlikely(page != xas_reload(&xas))) goto put_page; export: indices[ret] = iter.index; indices[ret] = xas.xa_index; entries[ret] = page; if (++ret == nr_entries) break; continue; put_page: put_page(head); retry: xas_reset(&xas); } rcu_read_unlock(); return ret; Loading