diff options
Diffstat (limited to 'mm/filemap.c')
-rw-r--r-- | mm/filemap.c | 9 |
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); | ||
625 | repeat: | 624 | repeat: |
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); |
644 | out: | ||
644 | return page; | 645 | return page; |
645 | } | 646 | } |
646 | EXPORT_SYMBOL(find_lock_page); | 647 | EXPORT_SYMBOL(find_lock_page); |