mm: improve find_lock_page
authorNick Piggin <npiggin@suse.de>
Tue, 16 Oct 2007 08:24:41 +0000 (01:24 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Tue, 16 Oct 2007 16:42:53 +0000 (09:42 -0700)
find_lock_page does not need to recheck ->index because if the page is in the
right mapping then the index must be the same.  Also, tree_lock does not need
to be retaken after the page is locked in order to test that ->mapping has not
changed, because holding the page lock pins its mapping.

Signed-off-by: Nick Piggin <npiggin@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
mm/filemap.c

index b436cbb3a834debb936c2e60e6508b0746606aa5..7989c44cb293d09c5c6b306128aceafdb369d311 100644 (file)
@@ -621,26 +621,27 @@ struct page *find_lock_page(struct address_space *mapping,
 {
        struct page *page;
 
-       read_lock_irq(&mapping->tree_lock);
 repeat:
+       read_lock_irq(&mapping->tree_lock);
        page = radix_tree_lookup(&mapping->page_tree, offset);
        if (page) {
                page_cache_get(page);
                if (TestSetPageLocked(page)) {
                        read_unlock_irq(&mapping->tree_lock);
                        __lock_page(page);
-                       read_lock_irq(&mapping->tree_lock);
 
                        /* Has the page been truncated while we slept? */
-                       if (unlikely(page->mapping != mapping ||
-                                    page->index != offset)) {
+                       if (unlikely(page->mapping != mapping)) {
                                unlock_page(page);
                                page_cache_release(page);
                                goto repeat;
                        }
+                       VM_BUG_ON(page->index != offset);
+                       goto out;
                }
        }
        read_unlock_irq(&mapping->tree_lock);
+out:
        return page;
 }
 EXPORT_SYMBOL(find_lock_page);