Loading mm/filemap.c +28 −35 Original line number Original line Diff line number Diff line Loading @@ -1382,27 +1382,21 @@ EXPORT_SYMBOL(page_cache_prev_miss); */ */ struct page *find_get_entry(struct address_space *mapping, pgoff_t offset) struct page *find_get_entry(struct address_space *mapping, pgoff_t offset) { { void **pagep; XA_STATE(xas, &mapping->i_pages, offset); struct page *head, *page; struct page *head, *page; rcu_read_lock(); rcu_read_lock(); repeat: repeat: page = NULL; xas_reset(&xas); pagep = radix_tree_lookup_slot(&mapping->i_pages, offset); page = xas_load(&xas); if (pagep) { if (xas_retry(&xas, page)) page = radix_tree_deref_slot(pagep); if (unlikely(!page)) goto out; if (radix_tree_exception(page)) { if (radix_tree_deref_retry(page)) goto repeat; goto repeat; /* /* * A shadow entry of a recently evicted page, * A shadow entry of a recently evicted page, or a swap entry from * or a swap entry from shmem/tmpfs. Return * shmem/tmpfs. Return it without attempting to raise page count. * it without attempting to raise page count. */ */ if (!page || xa_is_value(page)) goto out; goto out; } head = compound_head(page); head = compound_head(page); if (!page_cache_get_speculative(head)) if (!page_cache_get_speculative(head)) Loading @@ -1419,11 +1413,10 @@ struct page *find_get_entry(struct address_space *mapping, pgoff_t offset) * This is part of the lockless pagecache protocol. See * This is part of the lockless pagecache protocol. See * include/linux/pagemap.h for details. * include/linux/pagemap.h for details. */ */ if (unlikely(page != *pagep)) { if (unlikely(page != xas_reload(&xas))) { put_page(head); put_page(head); goto repeat; goto repeat; } } } out: out: rcu_read_unlock(); rcu_read_unlock(); Loading Loading @@ -1453,7 +1446,7 @@ struct page *find_lock_entry(struct address_space *mapping, pgoff_t offset) repeat: repeat: page = find_get_entry(mapping, offset); page = find_get_entry(mapping, offset); if (page && !radix_tree_exception(page)) { if (page && !xa_is_value(page)) { lock_page(page); lock_page(page); /* Has the page been truncated? */ /* Has the page been truncated? */ if (unlikely(page_mapping(page) != mapping)) { if (unlikely(page_mapping(page) != mapping)) { Loading Loading
mm/filemap.c +28 −35 Original line number Original line Diff line number Diff line Loading @@ -1382,27 +1382,21 @@ EXPORT_SYMBOL(page_cache_prev_miss); */ */ struct page *find_get_entry(struct address_space *mapping, pgoff_t offset) struct page *find_get_entry(struct address_space *mapping, pgoff_t offset) { { void **pagep; XA_STATE(xas, &mapping->i_pages, offset); struct page *head, *page; struct page *head, *page; rcu_read_lock(); rcu_read_lock(); repeat: repeat: page = NULL; xas_reset(&xas); pagep = radix_tree_lookup_slot(&mapping->i_pages, offset); page = xas_load(&xas); if (pagep) { if (xas_retry(&xas, page)) page = radix_tree_deref_slot(pagep); if (unlikely(!page)) goto out; if (radix_tree_exception(page)) { if (radix_tree_deref_retry(page)) goto repeat; goto repeat; /* /* * A shadow entry of a recently evicted page, * A shadow entry of a recently evicted page, or a swap entry from * or a swap entry from shmem/tmpfs. Return * shmem/tmpfs. Return it without attempting to raise page count. * it without attempting to raise page count. */ */ if (!page || xa_is_value(page)) goto out; goto out; } head = compound_head(page); head = compound_head(page); if (!page_cache_get_speculative(head)) if (!page_cache_get_speculative(head)) Loading @@ -1419,11 +1413,10 @@ struct page *find_get_entry(struct address_space *mapping, pgoff_t offset) * This is part of the lockless pagecache protocol. See * This is part of the lockless pagecache protocol. See * include/linux/pagemap.h for details. * include/linux/pagemap.h for details. */ */ if (unlikely(page != *pagep)) { if (unlikely(page != xas_reload(&xas))) { put_page(head); put_page(head); goto repeat; goto repeat; } } } out: out: rcu_read_unlock(); rcu_read_unlock(); Loading Loading @@ -1453,7 +1446,7 @@ struct page *find_lock_entry(struct address_space *mapping, pgoff_t offset) repeat: repeat: page = find_get_entry(mapping, offset); page = find_get_entry(mapping, offset); if (page && !radix_tree_exception(page)) { if (page && !xa_is_value(page)) { lock_page(page); lock_page(page); /* Has the page been truncated? */ /* Has the page been truncated? */ if (unlikely(page_mapping(page) != mapping)) { if (unlikely(page_mapping(page) != mapping)) { Loading