page cache: Convert find_get_entry to XArray
authorMatthew Wilcox <willy@infradead.org>
Wed, 16 May 2018 20:12:50 +0000 (16:12 -0400)
committerMatthew Wilcox <willy@infradead.org>
Sun, 21 Oct 2018 14:46:34 +0000 (10:46 -0400)
Slightly shorter and simpler code.

Signed-off-by: Matthew Wilcox <willy@infradead.org>
mm/filemap.c

index 414efbdc95df8a1c1974b674a99b9c77e32774a9..2bf9f0742082ac0a798531e1db079f26fb9ce862 100644 (file)
@@ -1382,47 +1382,40 @@ EXPORT_SYMBOL(page_cache_prev_miss);
  */
 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;
 
        rcu_read_lock();
 repeat:
-       page = NULL;
-       pagep = radix_tree_lookup_slot(&mapping->i_pages, offset);
-       if (pagep) {
-               page = radix_tree_deref_slot(pagep);
-               if (unlikely(!page))
-                       goto out;
-               if (radix_tree_exception(page)) {
-                       if (radix_tree_deref_retry(page))
-                               goto repeat;
-                       /*
-                        * A shadow entry of a recently evicted page,
-                        * or a swap entry from shmem/tmpfs.  Return
-                        * it without attempting to raise page count.
-                        */
-                       goto out;
-               }
+       xas_reset(&xas);
+       page = xas_load(&xas);
+       if (xas_retry(&xas, page))
+               goto repeat;
+       /*
+        * A shadow entry of a recently evicted page, or a swap entry from
+        * shmem/tmpfs.  Return it without attempting to raise page count.
+        */
+       if (!page || xa_is_value(page))
+               goto out;
 
-               head = compound_head(page);
-               if (!page_cache_get_speculative(head))
-                       goto repeat;
+       head = compound_head(page);
+       if (!page_cache_get_speculative(head))
+               goto repeat;
 
-               /* The page was split under us? */
-               if (compound_head(page) != head) {
-                       put_page(head);
-                       goto repeat;
-               }
+       /* The page was split under us? */
+       if (compound_head(page) != head) {
+               put_page(head);
+               goto repeat;
+       }
 
-               /*
-                * Has the page moved?
-                * This is part of the lockless pagecache protocol. See
-                * include/linux/pagemap.h for details.
-                */
-               if (unlikely(page != *pagep)) {
-                       put_page(head);
-                       goto repeat;
-               }
+       /*
+        * Has the page moved?
+        * This is part of the lockless pagecache protocol. See
+        * include/linux/pagemap.h for details.
+        */
+       if (unlikely(page != xas_reload(&xas))) {
+               put_page(head);
+               goto repeat;
        }
 out:
        rcu_read_unlock();
@@ -1453,7 +1446,7 @@ struct page *find_lock_entry(struct address_space *mapping, pgoff_t offset)
 
 repeat:
        page = find_get_entry(mapping, offset);
-       if (page && !radix_tree_exception(page)) {
+       if (page && !xa_is_value(page)) {
                lock_page(page);
                /* Has the page been truncated? */
                if (unlikely(page_mapping(page) != mapping)) {