aboutsummaryrefslogtreecommitdiffstats
path: root/mm/filemap.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-09-06 23:49:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-09-06 23:49:49 -0400
commitd34fc1adf01ff87026da85fb972dc259dc347540 (patch)
tree27356073d423187157b7cdb69da32b53102fb9e7 /mm/filemap.c
parent1c9fe4409ce3e9c78b1ed96ee8ed699d4f03bf33 (diff)
parentd2cd9ede6e193dd7d88b6d27399e96229a551b19 (diff)
Merge branch 'akpm' (patches from Andrew)
Merge updates from Andrew Morton: - various misc bits - DAX updates - OCFS2 - most of MM * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (119 commits) mm,fork: introduce MADV_WIPEONFORK x86,mpx: make mpx depend on x86-64 to free up VMA flag mm: add /proc/pid/smaps_rollup mm: hugetlb: clear target sub-page last when clearing huge page mm: oom: let oom_reap_task and exit_mmap run concurrently swap: choose swap device according to numa node mm: replace TIF_MEMDIE checks by tsk_is_oom_victim mm, oom: do not rely on TIF_MEMDIE for memory reserves access z3fold: use per-cpu unbuddied lists mm, swap: don't use VMA based swap readahead if HDD is used as swap mm, swap: add sysfs interface for VMA based swap readahead mm, swap: VMA based swap readahead mm, swap: fix swap readahead marking mm, swap: add swap readahead hit statistics mm/vmalloc.c: don't reinvent the wheel but use existing llist API mm/vmstat.c: fix wrong comment selftests/memfd: add memfd_create hugetlbfs selftest mm/shmem: add hugetlbfs support to memfd_create() mm, devm_memremap_pages: use multi-order radix for ZONE_DEVICE lookups mm/vmalloc.c: halve the number of comparisons performed in pcpu_get_vm_areas() ...
Diffstat (limited to 'mm/filemap.c')
-rw-r--r--mm/filemap.c67
1 files changed, 39 insertions, 28 deletions
diff --git a/mm/filemap.c b/mm/filemap.c
index 1e01cb6e5173..9d21afd692b9 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -130,17 +130,8 @@ static int page_cache_tree_insert(struct address_space *mapping,
130 return -EEXIST; 130 return -EEXIST;
131 131
132 mapping->nrexceptional--; 132 mapping->nrexceptional--;
133 if (!dax_mapping(mapping)) { 133 if (shadowp)
134 if (shadowp) 134 *shadowp = p;
135 *shadowp = p;
136 } else {
137 /* DAX can replace empty locked entry with a hole */
138 WARN_ON_ONCE(p !=
139 dax_radix_locked_entry(0, RADIX_DAX_EMPTY));
140 /* Wakeup waiters for exceptional entry lock */
141 dax_wake_mapping_entry_waiter(mapping, page->index, p,
142 true);
143 }
144 } 135 }
145 __radix_tree_replace(&mapping->page_tree, node, slot, page, 136 __radix_tree_replace(&mapping->page_tree, node, slot, page,
146 workingset_update_node, mapping); 137 workingset_update_node, mapping);
@@ -402,8 +393,7 @@ bool filemap_range_has_page(struct address_space *mapping,
402{ 393{
403 pgoff_t index = start_byte >> PAGE_SHIFT; 394 pgoff_t index = start_byte >> PAGE_SHIFT;
404 pgoff_t end = end_byte >> PAGE_SHIFT; 395 pgoff_t end = end_byte >> PAGE_SHIFT;
405 struct pagevec pvec; 396 struct page *page;
406 bool ret;
407 397
408 if (end_byte < start_byte) 398 if (end_byte < start_byte)
409 return false; 399 return false;
@@ -411,12 +401,10 @@ bool filemap_range_has_page(struct address_space *mapping,
411 if (mapping->nrpages == 0) 401 if (mapping->nrpages == 0)
412 return false; 402 return false;
413 403
414 pagevec_init(&pvec, 0); 404 if (!find_get_pages_range(mapping, &index, end, 1, &page))
415 if (!pagevec_lookup(&pvec, mapping, index, 1))
416 return false; 405 return false;
417 ret = (pvec.pages[0]->index <= end); 406 put_page(page);
418 pagevec_release(&pvec); 407 return true;
419 return ret;
420} 408}
421EXPORT_SYMBOL(filemap_range_has_page); 409EXPORT_SYMBOL(filemap_range_has_page);
422 410
@@ -1564,23 +1552,29 @@ export:
1564} 1552}
1565 1553
1566/** 1554/**
1567 * find_get_pages - gang pagecache lookup 1555 * find_get_pages_range - gang pagecache lookup
1568 * @mapping: The address_space to search 1556 * @mapping: The address_space to search
1569 * @start: The starting page index 1557 * @start: The starting page index
1558 * @end: The final page index (inclusive)
1570 * @nr_pages: The maximum number of pages 1559 * @nr_pages: The maximum number of pages
1571 * @pages: Where the resulting pages are placed 1560 * @pages: Where the resulting pages are placed
1572 * 1561 *
1573 * find_get_pages() will search for and return a group of up to 1562 * find_get_pages_range() will search for and return a group of up to @nr_pages
1574 * @nr_pages pages in the mapping. The pages are placed at @pages. 1563 * pages in the mapping starting at index @start and up to index @end
1575 * find_get_pages() takes a reference against the returned pages. 1564 * (inclusive). The pages are placed at @pages. find_get_pages_range() takes
1565 * a reference against the returned pages.
1576 * 1566 *
1577 * The search returns a group of mapping-contiguous pages with ascending 1567 * The search returns a group of mapping-contiguous pages with ascending
1578 * indexes. There may be holes in the indices due to not-present pages. 1568 * indexes. There may be holes in the indices due to not-present pages.
1569 * We also update @start to index the next page for the traversal.
1579 * 1570 *
1580 * find_get_pages() returns the number of pages which were found. 1571 * find_get_pages_range() returns the number of pages which were found. If this
1572 * number is smaller than @nr_pages, the end of specified range has been
1573 * reached.
1581 */ 1574 */
1582unsigned find_get_pages(struct address_space *mapping, pgoff_t start, 1575unsigned find_get_pages_range(struct address_space *mapping, pgoff_t *start,
1583 unsigned int nr_pages, struct page **pages) 1576 pgoff_t end, unsigned int nr_pages,
1577 struct page **pages)
1584{ 1578{
1585 struct radix_tree_iter iter; 1579 struct radix_tree_iter iter;
1586 void **slot; 1580 void **slot;
@@ -1590,8 +1584,11 @@ unsigned find_get_pages(struct address_space *mapping, pgoff_t start,
1590 return 0; 1584 return 0;
1591 1585
1592 rcu_read_lock(); 1586 rcu_read_lock();
1593 radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, start) { 1587 radix_tree_for_each_slot(slot, &mapping->page_tree, &iter, *start) {
1594 struct page *head, *page; 1588 struct page *head, *page;
1589
1590 if (iter.index > end)
1591 break;
1595repeat: 1592repeat:
1596 page = radix_tree_deref_slot(slot); 1593 page = radix_tree_deref_slot(slot);
1597 if (unlikely(!page)) 1594 if (unlikely(!page))
@@ -1627,11 +1624,25 @@ repeat:
1627 } 1624 }
1628 1625
1629 pages[ret] = page; 1626 pages[ret] = page;
1630 if (++ret == nr_pages) 1627 if (++ret == nr_pages) {
1631 break; 1628 *start = pages[ret - 1]->index + 1;
1629 goto out;
1630 }
1632 } 1631 }
1633 1632
1633 /*
1634 * We come here when there is no page beyond @end. We take care to not
1635 * overflow the index @start as it confuses some of the callers. This
1636 * breaks the iteration when there is page at index -1 but that is
1637 * already broken anyway.
1638 */
1639 if (end == (pgoff_t)-1)
1640 *start = (pgoff_t)-1;
1641 else
1642 *start = end + 1;
1643out:
1634 rcu_read_unlock(); 1644 rcu_read_unlock();
1645
1635 return ret; 1646 return ret;
1636} 1647}
1637 1648