aboutsummaryrefslogtreecommitdiffstats
path: root/mm/filemap.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/filemap.c')
-rw-r--r--mm/filemap.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/mm/filemap.c b/mm/filemap.c
index b436cbb3a834..7989c44cb293 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -621,26 +621,27 @@ struct page *find_lock_page(struct address_space *mapping,
621{ 621{
622 struct page *page; 622 struct page *page;
623 623
624 read_lock_irq(&mapping->tree_lock);
625repeat: 624repeat:
625 read_lock_irq(&mapping->tree_lock);
626 page = radix_tree_lookup(&mapping->page_tree, offset); 626 page = radix_tree_lookup(&mapping->page_tree, offset);
627 if (page) { 627 if (page) {
628 page_cache_get(page); 628 page_cache_get(page);
629 if (TestSetPageLocked(page)) { 629 if (TestSetPageLocked(page)) {
630 read_unlock_irq(&mapping->tree_lock); 630 read_unlock_irq(&mapping->tree_lock);
631 __lock_page(page); 631 __lock_page(page);
632 read_lock_irq(&mapping->tree_lock);
633 632
634 /* Has the page been truncated while we slept? */ 633 /* Has the page been truncated while we slept? */
635 if (unlikely(page->mapping != mapping || 634 if (unlikely(page->mapping != mapping)) {
636 page->index != offset)) {
637 unlock_page(page); 635 unlock_page(page);
638 page_cache_release(page); 636 page_cache_release(page);
639 goto repeat; 637 goto repeat;
640 } 638 }
639 VM_BUG_ON(page->index != offset);
640 goto out;
641 } 641 }
642 } 642 }
643 read_unlock_irq(&mapping->tree_lock); 643 read_unlock_irq(&mapping->tree_lock);
644out:
644 return page; 645 return page;
645} 646}
646EXPORT_SYMBOL(find_lock_page); 647EXPORT_SYMBOL(find_lock_page);